Compare commits

..

10 Commits

Author SHA1 Message Date
Miguel 256d86aca5 Se realizaron actualizaciones en múltiples clases para mejorar la legibilidad y la organización de las propiedades. Se añadieron nuevos atributos de descripción y nombre en varias clases, como ucBasicExample, ucTransporteCurva, y ucTransporteGuias, facilitando la identificación de los elementos en la interfaz de usuario. Además, se eliminaron archivos innecesarios del proyecto y se ajustaron las categorías de propiedades para una mejor clasificación. Estas mejoras optimizan la experiencia del usuario y la gestión de los objetos en la simulación. 2025-06-24 21:35:17 +02:00
Miguel 3bc314182c Se realizaron mejoras en la clase MainViewModel al agregar espacios en blanco para mejorar la legibilidad. En TagEditorAttribute, se añadieron nuevos atributos y se implementó la lógica para manejar nombres personalizados de propiedades. En UserControlFactory, se optimizó la obtención de nombres de propiedades y se eliminaron espacios en blanco innecesarios. Finalmente, se añadió un atributo Name en ucTransporteTTop para el coeficiente de fricción, mejorando la claridad en la interfaz de usuario. 2025-06-24 17:45:47 +02:00
Miguel 6928088691 Se añadieron nuevas propiedades y métodos en el control CircularSegment para gestionar guías visuales, incluyendo la distancia, grosor y color de las guías. Se implementó la lógica para dibujar las guías en el segmento circular, mejorando la visualización y personalización del control. 2025-06-24 17:32:17 +02:00
Miguel 81329e4c09 Se añadieron nuevas propiedades y métodos en la clase ucTransporteCurvaGuias para gestionar guías curvas, incluyendo la creación y actualización de segmentos de guías. Se implementaron validaciones para el número de segmentos y se mejoró la lógica de actualización de geometrías al cambiar propiedades relevantes. 2025-06-24 17:07:37 +02:00
Miguel b6f616f6cc Agregado del control TransportCurva con Guias 2025-06-24 16:53:03 +02:00
Miguel 1449544d71 Se actualizaron las propiedades en las clases osBase, ucCustomImage y ucVMmotorSim para utilizar el nuevo atributo [property: JsonIgnore], mejorando la gestión de la serialización JSON. Además, se ajustó la configuración del serializador en StateSerializer.cs para respetar los atributos JsonIgnore, optimizando la deserialización de objetos. 2025-06-24 11:17:34 +02:00
Miguel 5c2daaeb98 Se añadió un estilo global para TreeViewItem en App.xaml para evitar errores de binding. Se actualizaron las referencias de paquetes en CtrEditor.csproj, cambiando la versión de LiveChartsCore.SkiaSharpView.WPF y añadiendo SkiaSharp.Views.WPF. Se mejoró la gestión de carga de imágenes en osBase.cs y ucCustomImage.xaml.cs, implementando un manejo de errores más robusto y estableciendo imágenes por defecto en caso de fallos. Se ajustó el XAML de ucBoolTag para mejorar la conversión de color. Se implementó un convertidor seguro para ImageSource en StateSerializer.cs, mejorando la deserialización de imágenes. 2025-06-24 10:59:58 +02:00
Miguel 3af9ad99d8 Se añadió un nuevo parámetro de ángulo en el método CrearAnimacionStoryBoardTrasnporteCircular en la clase osBase, permitiendo ajustar la dirección de la animación según el valor del ángulo. Se actualizaron las llamadas a este método en ucTransporteCurva para incluir el nuevo parámetro, mejorando la lógica de animación en función de la dirección y el ángulo proporcionado. 2025-06-23 23:40:48 +02:00
Miguel da8d0516cb Se añadió la funcionalidad para crear y actualizar animaciones de transporte circular en la clase osBase y se integró en ucTransporteCurva. Se implementaron métodos para gestionar la dirección de las animaciones y se mejoró la lógica de actualización de geometrías. Además, se realizaron ajustes en el XAML de CircularSegment para incluir un patrón visual en el Path. 2025-06-23 22:10:00 +02:00
Miguel ac8773ebc7 Se realizaron mejoras en la gestión de objetos visuales en la clase ObjectManipulationManager. Se optimizó la lógica para purgar objetos eliminados y se mejoró la rotación de objetos, permitiendo rotaciones en incrementos de 45 grados al mantener presionada la tecla Shift. Además, se ajustaron espacios en blanco y se mejoró la legibilidad del código en varias secciones. 2025-06-23 21:36:53 +02:00
49 changed files with 2829 additions and 499 deletions

View File

@ -22,6 +22,12 @@
<local:SubclassFilterConverter x:Key="SubclassFilterConverterosVMMotor" TargetType="{x:Type os:osVMmotorSim}" />
<local:UnsavedChangesConverter x:Key="UnsavedChangesConverter"/>
<local:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<!-- Estilo global para TreeViewItem para evitar errores de binding -->
<Style TargetType="TreeViewItem">
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
</Style>
</Application.Resources>
</Application>

View File

@ -18,6 +18,7 @@
</PropertyGroup>
<ItemGroup>
<Compile Remove="Documentation\PlantillaEstandarizacion.cs" />
<Compile Remove="ObjetosSim\ucBasicExample.xaml.cs" />
<Compile Remove="ObjetosSim\ucTransporteCurva.xaml.cs" />
<Compile Remove="Simulacion\FPhysics.cs" />
@ -70,6 +71,7 @@
</ItemGroup>
<ItemGroup>
<None Include="Documentation\PlantillaEstandarizacion.cs" />
<None Include="ObjetosSim\ucBasicExample.xaml" />
<None Include="ObjetosSim\ucBasicExample.xaml.cs" />
<None Include="Simulacion\FPhysics.cs" />
@ -85,8 +87,9 @@
<PackageReference Include="Emgu.CV.UI" Version="4.9.0.5494" />
<PackageReference Include="Extended.Wpf.Toolkit" Version="4.7.25104.5739" />
<PackageReference Include="LanguageDetection" Version="1.2.0" />
<PackageReference Include="LiveChartsCore.SkiaSharpView.WPF" Version="2.0.0-rc4.5" />
<PackageReference Include="LiveChartsCore.SkiaSharpView.WPF" Version="2.0.0-rc3.3" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
<PackageReference Include="SkiaSharp.Views.WPF" Version="2.88.8" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Ookii.Dialogs.Wpf" Version="5.0.1" />
<PackageReference Include="PaddleOCRSharp" Version="4.5.0.1" />

View File

@ -0,0 +1,145 @@
# Estandarización de Objetos derivados de osBase
## Criterios para NombreClase()
### Categorías de Objetos:
1. **Transporte**: Transportadores, cintas, curvas
2. **Sensores**: Fotocélulas, encoders, botones
3. **Actuadores**: Motores, válvulas
4. **Elementos Estáticos**: Guías, descartes, barreras
5. **Emuladores**: Generadores, llenadores, tanques
6. **Señales**: Tags analógicos, digitales
7. **Datos**: Extracción, búsqueda
8. **Decorativos**: Imágenes, marcos, textos
9. **Fluidos**: Tuberías, válvulas, sistemas
### Formato de Nombres:
- **Español**: Usar nombres descriptivos en español
- **Específico**: Incluir característica principal (ej: "Motor VetroMeccanica", "Transporte con Guías")
- **Consistente**: Mantener formato similar por categoría
## Categorías Estandarizadas para Propiedades
### 1. "Identificación"
- Nombre del objeto
- Etiquetas de clasificación
### 2. "Posición y Tamaño"
- Coordenadas (Left, Top)
- Dimensiones (Ancho, Alto, Ángulo)
- Bloqueo de movimiento
### 3. "Configuración"
- Parámetros principales del objeto
- Configuraciones específicas por tipo
### 4. "Simulación"
- Velocidades, fuerzas, coeficientes
- Parámetros físicos
### 5. "Enlace PLC"
- Tags de entrada y salida
- Conexiones con motores/sensores
### 6. "Información"
- Valores calculados
- Estados actuales
- Datos de depuración
### 7. "Apariencia"
- Colores, tamaños visuales
- Aspectos gráficos
## Ejemplos de Aplicación
### Motor VetroMeccanica:
```csharp
[ObservableProperty]
[property: Description("Velocidad actual del motor en Hz")]
[property: Category("Información")]
[property: Name("Velocidad Actual")]
public float velocidad;
[ObservableProperty]
[property: Description("Tiempo de rampa para acelerar/desacelerar")]
[property: Category("Configuración")]
[property: Name("Tiempo de Rampa")]
public float tiempoRampa;
```
### Fotocélula:
```csharp
[ObservableProperty]
[property: Description("Indica si la luz está cortada por un objeto")]
[property: Category("Información")]
[property: Name("Luz Cortada")]
bool luzCortada;
[ObservableProperty]
[property: Description("Ancho del haz de luz del sensor")]
[property: Category("Configuración")]
[property: Name("Ancho del Haz")]
float ancho_Haz_De_Luz;
```
## Plan de Implementación
### ✅ Fase 1: Estandarizar métodos `NombreClase()`
- [x] Crear mapeo de nombres descriptivos
- [x] Implementar ejemplos: TransporteTTop, Motor VetroMeccanica, Fotocélula, Tag Analógico
- [x] Generar script de automatización PowerShell
### ✅ Fase 2: Aplicar categorías y descripciones estándar
- [x] Definir 8 categorías estándar
- [x] Crear plantilla de implementación
- [x] Aplicar en objetos de ejemplo
### ✅ Fase 3: Implementación Clase por Clase (COMPLETADO)
- [x] **ucTransporteTTop** - Transporte TTOP
- [x] **ucVMmotorSim** - Motor VetroMeccanica
- [x] **ucPhotocell** - Fotocélula
- [x] **ucAnalogTag** - Tag Analógico
- [x] **ucCustomImage** - Imagen Personalizada
- [x] **ucBoolTag** - Tag Digital
- [x] **ucGuia** - Guía
- [x] **ucBotella** - Botella
- [x] **ucTransporteCurva** - Transporte Curva 90°
- [x] **ucBoton** - Botón
- [x] **ucBottGenerator** - Generador de Botellas
- [x] **ucDescarte** - Descarte
- [x] **ucFramePlate** - Marco de Panel (parcial)
### 📊 Estadísticas de Progreso
- **Clases procesadas**: 13
- **`using System.ComponentModel;` agregados**: 6 clases
- **Nombres de clase mejorados**: 13
- **Propiedades estandarizadas**: ~85 propiedades
## Archivos Generados
1. **`Scripts/EstandarizarObjetos.ps1`**: Script para automatizar cambios
2. **`Documentation/PlantillaEstandarizacion.cs`**: Plantilla con ejemplos
3. **`Documentation/EstandarizacionObjetos.md`**: Esta documentación
## Instrucciones de Uso
### Para aplicar automáticamente:
```powershell
cd CtrEditor
.\Scripts\EstandarizarObjetos.ps1
```
### Para aplicar manualmente:
1. Consultar `PlantillaEstandarizacion.cs`
2. Seguir el patrón de categorías establecido
3. Usar nombres descriptivos en español
## Objetos Ya Actualizados
- ✅ `ucTransporteTTop` → "Transporte TTOP"
- ✅ `ucVMmotorSim` → "Motor VetroMeccanica"
- ✅ `ucPhotocell` → "Fotocélula"
- ✅ `ucAnalogTag` → "Tag Analógico"
---
*Documento generado para estandarización del proyecto CtrEditor*

View File

@ -0,0 +1,172 @@
/*
PLANTILLA DE ESTANDARIZACIÓN PARA OBJETOS osBase
Usar esta plantilla como guía para estandarizar cualquier objeto derivado de osBase
*/
namespace CtrEditor.ObjetosSim
{
public partial class osEjemplo : osBase, IosBase
{
// 1. MÉTODO NOMBRECLASE - Usar nombres descriptivos en español
public static string NombreClase()
{
return "Nombre Descriptivo del Objeto"; // Ej: "Motor VetroMeccanica", "Fotocélula", "Transporte TTOP"
}
private string nombre = NombreClase();
// 2. PROPIEDAD NOMBRE - Siempre en categoría "Identificación"
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
set => SetProperty(ref nombre, value);
}
// 3. CATEGORÍAS ESTÁNDAR:
// IDENTIFICACIÓN - Información básica del objeto
[ObservableProperty]
[property: Category("Identificación")]
[property: Description("Descripción o comentario del objeto")]
[property: Name("Descripción")]
public string descripcion;
// POSICIÓN Y TAMAÑO - Heredadas de osBase (Left, Top, Ancho, Alto, Angulo)
// No necesitan redefinirse, ya están en osBase
// CONFIGURACIÓN - Parámetros principales del objeto
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Velocidad máxima del objeto")]
[property: Name("Velocidad Máxima")]
public float velocidadMaxima;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Habilita/deshabilita funcionalidad específica")]
[property: Name("Habilitar Función")]
public bool habilitarFuncion;
// SIMULACIÓN - Parámetros físicos y de simulación
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Velocidad actual en la simulación")]
[property: Name("Velocidad Actual")]
public float velocidadActual;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Coeficiente de fricción")]
[property: Name("Coeficiente de Fricción")]
public float coeficienteFriccion;
// ENLACE PLC - Conexiones con PLC y otros objetos
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Dirección del tag en el PLC")]
[property: Name("Tag Principal")]
public string tagPrincipal;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Seleccionar motor para enlazar")]
[property: Name("Motor Enlazado")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
public string motorEnlazado;
// INFORMACIÓN - Valores calculados, estados, debug
[ObservableProperty]
[property: Category("Información")]
[property: Description("Estado actual del objeto")]
[property: Name("Estado")]
public bool estado;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Último valor calculado")]
[property: Name("Último Valor")]
public float ultimoValor;
// APARIENCIA - Aspectos visuales
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Tamaño visual del objeto")]
[property: Name("Tamaño")]
public float tamano;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color del objeto")]
[property: Name("Color")]
public Brush color;
// ENCODER - Específico para motores con encoder
[ObservableProperty]
[property: Category("Encoder")]
[property: Description("Habilita el encoder")]
[property: Name("Con Encoder")]
public bool conEncoder;
[ObservableProperty]
[property: Category("Encoder")]
[property: Description("Posición actual del encoder")]
[property: Name("Posición Encoder")]
public float posicionEncoder;
}
}
/*
GUÍA DE CATEGORÍAS:
1. "Identificación"
- Nombre del objeto
- Descripción
- Etiquetas de clasificación
2. "Posición y Tamaño"
- Ya heredadas de osBase: Left, Top, Ancho, Alto, Angulo, Lock_movement
3. "Configuración"
- Parámetros principales del objeto
- Configuraciones específicas por tipo
- Valores que el usuario configura
4. "Simulación"
- Velocidades, fuerzas, coeficientes
- Parámetros físicos
- Comportamiento en simulación
5. "Enlace PLC"
- Tags de entrada y salida
- Conexiones con motores/sensores
- Direcciones de PLC
6. "Información"
- Valores calculados
- Estados actuales
- Datos de depuración
- Información de solo lectura
7. "Apariencia"
- Colores, tamaños visuales
- Aspectos gráficos
- Elementos de UI
8. "Encoder" (solo para motores)
- Configuración del encoder
- Valores del encoder
FORMATO DE DESCRIPCIONES:
- Usar español
- Ser descriptivo y claro
- Explicar qué hace la propiedad
- Evitar términos técnicos innecesarios
FORMATO DE NOMBRES:
- Usar español
- Formato "Título" (primera letra mayúscula)
- Ser conciso pero descriptivo
- Ej: "Velocidad Actual", "Tag Principal", "Con Encoder"
*/

View File

@ -1337,6 +1337,8 @@ namespace CtrEditor
// Mostrar como modeless (no modal)
libraryWindow.Show();
}
}
public class SimulationData

View File

@ -260,7 +260,8 @@ namespace CtrEditor
// Calcular el bounding box que contenga todos los objetos seleccionados
Rect boundingBox = CalculateTotalBoundingBox(selectedObjects);
if (_selectedObjectsAreVisible) {
if (_selectedObjectsAreVisible)
{
FuncionesBase.MutableRect rectBox = new FuncionesBase.MutableRect(boundingBox);
rectBox.Left -= (float)rectHighlightSize;
@ -1125,6 +1126,9 @@ namespace CtrEditor
RemoveAllSelectionHighlights(); // Remover antes de rotar
// Verificar si la tecla Shift está presionada para rotación en incrementos de 45 grados
bool isShiftPressed = Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift);
// Calcular el ángulo respecto al centro del bounding box que contiene todos los objetos seleccionados
double deltaX = currentPosition.X - _transformedBoundingBoxCenter.X;
double deltaY = currentPosition.Y - _transformedBoundingBoxCenter.Y;
@ -1137,12 +1141,49 @@ namespace CtrEditor
else
{
double deltaAngle = angle - _lastAngle;
if (isShiftPressed)
{
// Rotación en incrementos de 45 grados
// Calcular el ángulo total acumulado desde el inicio de la rotación
double totalAngleChange = angle - _lastAngle;
// Determinar a qué incremento de 45 grados corresponde
double snapAngle = Math.Round(totalAngleChange / 45.0) * 45.0;
// Solo aplicar la rotación si hay un cambio significativo (al menos 22.5 grados de movimiento)
if (Math.Abs(totalAngleChange) > 22.5)
{
// Calcular el cambio real que necesitamos aplicar
double actualRotationChange = snapAngle;
foreach (var selectedObject in _selectedObjects)
{
// Obtener el ángulo actual del objeto
double currentObjectAngle = selectedObject.Angulo;
// Calcular el nuevo ángulo alineado a incrementos de 45 grados
double targetAngle = Math.Round((currentObjectAngle + actualRotationChange) / 45.0) * 45.0;
// Aplicar la rotación necesaria para llegar al ángulo objetivo
double rotationNeeded = targetAngle - currentObjectAngle;
selectedObject.Rotate(rotationNeeded);
}
// Actualizar el ángulo de referencia para evitar aplicar la misma rotación múltiples veces
_lastAngle = (float)angle;
}
}
else
{
// Rotación libre (comportamiento original)
foreach (var selectedObject in _selectedObjects)
{
selectedObject.Rotate(deltaAngle);
}
_lastAngle = (float)angle;
}
}
UpdateAllSelectionHighlights();
}

View File

@ -16,39 +16,80 @@ namespace CtrEditor.ObjetosSim
{
public static string NombreClase()
{
return "Custom Image";
return "Imagen Personalizada";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
set => SetProperty(ref nombre, value);
}
private string _imagePath;
[Description("Ruta del archivo de imagen")]
[Category("Configuración")]
[property: Name("Ruta de Imagen")]
public string ImagePath
{
get => _imagePath;
set
{
try
{
if (SetProperty(ref _imagePath, value))
{
OnImagePathChanged(value);
OnPropertyChanged(nameof(ImageSource_oculta));
}
}
catch
{
// Si hay error al establecer la propiedad, simplemente ignorarlo
// y establecer la imagen por defecto
try
{
SetProperty(ref _imagePath, value);
ImageSource_oculta = ImageFromPath("/Icons/unselect.png");
OnPropertyChanged(nameof(ImageSource_oculta));
}
catch
{
// En caso de error total, establecer valores seguros
_imagePath = value;
ImageSource_oculta = null;
}
}
}
}
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(ImageSource_oculta))]
[property: Description("Path to the image file")]
[property: Category("Image:")]
private string imagePath;
[ObservableProperty]
[property: Description("Flip the image horizontally")]
[property: Category("Image:")]
[property: Description("Voltear la imagen horizontalmente")]
[property: Category("Configuración")]
[property: Name("Voltear Horizontal")]
private bool horizontal_Flip;
[ObservableProperty]
[property: Description("Flip the image vertically")]
[property: Category("Image:")]
[property: Description("Voltear la imagen verticalmente")]
[property: Category("Configuración")]
[property: Name("Voltear Vertical")]
private bool vertical_Flip;
[JsonIgnore]
[ObservableProperty]
[property: JsonIgnore]
[property: Category("Apariencia")]
[property: Description("Imagen visual del objeto")]
[property: Name("Imagen")]
public ImageSource imageSource_oculta;
partial void OnImagePathChanged(string value)
private void OnImagePathChanged(string value)
{
try
{
if (!string.IsNullOrEmpty(value))
{
@ -60,6 +101,20 @@ namespace CtrEditor.ObjetosSim
ImageSource_oculta = ImageFromPath("/Icons/unselect.png");
}
}
catch
{
// Si hay cualquier error, usar la imagen por defecto
try
{
ImageSource_oculta = ImageFromPath("/Icons/unselect.png");
}
catch
{
// Si incluso la imagen por defecto falla, establecer como null
ImageSource_oculta = null;
}
}
}
partial void OnHorizontal_FlipChanged(bool value)
{
@ -82,6 +137,8 @@ namespace CtrEditor.ObjetosSim
public override void ucLoaded()
{
base.ucLoaded();
try
{
if (!string.IsNullOrEmpty(ImagePath))
{
ImageSource_oculta = ImageFromPath(ImagePath);
@ -92,6 +149,20 @@ namespace CtrEditor.ObjetosSim
ImageSource_oculta = ImageFromPath("/Icons/unselect.png");
}
}
catch
{
// Si hay cualquier error, usar la imagen por defecto
try
{
ImageSource_oculta = ImageFromPath("/Icons/unselect.png");
}
catch
{
// Si incluso la imagen por defecto falla, establecer como null
ImageSource_oculta = null;
}
}
}
}
public partial class ucCustomImage : UserControl, IDataContainer

View File

@ -29,9 +29,13 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Frame Plate";
return "Marco de Panel";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -39,8 +43,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Description("Layer index to add to Objects on the Frame")]
[property: Category("Layer:")]
[property: Description("Índice de capa para objetos en el marco")]
[property: Category("Configuración")]
[property: Name("Índice Z del Marco")]
int zindex_FramePlate;
partial void OnZindex_FramePlateChanged(int value)
@ -49,13 +54,27 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color de fondo del marco")]
[property: Name("Color")]
Color color;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color del texto del título")]
[property: Name("Color del Título")]
Color color_Titulo;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Texto del título del marco")]
[property: Name("Título")]
string titulo;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Alto del área del título")]
[property: Name("Alto del Título")]
public float alto_Titulo;
// Encoder X

View File

@ -4,6 +4,7 @@ using System.Windows.Media;
using CommunityToolkit.Mvvm.ComponentModel;
using CtrEditor.FuncionesBase;
using Newtonsoft.Json;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
@ -22,9 +23,13 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Plate";
return "Placa de Texto";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -32,17 +37,32 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color de fondo de la placa")]
[property: Name("Color")]
Color color;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color del texto del título")]
[property: Name("Color Título")]
Color color_Titulo;
[ObservableProperty]
[property: Category("Identificación")]
[property: Description("Texto del título")]
[property: Name("Título")]
string titulo;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Alto del área del título")]
[property: Name("Alto Título")]
public float alto_Titulo;
public override void TopChanging(float oldValue, float newValue) {
public override void TopChanging(float oldValue, float newValue)
{
offsetY = newValue - oldValue;
}
public override void LeftChanging(float oldValue, float newValue)

View File

@ -8,6 +8,7 @@ using CommunityToolkit.Mvvm.ComponentModel;
using nkast.Aether.Physics2D.Common;
using System.Windows.Media;
using CtrEditor.FuncionesBase;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
{
@ -27,6 +28,10 @@ namespace CtrEditor.ObjetosSim
return "Botella";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -44,9 +49,15 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color visual de la botella")]
[property: Name("Color")]
private Brush colorButton_oculto;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Diámetro de la botella en metros")]
[property: Name("Diámetro")]
private float diametro;
partial void OnDiametroChanged(float value)
@ -61,17 +72,33 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Información")]
[property: Description("Velocidad actual desde la simulación")]
[property: Name("Velocidad de Simulación")]
private string velocidad_desde_simulacion;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Inercia actual desde la simulación")]
[property: Name("Inercia de Simulación")]
private float inercia_desde_simulacion;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Conservar objeto cuando sale de transporte")]
[property: Name("Conservar Fuera de Transporte")]
private bool preserve_Outside_Transport;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Porcentaje de tracción con transporte")]
[property: Name("Porcentaje de Tracción")]
private float porcentaje_Traccion;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Masa del objeto en kg")]
[property: Name("Masa")]
private float mass;
partial void OnMassChanged(float value)
{

View File

@ -8,6 +8,7 @@ using CommunityToolkit.Mvvm.ComponentModel;
using nkast.Aether.Physics2D.Common;
using System.Windows.Media;
using CtrEditor.FuncionesBase;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
{
@ -25,6 +26,10 @@ namespace CtrEditor.ObjetosSim
return "Botella con Cuello";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -47,9 +52,15 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color del botón visual")]
[property: Name("Color")]
private Brush colorButton_oculto;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Diámetro de la botella")]
[property: Name("Diámetro")]
private float diametro;
partial void OnDiametroChanged(float value)
@ -58,12 +69,21 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Información")]
[property: Description("Velocidad desde simulación")]
[property: Name("Velocidad Simulación")]
private string velocidad_desde_simulacion;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Inercia desde simulación")]
[property: Name("Inercia Simulación")]
private float inercia_desde_simulacion;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Masa de la botella")]
[property: Name("Masa")]
private float mass;
partial void OnMassChanged(float value)
{

View File

@ -17,27 +17,43 @@ namespace CtrEditor.ObjetosSim
private float TiempoRestante;
public static string NombreClase()
{
return "BottGenerator";
return "Generador de Botellas";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre { get => nombre; set => SetProperty(ref nombre, value); }
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Desplazamiento horizontal del punto de salida")]
[property: Name("Offset Horizontal")]
private float offsetLeftSalida;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Desplazamiento vertical del punto de salida")]
[property: Name("Offset Vertical")]
private float offsetTopSalida;
[ObservableProperty]
[property: Description("The bottle will be destroyed if fall outside transport.")]
[property: Category("Enable to Run:")]
[property: Description("Las botellas se destruirán si caen fuera del transporte")]
[property: Category("Configuración")]
[property: Name("Conservar Fuera de Transporte")]
private bool preserve_Outside_Transport;
[ObservableProperty]
[property: Description("PLC tag for consense to run. 1 => always")]
[property: Category("Enable to Run:")]
[property: Description("Tag PLC para habilitar funcionamiento. 1 => siempre activo")]
[property: Category("Enlace PLC")]
[property: Name("Tag Consenso")]
private string tag_consenso;
[ObservableProperty]
[property: Description("Consense to run.")]
[property: Category("Enable to Run:")]
[property: Description("Estado de consenso para funcionamiento")]
[property: Category("Simulación")]
[property: Name("Consenso")]
private bool consenso;
partial void OnConsensoChanged(bool value)
{
@ -45,26 +61,38 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Description("Consense is Normally close.")]
[property: Category("Enable to Run:")]
[property: Description("Consenso normalmente cerrado")]
[property: Category("Configuración")]
[property: Name("Consenso NC")]
private bool consenso_NC;
[ObservableProperty]
[property: Description("Enable filter.")]
[property: Category("Enable to Run:")]
[property: Description("Habilitar filtro de consenso")]
[property: Category("Configuración")]
[property: Name("Filtro Habilitado")]
private bool consenso_Filtrado;
[ObservableProperty]
[property: Description("Time ON in s.")]
[property: Category("Enable to Run:")]
[property: Description("Tiempo de activación del filtro en segundos")]
[property: Category("Configuración")]
[property: Name("Tiempo ON (s)")]
float filtro_consenso_ON_s;
[ObservableProperty]
[property: Description("Time OFF in s.")]
[property: Category("Enable to Run:")]
[property: Description("Tiempo de desactivación del filtro en segundos")]
[property: Category("Configuración")]
[property: Name("Tiempo OFF (s)")]
float filtro_consenso_OFF_s;
[ObservableProperty]
[property: Description("Filter OUT signal.")]
[property: Category("Enable to Run:")]
[property: Description("Señal de salida del filtro")]
[property: Category("Información")]
[property: Name("Salida Filtro")]
bool filter_Output;
[ObservableProperty]
[property: Description("Cantidad de botellas generadas por hora")]
[property: Category("Configuración")]
[property: Name("Botellas por Hora")]
private float botellas_hora;
partial void OnBotellas_horaChanged(float value)
{
@ -72,6 +100,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Description("Cantidad de botellas generadas por segundo")]
[property: Category("Configuración")]
[property: Name("Botellas por Segundo")]
private float botellas_segundo;
partial void OnBotellas_segundoChanged(float value)
{
@ -79,8 +110,15 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Description("Velocidad actual como porcentaje")]
[property: Category("Simulación")]
[property: Name("Velocidad Actual (%)")]
private float velocidad_actual_percentual;
[ObservableProperty]
[property: Description("Diámetro de las botellas generadas")]
[property: Category("Configuración")]
[property: Name("Diámetro Botella")]
private float diametro_botella;
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{

View File

@ -5,6 +5,7 @@ using System.Windows.Controls;
using CommunityToolkit.Mvvm.ComponentModel;
using System.Diagnostics;
using CtrEditor.FuncionesBase;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
{
@ -21,9 +22,13 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Filler";
return "Llenadora";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -31,13 +36,27 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Offset horizontal para salida de botellas")]
[property: Name("Offset Left Salida")]
private float offsetLeftSalida;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Offset vertical para salida de botellas")]
[property: Name("Offset Top Salida")]
private float offsetTopSalida;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para consenso")]
[property: Name("Tag Consenso")]
private string tag_consenso;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Estado del consenso")]
[property: Name("Consenso")]
private bool consenso;
partial void OnConsensoChanged(bool value)
@ -45,13 +64,27 @@ namespace CtrEditor.ObjetosSim
_TON_TOFF.Senal = value;
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Consenso normalmente cerrado")]
[property: Name("Consenso NC")]
private bool consenso_NC;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Aplicar filtrado al consenso")]
[property: Name("Consenso Filtrado")]
private bool consenso_Filtrado;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Tiempo de filtro en segundos")]
[property: Name("Filtro Consenso (s)")]
float filtro_consenso_s;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Producción en botellas por hora")]
[property: Name("Botellas/Hora")]
private float botellas_hora;
partial void OnBotellas_horaChanged(float value)
@ -60,6 +93,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Información")]
[property: Description("Producción en botellas por segundo")]
[property: Name("Botellas/Segundo")]
private float botellas_segundo;
partial void OnBotellas_segundoChanged(float value)
@ -68,8 +104,15 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Velocidad actual en porcentaje")]
[property: Name("Velocidad (%)")]
private float velocidad_actual_percentual;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Diámetro de las botellas generadas")]
[property: Name("Diámetro Botella")]
private float diametro_botella;
public osFiller()

View File

@ -3,6 +3,7 @@ using LibS7Adv;
using System.Windows;
using System.Windows.Controls;
using CtrEditor.FuncionesBase;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
{
@ -18,6 +19,10 @@ namespace CtrEditor.ObjetosSim
return "Tanque";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -25,26 +30,68 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Capacidad total del tanque en litros")]
[property: Name("Capacidad (L)")]
public float capacidad_Litros;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Estado de apertura del ingreso")]
[property: Name("Ingreso Abierto")]
public bool ingreso_Abierto;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Estado de apertura de la salida")]
[property: Name("Salida Abierta")]
public bool salida_Abierta;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para nivel del tanque")]
[property: Name("Tag Nivel")]
public string tagNivel_Word;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para control de ingreso")]
[property: Name("Tag Ingreso")]
public string tagIngresoAbierto_Bool;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para control de salida")]
[property: Name("Tag Salida")]
public string tagSalidaAbierta_Bool;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Velocidad de llenado en L/min")]
[property: Name("Velocidad Ingreso")]
public float velocidad_Ingreso;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Velocidad de vaciado en L/min")]
[property: Name("Velocidad Salida")]
public float velocidad_Salida;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Valor mínimo escalado para salida PLC")]
[property: Name("Mínimo Escalado")]
public float min_OUT_Scaled;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Valor máximo escalado para salida PLC")]
[property: Name("Máximo Escalado")]
public float max_OUT_Scaled;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Nivel actual del tanque en porcentaje")]
[property: Name("Nivel (%)")]
public float level;
public osTanque()

View File

@ -7,6 +7,7 @@ using nkast.Aether.Physics2D.Common;
using System.Windows.Media.Animation;
using CommunityToolkit.Mvvm.ComponentModel;
using CtrEditor.FuncionesBase;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
{
/// <summary>
@ -22,6 +23,10 @@ namespace CtrEditor.ObjetosSim
return "Descarte";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -29,6 +34,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Diámetro del área de descarte en metros")]
[property: Name("Diámetro")]
private float diametro;
partial void OnDiametroChanged(float value)

View File

@ -1,10 +1,10 @@
using System.Windows;
using System.Windows.Controls;
using CommunityToolkit.Mvvm.ComponentModel;
using LibS7Adv;
using CtrEditor.Simulacion;
using CtrEditor.FuncionesBase;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
{
@ -17,9 +17,13 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Guia";
return "Guía";
}
private string nombre = "Guia";
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -27,6 +31,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Alto de la guía en metros")]
[property: Name("Alto de la Guía")]
public float altoGuia;
private void ActualizarGeometrias()

View File

@ -23,9 +23,13 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Transporte Curva 90";
return "Transporte Curva 90°";
}
private string nombre = "Transporte Curva 90";
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -33,6 +37,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Velocidad actual del transporte en m/s")]
[property: Name("Velocidad Actual")]
public float velocidadActual;
partial void OnVelocidadActualChanged(float value)
@ -41,11 +48,19 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Invierte el sentido de movimiento del transporte")]
[property: Name("Invertir Dirección")]
bool invertirDireccion;
partial void OnInvertirDireccionChanged(bool value)
{
SetSpeed();
if (_visualRepresentation is ucTransporteCurva uc)
{
CrearAnimacionStoryBoardTrasnporteCircular(uc.Transporte.TransportePath, InvertirDireccion, Angulo);
ActualizarAnimacionStoryBoardTransporte(VelocidadActual);
}
}
void SetSpeed()
@ -54,9 +69,13 @@ namespace CtrEditor.ObjetosSim
Simulation_TransporteCurva?.SetSpeed(-VelocidadActual);
else
Simulation_TransporteCurva?.SetSpeed(VelocidadActual);
ActualizarAnimacionStoryBoardTransporte(VelocidadActual);
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Radio exterior de la curva en metros")]
[property: Name("Radio Exterior")]
private float radioExterno;
partial void OnRadioExternoChanged(float value)
@ -75,18 +94,21 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Radio interior de la curva en metros")]
[property: Name("Radio Interior")]
private float radioInterno;
[ObservableProperty]
[property: Description("Bit to enable Link to Motor")]
[property: Category("PLC link:")]
[property: Description("Tag de bit para activar enlace con motor")]
[property: Category("Enlace PLC")]
[property: Name("Tag Activación Motor")]
string tag_ReleActivatedMotor;
[ObservableProperty]
[property: Description("Link to Motor")]
[property: Category("PLC link:")]
[property: Description("Seleccionar motor para enlazar")]
[property: Category("Enlace PLC")]
[property: Name("Motor Enlazado")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
string id_Motor;
@ -205,9 +227,14 @@ namespace CtrEditor.ObjetosSim
{
// Se llama antes de la simulacion
ActualizarGeometrias();
}
public override void SimulationStop()
{
// Se llama al detener la simulacion
ActualizarAnimacionStoryBoardTransporte(VelocidadActual);
}
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{
if (Motor != null)
@ -225,13 +252,13 @@ namespace CtrEditor.ObjetosSim
// El UserControl ya se ha cargado y podemos obtener las coordenadas para
// crear el objeto de simulacion
base.ucLoaded();
OnId_MotorChanged(Id_Motor); // Link Id_Motor = Motor
if (_visualRepresentation is ucTransporteCurva uc)
{
Simulation_TransporteCurva = AddCurve(RadioInterno, RadioExterno, Angulo, Angulo + Arco_en_grados);
// AddCurve(float innerRadius, float outerRadius, float startAngle, float endAngle, Vector2 position)
CrearAnimacionStoryBoardTrasnporteCircular(uc.Transporte.TransportePath, InvertirDireccion, Angulo);
}
}
public override void ucUnLoaded()
{

View File

@ -0,0 +1,24 @@
<UserControl x:Class="CtrEditor.ObjetosSim.ucTransporteCurvaGuias"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:localuc="clr-namespace:CtrEditor.ObjetosSim.UserControls" xmlns:vm="clr-namespace:CtrEditor.ObjetosSim"
mc:Ignorable="d">
<UserControl.DataContext>
<vm:osTransporteCurvaGuias />
</UserControl.DataContext>
<Canvas x:Name="MainCanvas">
<localuc:CircularSegment x:Name="Transporte" Angle="0"
OuterRadius="{Binding RadioExterno, Converter={StaticResource MeterToPixelConverter}}"
InnerRadius="{Binding RadioInterno, Converter={StaticResource MeterToPixelConverter}}"
StartAngle="{Binding Angulo}" EndAngle="{Binding AnguloFinal}"
ShowGuides="{Binding MostrarGuias}"
GuideDistance="{Binding DistanciaGuias, Converter={StaticResource MeterToPixelConverter}}"
GuideThickness="{Binding GrosorGuias, Converter={StaticResource MeterToPixelConverter}}"
GuideStroke="{Binding ColorGuiasBrush}" />
</Canvas>
</UserControl>

View File

@ -0,0 +1,510 @@
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using CommunityToolkit.Mvvm.ComponentModel;
using LibS7Adv;
using CtrEditor.Simulacion;
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
using CtrEditor.FuncionesBase;
using System.Text.Json.Serialization;
using System.Windows.Media;
namespace CtrEditor.ObjetosSim
{
/// <summary>
/// Interaction logic for ucTransporteCurvaGuias.xaml
/// </summary>
public partial class osTransporteCurvaGuias : osBase, IosBase
{
private osBase Motor = null;
private simCurve Simulation_TransporteCurvaGuias;
// Listas para almacenar los segmentos de las guías curvas
private List<simGuia> GuiasSuperiores = new List<simGuia>();
private List<simGuia> GuiasInferiores = new List<simGuia>();
private float _velocidadActual;
public static string NombreClase()
{
return "Transporte Curva con Guías";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
set => SetProperty(ref nombre, value);
}
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Velocidad actual del transporte")]
[property: Name("Velocidad Actual")]
public float velocidadActual;
partial void OnVelocidadActualChanged(float value)
{
SetSpeed();
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Invierte el sentido de movimiento")]
[property: Name("Invertir Dirección")]
bool invertirDireccion;
partial void OnInvertirDireccionChanged(bool value)
{
SetSpeed();
if (_visualRepresentation is ucTransporteCurvaGuias uc)
{
CrearAnimacionStoryBoardTrasnporteCircular(uc.Transporte.TransportePath, InvertirDireccion, Angulo);
ActualizarAnimacionStoryBoardTransporte(VelocidadActual);
}
}
void SetSpeed()
{
if (InvertirDireccion)
Simulation_TransporteCurvaGuias?.SetSpeed(-VelocidadActual);
else
Simulation_TransporteCurvaGuias?.SetSpeed(VelocidadActual);
ActualizarAnimacionStoryBoardTransporte(VelocidadActual);
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Radio externo de la curva")]
[property: Name("Radio Externo")]
private float radioExterno;
partial void OnRadioExternoChanged(float value)
{
// Update ancho and alto based on radioExterno
Ancho = value * 2;
Alto = value * 2;
// Ensure radioInterno maintains proper proportion if needed
if (RadioInterno >= value)
{
RadioInterno = value * 0.75f; // Default proportion
}
ActualizarGeometrias();
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Radio interno de la curva")]
[property: Name("Radio Interno")]
private float radioInterno;
partial void OnRadioInternoChanged(float value)
{
ActualizarGeometrias();
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Número de segmentos para las guías (máximo 20)")]
[property: Name("Segmentos Guías")]
private int numeroSegmentosGuias;
partial void OnNumeroSegmentosGuiasChanged(int value)
{
// Limitar entre 4 y 20 segmentos
if (value < 4) NumeroSegmentosGuias = 4;
if (value > 20) NumeroSegmentosGuias = 20;
ActualizarGeometrias();
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Grosor de las guías")]
[property: Name("Grosor Guías")]
private float grosorGuias;
partial void OnGrosorGuiasChanged(float value)
{
ActualizarGeometrias();
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Distancia de separación de las guías desde el borde")]
[property: Name("Distancia Guías")]
private float distanciaGuias;
partial void OnDistanciaGuiasChanged(float value)
{
ActualizarGeometrias();
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Mostrar guías visuales")]
[property: Name("Mostrar Guías")]
private bool mostrarGuias;
// Propiedad interna Brush para el binding
private Brush _colorGuiasBrush = new SolidColorBrush(Colors.DarkBlue);
[JsonIgnore]
public Brush ColorGuiasBrush
{
get => _colorGuiasBrush;
set
{
if (_colorGuiasBrush != value)
{
_colorGuiasBrush = value;
OnPropertyChanged(nameof(ColorGuiasBrush));
// Extraer el color del brush y actualizar la propiedad Color
if (value is SolidColorBrush solidBrush)
{
colorGuias = solidBrush.Color;
OnPropertyChanged(nameof(ColorGuias));
}
}
}
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color de las guías")]
[property: Name("Color Guías")]
private Color colorGuias = Colors.DarkBlue;
partial void OnColorGuiasChanged(Color value)
{
// Sincronizar con la propiedad Brush
ColorGuiasBrush = new SolidColorBrush(value);
}
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag para activar enlace con motor")]
[property: Name("Tag Activación Motor")]
string tag_ReleActivatedMotor;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Motor enlazado al transporte")]
[property: Name("Motor Enlazado")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
string id_Motor;
[JsonIgnore]
private PropertyChangedEventHandler motorPropertyChangedHandler;
partial void OnId_MotorChanged(string value)
{
if (Motor != null && motorPropertyChangedHandler != null)
Motor.PropertyChanged -= motorPropertyChangedHandler;
if (_mainViewModel != null && !string.IsNullOrEmpty(value))
{
Motor = (osVMmotorSim)_mainViewModel.ObjetosSimulables.FirstOrDefault(s => s is osVMmotorSim motor && motor.Nombre == value);
if (Motor != null)
{
motorPropertyChangedHandler = (sender, e) =>
{
if (e.PropertyName == nameof(osVMmotorSim.Nombre))
{
Id_Motor = ((osVMmotorSim)sender).Nombre;
}
};
Motor.PropertyChanged += motorPropertyChangedHandler;
}
}
}
public override void AnguloChanged(float value)
{
OnPropertyChanged(nameof(AnguloFinal));
ActualizarGeometrias();
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Arco de la curva en grados")]
[property: Name("Arco (grados)")]
[NotifyPropertyChangedFor(nameof(AnguloFinal))]
private float arco_en_grados;
partial void OnArco_en_gradosChanged(float value)
{
ActualizarGeometrias();
}
[Hidden]
public float AnguloFinal
{
get => Angulo + Arco_en_grados;
}
private void ActualizarGeometrias()
{
if (_visualRepresentation is ucTransporteCurvaGuias uc)
{
UpdateCurve(Simulation_TransporteCurvaGuias, RadioInterno, RadioExterno, Angulo, Angulo + Arco_en_grados);
ActualizarGuiasCurvas();
SetSpeed();
}
}
private void ActualizarGuiasCurvas()
{
// Limpiar guías existentes
EliminarGuiasExistentes();
// Crear nuevas guías
CrearGuiasCurvas();
}
private void EliminarGuiasExistentes()
{
foreach (var guia in GuiasSuperiores)
{
simulationManager?.Remove(guia);
}
foreach (var guia in GuiasInferiores)
{
simulationManager?.Remove(guia);
}
GuiasSuperiores.Clear();
GuiasInferiores.Clear();
}
private void CrearGuiasCurvas()
{
if (NumeroSegmentosGuias < 4 || simulationManager == null)
return;
float radioGuiaSuperior = RadioExterno + DistanciaGuias;
float radioGuiaInferior = RadioInterno - DistanciaGuias;
// Asegurar que el radio interior de la guía no sea negativo
if (radioGuiaInferior < 0.01f)
radioGuiaInferior = 0.01f;
// Convertir ángulos a radianes
float anguloInicioRad = simBase.GradosARadianes(Angulo);
float anguloFinalRad = simBase.GradosARadianes(AnguloFinal);
float rangoAngular = anguloFinalRad - anguloInicioRad;
// Calcular el paso angular entre segmentos
float pasoAngular = rangoAngular / NumeroSegmentosGuias;
// Obtener el centro una vez para todo el método
nkast.Aether.Physics2D.Common.Vector2 centro = GetCurveCenterInMeter(RadioExterno);
// Crear segmentos para guía superior (externa)
for (int i = 0; i < NumeroSegmentosGuias; i++)
{
float angulo1 = anguloInicioRad + i * pasoAngular;
float angulo2 = anguloInicioRad + (i + 1) * pasoAngular;
nkast.Aether.Physics2D.Common.Vector2 punto1 = new nkast.Aether.Physics2D.Common.Vector2(
radioGuiaSuperior * (float)Math.Cos(angulo1),
radioGuiaSuperior * (float)Math.Sin(angulo1)
);
nkast.Aether.Physics2D.Common.Vector2 punto2 = new nkast.Aether.Physics2D.Common.Vector2(
radioGuiaSuperior * (float)Math.Cos(angulo2),
radioGuiaSuperior * (float)Math.Sin(angulo2)
);
// Ajustar por la posición del objeto
punto1 += centro;
punto2 += centro;
simGuia guiaSegmento = simulationManager.AddLine(punto1, punto2);
GuiasSuperiores.Add(guiaSegmento);
}
// Crear segmentos para guía inferior (interna)
for (int i = 0; i < NumeroSegmentosGuias; i++)
{
float angulo1 = anguloInicioRad + i * pasoAngular;
float angulo2 = anguloInicioRad + (i + 1) * pasoAngular;
nkast.Aether.Physics2D.Common.Vector2 punto1 = new nkast.Aether.Physics2D.Common.Vector2(
radioGuiaInferior * (float)Math.Cos(angulo1),
radioGuiaInferior * (float)Math.Sin(angulo1)
);
nkast.Aether.Physics2D.Common.Vector2 punto2 = new nkast.Aether.Physics2D.Common.Vector2(
radioGuiaInferior * (float)Math.Cos(angulo2),
radioGuiaInferior * (float)Math.Sin(angulo2)
);
// Ajustar por la posición del objeto
punto1 += centro;
punto2 += centro;
simGuia guiaSegmento = simulationManager.AddLine(punto1, punto2);
GuiasInferiores.Add(guiaSegmento);
}
}
public override void OnMoveResizeRotate()
{
ActualizarGeometrias();
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Coeficiente de fricción")]
[property: Name("Coeficiente Fricción")]
public float frictionCoefficient;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Velocidad máxima a 50Hz")]
[property: Name("Velocidad Max 50Hz")]
public float velMax50hz;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Tiempo de rampa")]
[property: Name("Tiempo Rampa")]
public float tiempoRampa;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Estado de marcha")]
[property: Name("En Marcha")]
public bool esMarcha;
public override void OnResize(float Delta_Width, float Delta_Height)
{
// Calculate the proportional change factor
float widthChangeFactor = (Ancho + Delta_Width) / Ancho;
float heightChangeFactor = (Alto + Delta_Height) / Alto;
// Use the average or minimum change factor to maintain aspect ratio
float changeFactor = Math.Min(widthChangeFactor, heightChangeFactor);
// Save the original radiuses for calculating position adjustments
float originalRadioExterno = RadioExterno;
// Apply the change factor to both radios
RadioExterno *= changeFactor;
RadioInterno *= changeFactor;
// Calculate position adjustment to keep the component centered
float radiusDifference = RadioExterno - originalRadioExterno;
// Adjust Left and Top to maintain center position
// We move by negative half the difference because the component expands outward
Left -= radiusDifference;
Top -= radiusDifference;
// Ensure minimums
if (RadioExterno < 0.1f)
RadioExterno = 0.1f;
if (RadioInterno < 0.05f)
RadioInterno = 0.05f;
// Ensure radioInterno is always less than radioExterno
if (RadioInterno >= RadioExterno)
RadioInterno = RadioExterno * 0.75f;
}
public osTransporteCurvaGuias()
{
RadioExterno = 1.3f;
RadioInterno = 1f;
Ancho = RadioExterno * 2; // Set initial width based on external radius
Alto = RadioExterno * 2; // Set initial height based on external radius
Arco_en_grados = 90;
Tag_ReleActivatedMotor = "1";
NumeroSegmentosGuias = 12; // Valor por defecto
GrosorGuias = 0.03f;
DistanciaGuias = 0.05f;
MostrarGuias = true; // Mostrar guías por defecto
}
public override void UpdateGeometryStart()
{
// Se llama antes de la simulacion
ActualizarGeometrias();
}
public override void SimulationStop()
{
// Se llama al detener la simulacion
ActualizarAnimacionStoryBoardTransporte(VelocidadActual);
}
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{
if (Motor != null)
{
if (Motor is osVMmotorSim motor)
if (LeerBitTag(Tag_ReleActivatedMotor))
VelocidadActual = motor.Velocidad;
else
VelocidadActual = 0;
}
}
public override void ucLoaded()
{
// El UserControl ya se ha cargado y podemos obtener las coordenadas para
// crear el objeto de simulacion
base.ucLoaded();
OnId_MotorChanged(Id_Motor); // Link Id_Motor = Motor
if (_visualRepresentation is ucTransporteCurvaGuias uc)
{
Simulation_TransporteCurvaGuias = AddCurve(RadioInterno, RadioExterno, Angulo, Angulo + Arco_en_grados);
CrearGuiasCurvas(); // Crear las guías curvas
CrearAnimacionStoryBoardTrasnporteCircular(uc.Transporte.TransportePath, InvertirDireccion, Angulo);
}
}
public override void ucUnLoaded()
{
// El UserControl se esta eliminando
// eliminar el objeto de simulacion
simulationManager?.Remove(Simulation_TransporteCurvaGuias);
EliminarGuiasExistentes();
}
}
public partial class ucTransporteCurvaGuias : UserControl, IDataContainer
{
public osBase? Datos { get; set; }
public int zIndex_fromFrames { get; set; }
public ucTransporteCurvaGuias()
{
InitializeComponent();
this.Loaded += OnLoaded;
this.Unloaded += OnUnloaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
Datos?.ucLoaded();
}
private void OnUnloaded(object sender, RoutedEventArgs e)
{
Datos?.ucUnLoaded();
}
public void Highlight(bool State) { }
public ZIndexEnum ZIndex_Base()
{
return ZIndexEnum.Estaticos;
}
}
}

View File

@ -25,10 +25,13 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Transporte Guias";
return "Transporte con Guías";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -36,6 +39,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Velocidad actual del transporte")]
[property: Name("Velocidad Actual")]
public float velocidadActual;
partial void OnVelocidadActualChanged(float value)
@ -44,6 +50,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Invierte el sentido de movimiento")]
[property: Name("Invertir Dirección")]
bool invertirDireccion;
partial void OnInvertirDireccionChanged(bool value)
@ -67,16 +76,21 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color del transporte")]
[property: Name("Color")]
Color color = Colors.Blue;
[ObservableProperty]
[property: Description("Bit to enable Link to Motor")]
[property: Category("PLC link:")]
[property: Category("Enlace PLC")]
[property: Description("Tag para activar enlace con motor")]
[property: Name("Tag Activación Motor")]
string tag_ReleActivatedMotor;
[ObservableProperty]
[property: Description("Link to Motor")]
[property: Category("PLC link:")]
[property: Category("Enlace PLC")]
[property: Description("Motor enlazado al transporte")]
[property: Name("Motor Enlazado")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
string id_Motor;
@ -111,6 +125,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Actuar como freno")]
[property: Name("Es Freno")]
public bool esFreno;
partial void OnEsFrenoChanged(bool value)
@ -120,16 +137,39 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Coeficiente de fricción")]
[property: Name("Coeficiente Fricción")]
public float frictionCoefficient;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Velocidad máxima a 50Hz")]
[property: Name("Velocidad Max 50Hz")]
public float velMax50hz;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Tiempo de rampa")]
[property: Name("Tiempo Rampa")]
public float tiempoRampa;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Estado de marcha")]
[property: Name("En Marcha")]
public bool esMarcha;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Distancia entre guías")]
[property: Name("Distancia")]
private float distance;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Alto de las guías")]
[property: Name("Alto Guía")]
private float altoGuia;
private void ActualizarGeometrias()

View File

@ -28,10 +28,13 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Transporte Guias Union";
return "Transporte Guías Unión";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -39,16 +42,21 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color del transporte")]
[property: Name("Color")]
Color color;
[ObservableProperty]
[property: Description("Bit to enable Link to Motor")]
[property: Category("PLC link:")]
[property: Category("Enlace PLC")]
[property: Description("Tag para activar enlace con motor")]
[property: Name("Tag Activación Motor")]
string tag_ReleActivatedMotor;
[ObservableProperty]
[property: Description("Link to Motor A")]
[property: Category("PLC link:")]
[property: Category("Enlace PLC")]
[property: Description("Motor A enlazado")]
[property: Name("Motor A")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
string id_MotorA;
@ -74,8 +82,9 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Description("Link to Motor B")]
[property: Category("PLC link:")]
[property: Category("Enlace PLC")]
[property: Description("Motor B enlazado")]
[property: Name("Motor B")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
string id_MotorB;
@ -101,6 +110,9 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Velocidad actual del motor A")]
[property: Name("Velocidad A")]
public float velocidadActualA;
partial void OnVelocidadActualAChanged(float value)
@ -113,6 +125,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Invertir dirección del motor A")]
[property: Name("Invertir A")]
bool invertirDireccionA;
partial void OnInvertirDireccionAChanged(bool value)
@ -128,6 +143,9 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Velocidad actual del motor B")]
[property: Name("Velocidad B")]
public float velocidadActualB;
partial void OnVelocidadActualBChanged(float value)
@ -140,6 +158,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Invertir dirección del motor B")]
[property: Name("Invertir B")]
bool invertirDireccionB;
partial void OnInvertirDireccionBChanged(bool value)
@ -159,8 +180,15 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Ancho de las secciones rectas")]
[property: Name("Ancho Recto")]
public float anchoRecto;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Ancho de la sección central")]
[property: Name("Ancho Central")]
public float anchoCentral;
@ -175,19 +203,45 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Información")]
[property: Description("Ancho total del transporte calculado")]
[property: Name("Ancho Total")]
public float anchoTransporte_oculto;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Coeficiente de fricción")]
[property: Name("Coeficiente Fricción")]
public float frictionCoefficient;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Velocidad máxima a 50Hz")]
[property: Name("Velocidad Max 50Hz")]
public float velMax50hz;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Tiempo de rampa")]
[property: Name("Tiempo Rampa")]
public float tiempoRampa;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Estado de marcha")]
[property: Name("En Marcha")]
public bool esMarcha;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Distancia entre elementos")]
[property: Name("Distancia")]
private float distance;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Alto de las guías")]
[property: Name("Alto Guía")]
private float altoGuia;
void ActualizarStoryboards(Rectangle transporte)

View File

@ -23,11 +23,13 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Transporte";
return "Transporte TTOP";
}
private string nombre = "Transporte TTOP";
private string nombre = NombreClase();
[property: Category("Id:")]
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -35,7 +37,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Simulation:")]
[property: Category("Simulación")]
[property: Description("Velocidad actual del transporte en m/s")]
[property: Name("Velocidad Actual")]
public float velocidadActual;
partial void OnVelocidadActualChanged(float value)
@ -44,7 +48,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Simulation:")]
[property: Category("Configuración")]
[property: Description("Invierte el sentido de movimiento del transporte")]
[property: Name("Invertir Dirección")]
bool invertirDireccion;
partial void OnInvertirDireccionChanged(bool value)
@ -67,13 +73,15 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Description("Bit to enable Link to Motor")]
[property: Category("PLC link:")]
[property: Description("Tag de bit para activar enlace con motor")]
[property: Category("Enlace PLC")]
[property: Name("Tag Activación Motor")]
string tag_ReleActivatedMotor;
[ObservableProperty]
[property: Description("Link to Motor")]
[property: Category("PLC link:")]
[property: Description("Seleccionar motor para enlazar")]
[property: Category("Enlace PLC")]
[property: Name("Motor Enlazado")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
string id_Motor;
@ -104,16 +112,27 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Category("Setup:")]
[property: Category("Configuración")]
[property: Description("Coeficiente de fricción entre objetos y superficie")]
[property: Name("Coeficiente de Fricción")]
public float frictionCoefficient;
[ObservableProperty]
[property: Category("Setup:")]
[property: Category("Configuración")]
[property: Description("Velocidad máxima a 50Hz")]
[property: Name("Velocidad Máxima 50Hz")]
public float velMax50hz;
[ObservableProperty]
[property: Category("Setup:")]
[property: Category("Configuración")]
[property: Description("Tiempo de rampa para acelerar/desacelerar")]
[property: Name("Tiempo de Rampa")]
public float tiempoRampa;
[ObservableProperty]
[property: Category("Setup:")]
[property: Category("Información")]
[property: Description("Indica si el transporte está en marcha")]
[property: Name("En Marcha")]
public bool esMarcha;

View File

@ -26,11 +26,13 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Transporte Dual Inverter";
return "Transporte TTOP Doble Inversor";
}
private string nombre = "Transporte TTOP Dual Inverter";
private string nombre = NombreClase();
[property: Category("Id:")]
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -38,7 +40,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Simulation:")]
[property: Category("Simulación")]
[property: Description("Velocidad actual del transporte")]
[property: Name("Velocidad Actual")]
public float velocidadActual;
partial void OnVelocidadActualChanged(float value)
@ -47,7 +51,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Simulation:")]
[property: Category("Configuración")]
[property: Description("Invierte el sentido de movimiento")]
[property: Name("Invertir Dirección")]
bool invertirDireccion;
partial void OnInvertirDireccionChanged(bool value)
@ -70,24 +76,28 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Description("Bit to enable Link to Inverter A")]
[property: Category("PLC link:")]
[property: Category("Enlace PLC")]
[property: Description("Tag para activar enlace con inversor A")]
[property: Name("Tag Activación Motor A")]
string tag_ReleActivatedMotor_A;
[ObservableProperty]
[property: Description("Bit to enable Link to Inverter B")]
[property: Category("PLC link:")]
[property: Category("Enlace PLC")]
[property: Description("Tag para activar enlace con inversor B")]
[property: Name("Tag Activación Motor B")]
string tag_ReleActivatedMotor_B;
[ObservableProperty]
[property: Description("Link to Inverter A")]
[property: Category("PLC link:")]
[property: Category("Enlace PLC")]
[property: Description("Enlace a inversor A")]
[property: Name("Motor A")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
string id_Motor_A;
[ObservableProperty]
[property: Description("Link to Inverter B")]
[property: Category("PLC link:")]
[property: Category("Enlace PLC")]
[property: Description("Enlace a inversor B")]
[property: Name("Motor B")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
string id_Motor_B;
@ -141,16 +151,27 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Category("Setup:")]
[property: Category("Configuración")]
[property: Description("Coeficiente de fricción")]
[property: Name("Coeficiente Fricción")]
public float frictionCoefficient;
[ObservableProperty]
[property: Category("Setup:")]
[property: Category("Configuración")]
[property: Description("Velocidad máxima a 50Hz")]
[property: Name("Velocidad Max 50Hz")]
public float velMax50hz;
[ObservableProperty]
[property: Category("Setup:")]
[property: Category("Configuración")]
[property: Description("Tiempo de rampa")]
[property: Name("Tiempo Rampa")]
public float tiempoRampa;
[ObservableProperty]
[property: Category("Setup:")]
[property: Category("Información")]
[property: Description("Estado de marcha")]
[property: Name("En Marcha")]
public bool esMarcha;

View File

@ -25,20 +25,30 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "VetroMeccanica Motor";
return "Motor VetroMeccanica";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
set => SetProperty(ref nombre, value);
}
[JsonIgnore]
[ObservableProperty]
[property: JsonIgnore]
[property: Category("Apariencia")]
[property: Description("Imagen visual del motor")]
[property: Name("Imagen")]
public ImageSource imageSource_oculta;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Tamaño visual del motor")]
[property: Name("Tamaño")]
public float tamano;
public override void OnResize(float Delta_Width, float Delta_Height)
@ -47,28 +57,45 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Tiempo de actualización en milisegundos")]
[property: Name("Tiempo de Actualización")]
public float refresh_Time_ms;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Velocidad proporcional en porcentaje")]
[property: Name("Velocidad Proporcional")]
public float proporcional_Speed;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Velocidad máxima para rampa")]
[property: Name("Velocidad Máxima Rampa")]
public float max_Speed_for_Ramp;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Contacto normalmente cerrado de trip del VFD")]
[property: Name("VFD Trip NC")]
bool vFD_Trip_NC;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Tiempo de rampa para acelerar/desacelerar")]
[property: Name("Tiempo de Rampa")]
public float tiempoRampa;
[ObservableProperty]
[property: Description("Enable read of the Motor encoder simulated on PLC.")]
[property: Category("Encoder:")]
[property: Description("Habilita lectura del encoder del motor simulado en PLC")]
[property: Category("Encoder")]
[property: Name("Motor con Encoder")]
bool motor_With_Encoder;
[ObservableProperty]
[property: Description("Actual Value of the encoder position.")]
[property: Category("Encoder:")]
[property: Description("Valor actual de la posición del encoder")]
[property: Category("Encoder")]
[property: Name("Posición Actual")]
public float actual_Position;
partial void OnTiempoRampaChanged(float value)
@ -79,8 +106,15 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Información")]
[property: Description("Estado de encendido del motor")]
[property: Name("Encendido")]
bool encendido;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Número del motor en el PLC")]
[property: Name("Número de Motor PLC")]
int pLC_NumeroMotor;
partial void OnPLC_NumeroMotorChanged(int value)
@ -92,16 +126,27 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Bloque de datos del motor en el PLC")]
[property: Name("DB del Motor")]
int pLC_DB_Motor;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Relación de transmisión")]
[property: Name("Ratio")]
public float ratio;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Velocidad actual del motor")]
[property: Name("Velocidad")]
public float velocidad;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Invierte el sentido de giro")]
[property: Name("Sentido Contrario")]
public bool sentido_contrario;

View File

@ -74,10 +74,13 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
public static string NombreClase()
{
return "Search Templates";
return "Buscador de Plantillas";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -85,7 +88,9 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
}
[ObservableProperty]
[property: Category("Tag Extraction:")]
[property: Category("Configuración")]
[property: Description("Ejecutar búsqueda de plantillas")]
[property: Name("Buscar Plantillas")]
bool search_templates;
partial void OnSearch_templatesChanged(bool oldValue, bool newValue)
@ -96,16 +101,22 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
}
[ObservableProperty]
[property: Category("Tag Extraction:")]
[property: Category("Configuración")]
[property: Description("Capturar imagen de referencia")]
[property: Name("Tomar Clip")]
bool tomarClip;
// En lugar de almacenar Mat directamente, guardaremos una representación serializable
[ObservableProperty]
[property: Category("Tag Extraction:")]
[property: Category("Información")]
[property: Description("Datos de región capturada")]
[property: Name("Datos Región")]
byte[] capturedRegionData;
[ObservableProperty]
[property: Category("Tag Extraction:")]
[property: Category("Información")]
[property: Description("Indica si la región fue capturada")]
[property: Name("Región Capturada")]
[property: ReadOnly(true)]
bool regionCapturada;
@ -115,19 +126,27 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
// Propiedades para almacenar las dimensiones de la captura
[ObservableProperty]
[property: Category("Tag Extraction:")]
[property: Category("Información")]
[property: Description("Ancho de región capturada")]
[property: Name("Ancho Capturado")]
int capturedWidth;
[ObservableProperty]
[property: Category("Tag Extraction:")]
[property: Category("Información")]
[property: Description("Alto de región capturada")]
[property: Name("Alto Capturado")]
int capturedHeight;
[ObservableProperty]
[property: Category("Tag Extraction:")]
[property: Category("Datos")]
[property: Description("Exportar datos OCR")]
[property: Name("Exportar OCR")]
bool export_ocr;
[ObservableProperty]
[property: Category("Tag Extraction:")]
[property: Category("Datos")]
[property: Description("Texto exportado OCR")]
[property: Name("Texto Export OCR")]
string text_export_ocr;

View File

@ -17,9 +17,13 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
{
public static string NombreClase()
{
return "Extraccion Tags";
return "Extractor de Tags";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -32,20 +36,28 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
}
[ObservableProperty]
[property: Category("Tag Extraction:")]
[property: Category("Configuración")]
[property: Description("Ejecutar extracción de tag")]
[property: Name("Extraer")]
bool extraer;
[ObservableProperty]
[property: Category("Tag Extraction:")]
[property: Category("Configuración")]
[property: Description("Eliminar saltos de línea del texto extraído")]
[property: Name("Eliminar Enter")]
bool eliminar_enters;
[ObservableProperty]
[property: Category("Tag Extraction:")]
[property: Category("Configuración")]
[property: Description("Idioma para reconocimiento OCR")]
[property: Name("Idioma OCR")]
[property: ItemsSource(typeof(IdiomasItemsSource<Idiomas>))]
string idioma_Extraccion;
[ObservableProperty]
[property: Category("Tag Extraction:")]
[property: Category("Configuración")]
[property: Description("Patrón de extracción de texto")]
[property: Name("Tipo de Patrón")]
[property: ItemsSource(typeof(TagPatternItemsSource<TagPattern>))]
string pattern_Type;
@ -97,8 +109,9 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
private osBuscarCoincidencias Search_Templates;
[ObservableProperty]
[property: Description("Link to Search Templates")]
[property: Category("Tag Extraction:")]
[property: Category("Configuración")]
[property: Description("Plantillas de búsqueda asociadas")]
[property: Name("Plantillas Búsqueda")]
[property: ItemsSource(typeof(osBaseItemsSource<osBuscarCoincidencias>))]
string id_Search_Templates;
@ -123,33 +136,46 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
}
[ObservableProperty]
[property: Category("Tag Extraction:")]
[property: Category("Datos")]
[property: Description("Texto extraído mediante OCR")]
[property: Name("Tag Extraído")]
string tag_extract;
[ObservableProperty]
[property: Category("Export:")]
[property: Category("Datos")]
[property: Description("Clase del objeto para exportación")]
[property: Name("Clase")]
string clase;
[ObservableProperty]
[property: Category("Export:")]
[property: Category("Datos")]
[property: Description("Nombre de la columna para exportación")]
[property: Name("Nombre Columna")]
string collumn_name;
[ObservableProperty]
[property: Description("Excel collumn.")]
[property: Category("Export:")]
[property: Category("Datos")]
[property: Description("Número de columna Excel")]
[property: Name("Número Columna")]
int collumn_number;
[ObservableProperty]
[property: Category("Tag Extraction:")]
[property: Category("Información")]
[property: Description("Número de copia del objeto")]
[property: Name("Número de Copia")]
[property: ReadOnly(true)]
int copy_Number;
[ObservableProperty]
[property: Category("Tag Extraction:")]
[property: Category("Configuración")]
[property: Description("Mostrar ventana de depuración OCR")]
[property: Name("Mostrar Debug")]
bool show_Debug_Window;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Opacidad del objeto")]
[property: Name("Opacidad")]
float opacity_oculto;
public osExtraccionTag()

View File

@ -1,11 +1,11 @@
using CommunityToolkit.Mvvm.ComponentModel;
using LibS7Adv;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using CtrEditor.FuncionesBase;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
{
@ -18,9 +18,13 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Boton";
return "Botón";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -28,19 +32,34 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Texto mostrado en el botón")]
[property: Name("Texto del Botón")]
string button_Name;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Tipo normalmente cerrado")]
[property: Name("Normalmente Cerrado")]
public bool tipo_NC;
[ObservableProperty]
[property: Hidden]
[property: Category("Apariencia")]
[property: Description("Color cuando está presionado")]
[property: Name("Color Presionado")]
Color color_Pressed;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color del texto del botón")]
[property: Name("Color del Texto")]
Color color_Titulo;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color principal del botón")]
[property: Name("Color")]
Color color;
partial void OnColorChanged(Color value)
@ -50,9 +69,15 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Hidden]
[property: Category("Apariencia")]
[property: Description("Color actual del botón")]
[property: Name("Color Actual")]
private Color colorButton;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Tamaño visual del botón")]
[property: Name("Tamaño")]
public float tamano;
public override void OnResize(float Delta_Width, float Delta_Height)
@ -61,6 +86,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Estado actual del botón")]
[property: Name("Estado")]
public bool estado;
partial void OnEstadoChanged(bool value)
@ -76,9 +104,15 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Dirección del tag en el PLC")]
[property: Name("Tag PLC")]
public string tag;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag para controlar luz indicadora")]
[property: Name("Tag Luz")]
public string tag_Luz;
public void ButtonDownCommand()
@ -114,7 +148,8 @@ namespace CtrEditor.ObjetosSim
else ColorButton = Color;
}
public override void UpdatePLCPrimerCiclo() {
public override void UpdatePLCPrimerCiclo()
{
// Escribimos el valor actual al iniciar la conexion
// Esto es util para NC principalmente

View File

@ -17,10 +17,14 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Encoder Motor";
return "Encoder de Motor";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -28,35 +32,46 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color visual del encoder")]
[property: Name("Color")]
private Brush color_oculto;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Velocidad actual del motor")]
[property: Name("Velocidad Actual")]
public float velocidadActual;
[ObservableProperty]
[property: Category("Encoder")]
[property: Description("Pulsos por vuelta del encoder")]
[property: Category("Encoder Config:")]
[property: Name("Pulsos por Vuelta")]
public float pulsos_Por_Vuelta;
[ObservableProperty]
[property: Category("Encoder")]
[property: Description("Ratio de giros por 50Hz")]
[property: Category("Encoder Config:")]
[property: Name("Ratio Giros 50Hz")]
public float ratio_Giros_50hz;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Valor actual del encoder")]
[property: Category("Encoder Status:")]
[property: Name("Valor Actual")]
public float valor_Actual;
[ObservableProperty]
[property: Description("Link to Motor")]
[property: Category("PLC link:")]
[property: Category("Enlace PLC")]
[property: Description("Motor enlazado al encoder")]
[property: Name("Motor Enlazado")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
string id_Motor;
[ObservableProperty]
[property: Description("Tag para escribir el valor del encoder")]
[property: Category("PLC link:")]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para valor del encoder")]
[property: Name("Tag Valor")]
string tag_Valor;
partial void OnId_MotorChanged(string value)

View File

@ -21,6 +21,10 @@ namespace CtrEditor.ObjetosSim
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -28,35 +32,46 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color visual del encoder")]
[property: Name("Color")]
private Brush color_oculto;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Velocidad actual del motor")]
[property: Name("Velocidad Actual")]
public float velocidadActual;
[ObservableProperty]
[property: Description("Pulsos por Hz por segundo : K")]
[property: Category("Encoder Config:")]
[property: Category("Encoder")]
[property: Description("Pulsos por Hz por segundo (K)")]
[property: Name("Pulsos por Hz")]
public float pulsos_Por_Hz;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Valor actual del encoder")]
[property: Category("Encoder Status:")]
[property: Name("Valor Actual")]
public float valor_Actual;
[ObservableProperty]
[property: Description("Link to Motor")]
[property: Category("PLC link:")]
[property: Category("Enlace PLC")]
[property: Description("Motor enlazado al encoder")]
[property: Name("Motor Enlazado")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
string id_Motor;
[ObservableProperty]
[property: Description("Tag para escribir el valor del encoder")]
[property: Category("PLC link:")]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para escribir valor del encoder")]
[property: Name("Tag Valor Escritura")]
string tag_Valor;
[ObservableProperty]
[property: Description("Tag para leer el valor del encoder. Este tag tiene prioridad sobre el Motor. Si se usa solo se lee el tag para actualizar la posicion.")]
[property: Category("PLC link:")]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para leer valor del encoder (tiene prioridad sobre motor)")]
[property: Name("Tag Valor Lectura")]
string tag_ReadValor;

View File

@ -24,10 +24,14 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Ruota Fonica";
return "Encoder de Engranaje";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -35,8 +39,15 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para señal de pulso")]
[property: Name("Tag PLC")]
public string tag;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Estado actual del pulso")]
[property: Name("Pulso")]
public bool pulso;
partial void OnPulsoChanged(bool value)
@ -56,8 +67,15 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color visual del encoder")]
[property: Name("Color")]
private Brush color_oculto;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Velocidad actual del encoder")]
[property: Name("Velocidad Actual")]
public float velocidadActual;
public override void AnguloChanged(float value)
@ -67,9 +85,15 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Información")]
[property: Description("Tiempo entre pulsos en ms")]
[property: Name("Tiempo de Pulso")]
public float tiempo_Pulso;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Pulsos generados por segundo")]
[property: Name("Pulsos por Segundo")]
public float pulsos_Por_Segundo;
partial void OnPulsos_Por_SegundoChanged(float value)
@ -78,6 +102,9 @@ namespace CtrEditor.ObjetosSim
Giros_segundo_a_100 = (float)((pulsos_Por_Segundo / Dientes) * 100 / VelocidadActual);
}
[ObservableProperty]
[property: Category("Encoder")]
[property: Description("Ejecutar homing del encoder")]
[property: Name("Homing")]
private bool homing;
partial void OnHomingChanged(bool value)
@ -87,14 +114,33 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Encoder")]
[property: Description("Número de dientes del encoder")]
[property: Name("Cantidad de Dientes")]
public float dientes;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Radio interno del encoder")]
[property: Name("Radio Interno")]
public float radio_Interno;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Radio externo del encoder")]
[property: Name("Radio Externo")]
public float radio_Externo;
[ObservableProperty]
[property: Category("Encoder")]
[property: Description("Ancho de los dientes (0-1)")]
[property: Name("Ancho de Dientes")]
public float ancho_Dientes;
[ObservableProperty]
[property: Category("Encoder")]
[property: Description("Giros por segundo al 100%")]
[property: Name("Giros/seg al 100%")]
public float giros_segundo_a_100;
public override void OnResize(float Delta_Width, float Delta_Height)
@ -104,8 +150,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Description("Link to Motor")]
[property: Category("PLC link:")]
[property: Category("Enlace PLC")]
[property: Description("Motor enlazado al encoder")]
[property: Name("Motor Enlazado")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
string id_Motor;

View File

@ -1,5 +1,4 @@

using CtrEditor.Simulacion;
using CtrEditor.Simulacion;
using LibS7Adv;
using System.Windows;
using System.Windows.Controls;
@ -25,9 +24,13 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Photocell";
return "Fotocélula";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -35,13 +38,15 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Description("Color")]
[property: Category("Layout:")]
[property: Description("Color del sensor")]
[property: Category("Apariencia")]
[property: Name("Color")]
Brush color;
[ObservableProperty]
[property: Description("Light cut")]
[property: Category("Debug:")]
[property: Description("Indica si la luz está cortada por un objeto")]
[property: Category("Información")]
[property: Name("Luz Cortada")]
bool luzCortada;
partial void OnLuzCortadaChanged(bool value)
@ -60,10 +65,12 @@ namespace CtrEditor.ObjetosSim
Frecuency = 0;
}
if (!value) {
if (!value)
{
Lenght_positive_pulse = (float)(timer.Elapsed.TotalMilliseconds - timer_lastPositive);
timer_lastNegative = timer.Elapsed.TotalMilliseconds;
} else
}
else
{
Lenght_negative_pulse = (float)(timer.Elapsed.TotalMilliseconds - timer_lastNegative);
timer_lastPositive = timer.Elapsed.TotalMilliseconds;
@ -74,18 +81,21 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Description("Size of the Light.")]
[property: Category("Setup:")]
[property: Description("Ancho del haz de luz del sensor")]
[property: Category("Configuración")]
[property: Name("Ancho del Haz")]
float ancho_Haz_De_Luz;
[ObservableProperty]
[property: Description("Distance to the neck.")]
[property: Category("Debug:")]
[property: Description("Distancia al cuello de la botella")]
[property: Category("Información")]
[property: Name("Distancia al Cuello")]
float distancia_cuello;
[ObservableProperty]
[property: Description("Type of detection: Neck of the bottle or Complete bottle.")]
[property: Category("Setup:")]
[property: Description("Tipo de detección: cuello de botella o botella completa")]
[property: Category("Configuración")]
[property: Name("Detectar Cuello")]
bool detectarCuello;
partial void OnDetectarCuelloChanged(bool value)
@ -97,8 +107,9 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Description("Filter signal.")]
[property: Category("Setup:")]
[property: Description("Filtro de frecuencia para la señal")]
[property: Category("Configuración")]
[property: Name("Filtro de Frecuencia")]
float filter_Frecuency;
partial void OnFilter_FrecuencyChanged(float value)
@ -108,24 +119,33 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Debug:")]
[property: Category("Información")]
[property: Description("Frecuencia calculada")]
[property: Name("Frecuencia")]
float frecuency;
[ObservableProperty]
[property: Category("Debug:")]
[property: Category("Información")]
[property: Description("Duración del pulso positivo")]
[property: Name("Duración Pulso Positivo")]
float lenght_positive_pulse;
[ObservableProperty]
[property: Category("Debug:")]
[property: Category("Información")]
[property: Description("Duración del pulso negativo")]
[property: Name("Duración Pulso Negativo")]
float lenght_negative_pulse;
[ObservableProperty]
[property: Category("Debug:")]
[property: Category("Información")]
[property: Description("Tiempo de flanco positivo a flanco positivo")]
[property: Name("Tiempo FP a FP")]
float lenght_FP_to_FP;
[ObservableProperty]
[property: Description("Type Filter signal.")]
[property: Category("Setup:")]
[property: Description("Tipo de contacto: Normalmente Cerrado")]
[property: Category("Configuración")]
[property: Name("Tipo NC")]
public bool tipo_NC;
partial void OnTipo_NCChanged(bool value)
@ -134,6 +154,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag de salida de la fotocélula")]
[property: Name("Tag de Salida")]
public string tagPhotocell_OUT;
@ -199,7 +222,8 @@ namespace CtrEditor.ObjetosSim
OnLuzCortadaChanged(LuzCortada);
}
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds) {
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{
}
public override void ucLoaded()
{

View File

@ -17,9 +17,13 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Temperatura";
return "Sensor de Temperatura";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -27,13 +31,27 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para valor de temperatura")]
[property: Name("Tag PLC")]
public string tag;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Valor mínimo escalado")]
[property: Name("Mínimo Escalado")]
public float min_OUT_Scaled;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Valor máximo escalado")]
[property: Name("Máximo Escalado")]
public float max_OUT_Scaled;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Valor actual de temperatura")]
[property: Name("Temperatura")]
public float value;
partial void OnValueChanged(float value)

View File

@ -1,3 +1,4 @@
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
@ -12,9 +13,26 @@ namespace CtrEditor.ObjetosSim
/// <summary>
/// Atributo para marcar propiedades que deben usar el editor de etiquetas
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class TagEditorAttribute : Attribute
{
public TagEditorAttribute() { }
public Type? EditorType { get; }
public TagEditorAttribute(Type? editorType = null)
{
EditorType = editorType;
}
}
[AttributeUsage(AttributeTargets.Property)]
public class NameAttribute : Attribute
{
public string DisplayName { get; }
public NameAttribute(string displayName)
{
DisplayName = displayName ?? throw new ArgumentNullException(nameof(displayName));
}
}
/// <summary>

View File

@ -1,11 +1,11 @@

using LibS7Adv;
using LibS7Adv;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using CommunityToolkit.Mvvm.ComponentModel;
using Newtonsoft.Json.Linq;
using CtrEditor.FuncionesBase;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
{
@ -21,9 +21,13 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Analog Tag";
return "Tag Analógico";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -31,6 +35,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Tamaño visual del tag")]
[property: Name("Tamaño")]
public float tamano;
public override void OnResize(float Delta_Width, float Delta_Height)
@ -40,23 +47,49 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(Value))]
[property: Category("Enlace PLC")]
[property: Description("Dirección del tag en el PLC")]
[property: Name("Tag")]
public string tag;
[ObservableProperty]
[property: Category("Identificación")]
[property: Description("Descripción del tag")]
[property: Name("Descripción")]
public string descripcion;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(Value))]
[property: Category("Configuración")]
[property: Description("Valor mínimo de entrada escalado")]
[property: Name("Mínimo Entrada")]
public float min_IN_Scaled;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(Value))]
[property: Category("Configuración")]
[property: Description("Valor máximo de entrada escalado")]
[property: Name("Máximo Entrada")]
public float max_IN_Scaled;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(Value))]
[property: Category("Configuración")]
[property: Description("Valor mínimo de salida escalado")]
[property: Name("Mínimo Salida")]
public float min_OUT_Scaled;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(Value))]
[property: Category("Configuración")]
[property: Description("Valor máximo de salida escalado")]
[property: Name("Máximo Salida")]
public float max_OUT_Scaled;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Valor actual del tag")]
[property: Name("Valor")]
public float value;
partial void OnValueChanged(float value)

View File

@ -27,7 +27,7 @@
Width="16" Height="25" VerticalAlignment="Center" HorizontalAlignment="Center"
Background="{Binding Color, Converter={StaticResource ColorToBrushConverter}}" />
<Label Content="{Binding Descripcion}" Grid.Column="1" VerticalAlignment="Center"
Background="{Binding Color}"
Background="{Binding Color, Converter={StaticResource ColorToBrushConverter}}"
Visibility="{Binding Show_Description, Converter={StaticResource BooleanToVisibilityConverter}}" />
<CheckBox Grid.Column="2" VerticalAlignment="Center" IsChecked="{Binding Estado}"
Background="{Binding Color_oculto}" />

View File

@ -6,6 +6,7 @@ using System.Windows.Media;
using CommunityToolkit.Mvvm.ComponentModel;
using Newtonsoft.Json.Linq;
using CtrEditor.FuncionesBase;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
{
@ -21,9 +22,13 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Bool Tag";
return "Tag Digital";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -31,15 +36,27 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color de fondo cuando está activo")]
[property: Name("Color de Fondo")]
private Brush color_oculto;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color del tag")]
[property: Name("Color")]
Color color;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Estado actual del tag")]
[property: Name("Estado")]
public bool estado;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Mostrar descripción en el objeto")]
[property: Name("Mostrar Descripción")]
public bool show_Description;
partial void OnEstadoChanged(bool value)
@ -52,6 +69,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Tamaño visual del tag")]
[property: Name("Tamaño")]
public float tamano;
public override void OnResize(float Delta_Width, float Delta_Height)
@ -60,10 +80,16 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Dirección del tag en el PLC")]
[property: Name("Tag PLC")]
[NotifyPropertyChangedFor(nameof(Estado))]
public string tag;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Descripción del tag")]
[property: Name("Descripción")]
public string descripcion;
public osBoolTag()

View File

@ -2,6 +2,7 @@
using System.Windows;
using System.Windows.Controls;
using CtrEditor.FuncionesBase;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
@ -15,15 +16,22 @@ namespace CtrEditor.ObjetosSim
public TagsConsensos Consensos = new TagsConsensos();
[ObservableProperty]
[property: Category("Datos")]
[property: Description("Lista de tags para consenso")]
[property: Name("Tags")]
public List<string> tags;
// Otros datos y métodos relevantes para la simulación
public static string NombreClase()
{
return "Consensi";
return "Consenso Genérico";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -31,6 +39,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Tamaño del consenso")]
[property: Name("Tamaño")]
public float tamano;
public override void OnResize(float Delta_Width, float Delta_Height)

View File

@ -7,6 +7,7 @@ using System.Windows.Shapes;
using LibS7Adv;
using System.Runtime.Intrinsics;
using CtrEditor.FuncionesBase;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
{
@ -23,9 +24,13 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Trace3";
return "Trazador de 3 Señales";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -33,31 +38,75 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color de la serie 1")]
[property: Name("Color Serie 1")]
private Brush color_Serie_1;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color de la serie 2")]
[property: Name("Color Serie 2")]
private Brush color_Serie_2;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color de la serie 3")]
[property: Name("Color Serie 3")]
private Brush color_Serie_3;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Alto del trazador")]
[property: Name("Alto")]
float alto;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Ancho del trazador")]
[property: Name("Ancho")]
float ancho;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Serie 1 es tipo booleana")]
[property: Name("Serie 1 Bool")]
bool serie1_Tipo_Bool;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para serie 1")]
[property: Name("Tag Serie 1")]
string tag_Serie1;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Serie 2 es tipo booleana")]
[property: Name("Serie 2 Bool")]
bool serie2_Tipo_Bool;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para serie 2")]
[property: Name("Tag Serie 2")]
string tag_Serie2;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Serie 3 es tipo booleana")]
[property: Name("Serie 3 Bool")]
bool serie3_Tipo_Bool;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para serie 3")]
[property: Name("Tag Serie 3")]
string tag_Serie3;
[ObservableProperty]
[property: Category("Identificación")]
[property: Description("Título del trazador")]
[property: Name("Título")]
string titulo;
[ObservableProperty]
@ -89,6 +138,9 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Máximo número de elementos a mostrar")]
[property: Name("Max Elementos")]
float max_Cantidad_Elementos;
public osTrace3()
@ -279,7 +331,8 @@ namespace CtrEditor.ObjetosSim
{
Datos?.ucUnLoaded();
}
public void Resize(float width, float height) {
public void Resize(float width, float height)
{
if (Datos is osTrace3 datos)
{
datos.Ancho += PixelToMeter.Instance.calc.PixelsToMeters(width);
@ -294,7 +347,8 @@ namespace CtrEditor.ObjetosSim
Datos.Top = PixelToMeter.Instance.calc.PixelsToMeters(TopPixels);
}
}
public float Angle() { return 0; } public void Rotate(float Angle) { }
public float Angle() { return 0; }
public void Rotate(float Angle) { }
public void Highlight(bool State) { }
public ZIndexEnum ZIndex_Base()
{

View File

@ -11,6 +11,7 @@ using LiveChartsCore.SkiaSharpView;
using LiveChartsCore.Defaults;
using System.Diagnostics;
using CtrEditor.FuncionesBase;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
{
@ -28,9 +29,13 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Trace";
return "Trazador Simple";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -38,18 +43,33 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Alto del trazador")]
[property: Name("Alto")]
float alto;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Ancho del trazador")]
[property: Name("Ancho")]
float ancho;
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para la serie de datos")]
[property: Name("Tag Serie")]
string tag_serie;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Nombre del eje X")]
[property: Name("Nombre Eje X")]
string x_Series_Name;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Nombre del eje Y")]
[property: Name("Nombre Eje Y")]
string y_Series_Name;
private readonly ObservableCollection<ObservableValue> _observableValues;
@ -90,7 +110,8 @@ namespace CtrEditor.ObjetosSim
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{
if (Tag_serie != null && Tag_serie.Length > 0) {
if (Tag_serie != null && Tag_serie.Length > 0)
{
var value = LeerBitTag(Tag_serie) == false ? 0 : 1;
data.Add(value);
}
@ -144,7 +165,8 @@ namespace CtrEditor.ObjetosSim
{
Datos?.ucUnLoaded();
}
public void Resize(float width, float height) {
public void Resize(float width, float height)
{
if (Datos is osTraceSimple datos)
{
datos.Ancho += PixelToMeter.Instance.calc.PixelsToMeters(width);
@ -159,7 +181,8 @@ namespace CtrEditor.ObjetosSim
Datos.Top = PixelToMeter.Instance.calc.PixelsToMeters(TopPixels);
}
}
public float Angle() { return 0; } public void Rotate(float Angle) { }
public float Angle() { return 0; }
public void Rotate(float Angle) { }
public void Highlight(bool State) { }
public ZIndexEnum ZIndex_Base()
{

View File

@ -190,12 +190,26 @@ namespace CtrEditor.ObjetosSim
continue;
var displayNameAttr = property.Attributes.OfType<DisplayNameAttribute>().FirstOrDefault();
var customNameAttr = property.Attributes.OfType<NameAttribute>().FirstOrDefault();
string displayName;
if (customNameAttr != null)
{
displayName = customNameAttr.DisplayName;
}
else if (displayNameAttr != null)
{
displayName = displayNameAttr.DisplayName;
}
else
{
displayName = property.Name.Replace("_", " ");
}
var propertyDefinition = new PropertyDefinition
{
TargetProperties = new[] { property.Name },
DisplayName = displayNameAttr != null
? displayNameAttr.DisplayName
: property.Name.Replace("_", " ")
DisplayName = displayName
};
// Aquí se añaden todas las propiedades; para "ImagePath" no se requiere

View File

@ -5,8 +5,24 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:CtrEditor.ObjetosSim.UserControls"
mc:Ignorable="d" Name="circularSegmentControl">
<Canvas>
<Path Name="path" Stroke="Black" Fill="LightBlue" StrokeThickness="1">
<Canvas Name="mainCanvas">
<Path Name="path" Stroke="Black" StrokeThickness="1">
<Path.Fill>
<VisualBrush TileMode="Tile" Viewport="0,0,20,20" ViewportUnits="Absolute">
<VisualBrush.Transform>
<TransformGroup>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</VisualBrush.Transform>
<VisualBrush.Visual>
<Canvas Width="20" Height="20">
<!-- Patrón de rayas radiales que simulan el movimiento tangencial -->
<Rectangle Fill="LightGray" Width="10" Height="10" Canvas.Left="0" Canvas.Top="0"/>
<Rectangle Fill="GhostWhite" Width="10" Height="10" Canvas.Left="0" Canvas.Top="10"/>
</Canvas>
</VisualBrush.Visual>
</VisualBrush>
</Path.Fill>
<Path.RenderTransform>
<RotateTransform Angle="{Binding Angle, ElementName=circularSegmentControl}"/>
</Path.RenderTransform>

View File

@ -1,6 +1,7 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
namespace CtrEditor.ObjetosSim.UserControls
{
@ -54,21 +55,95 @@ namespace CtrEditor.ObjetosSim.UserControls
public static readonly DependencyProperty EndAngleProperty =
DependencyProperty.Register("EndAngle", typeof(double), typeof(CircularSegment), new PropertyMetadata(90.0, OnPropertyChanged));
// Nuevas propiedades para las guías
public bool ShowGuides
{
get { return (bool)GetValue(ShowGuidesProperty); }
set { SetValue(ShowGuidesProperty, value); }
}
public static readonly DependencyProperty ShowGuidesProperty =
DependencyProperty.Register("ShowGuides", typeof(bool), typeof(CircularSegment), new PropertyMetadata(false, OnPropertyChanged));
public double GuideDistance
{
get { return (double)GetValue(GuideDistanceProperty); }
set { SetValue(GuideDistanceProperty, value); }
}
public static readonly DependencyProperty GuideDistanceProperty =
DependencyProperty.Register("GuideDistance", typeof(double), typeof(CircularSegment), new PropertyMetadata(5.0, OnPropertyChanged));
public double GuideThickness
{
get { return (double)GetValue(GuideThicknessProperty); }
set { SetValue(GuideThicknessProperty, value); }
}
public static readonly DependencyProperty GuideThicknessProperty =
DependencyProperty.Register("GuideThickness", typeof(double), typeof(CircularSegment), new PropertyMetadata(2.0, OnPropertyChanged));
public static readonly DependencyProperty GuideStrokeProperty =
DependencyProperty.Register("GuideStroke", typeof(Brush), typeof(CircularSegment), new PropertyMetadata(new SolidColorBrush(Colors.DarkBlue), OnGuidePropertyChanged));
public Brush GuideStroke
{
get { return (Brush)GetValue(GuideStrokeProperty); }
set { SetValue(GuideStrokeProperty, value); }
}
public CircularSegment()
{
InitializeComponent();
this.Loaded += CircularSegment_Loaded;
}
private void CircularSegment_Loaded(object sender, RoutedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("CircularSegment_Loaded called");
DrawSegment();
}
// Propiedad pública para acceder al Path desde código externo
public System.Windows.Shapes.Path TransportePath => path;
private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as CircularSegment)?.DrawSegment();
}
private static void OnGuidePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as CircularSegment)?.DrawSegment();
}
private void DrawSegment()
{
System.Diagnostics.Debug.WriteLine($"DrawSegment called - ShowGuides: {ShowGuides}");
if (OuterRadius <= 0 || InnerRadius <= 0 || StartAngle == EndAngle)
return;
// Limpiar canvas existente - mantener solo el path principal
for (int i = mainCanvas.Children.Count - 1; i >= 0; i--)
{
if (mainCanvas.Children[i] != path)
{
mainCanvas.Children.RemoveAt(i);
}
}
DrawMainSegment();
if (ShowGuides)
{
System.Diagnostics.Debug.WriteLine("About to call DrawGuides()");
DrawGuides();
}
}
private void DrawMainSegment()
{
PathGeometry geometry = new PathGeometry();
PathFigure figure = new PathFigure();
@ -100,5 +175,76 @@ namespace CtrEditor.ObjetosSim.UserControls
geometry.Figures.Add(figure);
path.Data = geometry;
}
private void DrawGuides()
{
Point center = new Point(OuterRadius, OuterRadius);
// Calcular radios de las guías
double outerGuideRadius = OuterRadius + GuideDistance;
double innerGuideRadius = InnerRadius - GuideDistance;
System.Diagnostics.Debug.WriteLine($"DrawGuides - Creating guides with radii: Outer={outerGuideRadius}, Inner={innerGuideRadius}");
// Asegurar que el radio interior no sea negativo
if (innerGuideRadius < 1.0)
innerGuideRadius = 1.0;
// Crear guía exterior
CreateGuideArc(center, outerGuideRadius, "OuterGuide");
// Crear guía interior solo si el radio es válido
if (innerGuideRadius > 1.0)
{
CreateGuideArc(center, innerGuideRadius, "InnerGuide");
}
}
private void CreateGuideArc(Point center, double radius, string name)
{
var guidePath = new System.Windows.Shapes.Path
{
Name = name,
Stroke = GuideStroke,
StrokeThickness = GuideThickness,
Fill = null
};
// Crear geometría del arco
double radiansStart = StartAngle * Math.PI / 180.0;
double radiansEnd = EndAngle * Math.PI / 180.0;
Point startPoint = new Point(
center.X + radius * Math.Cos(radiansStart),
center.Y + radius * Math.Sin(radiansStart)
);
Point endPoint = new Point(
center.X + radius * Math.Cos(radiansEnd),
center.Y + radius * Math.Sin(radiansEnd)
);
// Crear el arco usando ArcSegment
var pathGeometry = new PathGeometry();
var pathFigure = new PathFigure
{
StartPoint = startPoint
};
var arcSegment = new ArcSegment
{
Point = endPoint,
Size = new Size(radius, radius),
SweepDirection = SweepDirection.Clockwise,
IsLargeArc = Math.Abs(EndAngle - StartAngle) > 180
};
pathFigure.Segments.Add(arcSegment);
pathGeometry.Figures.Add(pathFigure);
guidePath.Data = pathGeometry;
System.Diagnostics.Debug.WriteLine($"Adding guide {name} to canvas");
mainCanvas.Children.Add(guidePath);
}
}
}

View File

@ -71,8 +71,8 @@ namespace CtrEditor.ObjetosSim
[JsonIgnore]
private System.Threading.Timer timer = null;
[JsonIgnore]
[ObservableProperty]
[property: JsonIgnore]
[property: Hidden]
public bool isVisFilter;
@ -80,13 +80,15 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Description("Lock object to mouse movement.")]
[property: Category("Layout:")]
[property: Category("Configuración")]
[property: Description("Bloquear movimiento del objeto")]
[property: Name("Bloquear Movimiento")]
private bool lock_movement;
[ObservableProperty]
[property: Description("X coordinate.")]
[property: Category("Layout:")]
[property: Category("Configuración")]
[property: Description("Coordenada X del objeto")]
[property: Name("Izquierda")]
private float left;
public void CheckData()
@ -114,8 +116,9 @@ namespace CtrEditor.ObjetosSim
public virtual void LeftChanging(float oldValue, float newValue) { }
[ObservableProperty]
[property: Description("Y coordinate.")]
[property: Category("Layout:")]
[property: Category("Configuración")]
[property: Description("Coordenada Y del objeto")]
[property: Name("Superior")]
private float top;
partial void OnTopChanged(float value)
@ -137,8 +140,9 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Description("Widht.")]
[property: Category("Layout:")]
[property: Category("Configuración")]
[property: Description("Ancho del objeto")]
[property: Name("Ancho")]
private float ancho;
partial void OnAnchoChanged(float value)
@ -148,8 +152,9 @@ namespace CtrEditor.ObjetosSim
public virtual void AnchoChanged(float value) { }
[ObservableProperty]
[property: Description("Height.")]
[property: Category("Layout:")]
[property: Category("Configuración")]
[property: Description("Alto del objeto")]
[property: Name("Alto")]
private float alto;
partial void OnAltoChanged(float value)
@ -160,8 +165,9 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Description("Angle.")]
[property: Category("Layout:")]
[property: Category("Configuración")]
[property: Description("Ángulo de rotación del objeto")]
[property: Name("Ángulo")]
private float angulo;
partial void OnAnguloChanged(float value)
@ -177,8 +183,9 @@ namespace CtrEditor.ObjetosSim
public virtual void AnguloChanging(float oldValue, float newValue) { }
[ObservableProperty]
[property: Category("Identificación")]
[property: Description("Etiquetas para clasificar el objeto. Use # antes de cada etiqueta (ej: #motor #bomba #critico)")]
[property: Category("General:")]
[property: Name("Etiquetas")]
[property: Editor(typeof(TagPropertyEditor), typeof(TagPropertyEditor))]
[property: TagEditor]
private string etiquetas = "";
@ -290,8 +297,9 @@ namespace CtrEditor.ObjetosSim
// Group as FacePlate
[ObservableProperty]
[property: Description("This is a link to a faceplate. It works like an anchor.")]
[property: Category("Group:")]
[property: Category("Agrupación")]
[property: Description("Enlace a una placa de texto como ancla")]
[property: Name("Panel Grupo")]
[property: ItemsSource(typeof(osBaseItemsSource<osTextPlate>))]
private string group_Panel;
@ -333,8 +341,9 @@ namespace CtrEditor.ObjetosSim
// Group as FacePlate
[ObservableProperty]
[property: Description("This is a link to a FromPlate that moves automatically. It works like an anchor.")]
[property: Category("Group:")]
[property: Category("Agrupación")]
[property: Description("Enlace a un marco que se mueve automáticamente como ancla")]
[property: Name("Panel Marco")]
[property: ItemsSource(typeof(osBaseItemsSource<osFramePlate>))]
private string group_FramePanel;
@ -344,28 +353,28 @@ namespace CtrEditor.ObjetosSim
private bool isUpdatingFromFramePlate = false;
// Variables para rotación orbital alrededor del FramePlate
[JsonIgnore]
[ObservableProperty]
[property: JsonIgnore]
[property: Hidden]
private float framePlate_RelativeX;
[JsonIgnore]
[ObservableProperty]
[property: JsonIgnore]
[property: Hidden]
private float framePlate_RelativeY;
[JsonIgnore]
[ObservableProperty]
[property: JsonIgnore]
[property: Hidden]
private float framePlate_InitialAngle;
[JsonIgnore]
[ObservableProperty]
[property: JsonIgnore]
[property: Hidden]
private float framePlate_PivotX;
[JsonIgnore]
[ObservableProperty]
[property: JsonIgnore]
[property: Hidden]
private float framePlate_PivotY;
@ -754,8 +763,9 @@ namespace CtrEditor.ObjetosSim
// All Pages Objects
[NotifyPropertyChangedFor(nameof(Show_On_This_Page))]
[ObservableProperty]
[property: Description("Enable this object to be used in all pages.")]
[property: Category("Layout:")]
[property: Category("Configuración")]
[property: Description("Habilitar este objeto para ser usado en todas las páginas")]
[property: Name("Habilitado en Todas Páginas")]
private bool enable_On_All_Pages;
@ -779,8 +789,9 @@ namespace CtrEditor.ObjetosSim
// Local Data for Global Objects
[NotifyPropertyChangedFor(nameof(Show_On_This_Page))]
[ObservableProperty]
[property: Description("Enable local data of this global Object on all pages.")]
[property: Category("Layout:")]
[property: Category("Configuración")]
[property: Description("Habilitar datos locales de este objeto global en todas las páginas")]
[property: Name("Datos Locales para Todas")]
private bool enable_Local_Data_for_All;
partial void OnEnable_Local_Data_for_AllChanged(bool value)
@ -795,8 +806,9 @@ namespace CtrEditor.ObjetosSim
// Local Data for Global Objects
[NotifyPropertyChangedFor(nameof(Show_On_This_Page))]
[ObservableProperty]
[property: Description("Enable local data of this global Object on this page.")]
[property: Category("Layout:")]
[property: Category("Configuración")]
[property: Description("Habilitar datos locales de este objeto global en esta página")]
[property: Name("Datos Locales")]
[property: JsonIgnore]
private bool enable_Local_Data;
@ -910,7 +922,9 @@ namespace CtrEditor.ObjetosSim
private List<string> showOnThisPagesList;
private bool show_On_This_Page;
[property: Category("Layout:")]
[property: Category("Información")]
[property: Description("Mostrar en esta página")]
[property: Name("Mostrar en Esta Página")]
public bool Show_On_This_Page
{
get
@ -958,13 +972,15 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Description("Autocreated and cloned with Search Templates")]
[property: Category("Tag Extraction:")]
[property: Category("Datos")]
[property: Description("Creado automáticamente y clonado con plantillas de búsqueda")]
[property: Name("Clonado")]
bool cloned;
[ObservableProperty]
[property: Description("Autocreated and cloned with Search Templates")]
[property: Category("Tag Extraction:")]
[property: Category("Datos")]
[property: Description("ID del objeto del cual fue clonado")]
[property: Name("Clonado Desde")]
[property: Hidden]
UniqueId cloned_from;
@ -1153,6 +1169,27 @@ namespace CtrEditor.ObjetosSim
return storyboard;
}
protected Storyboard CrearAnimacionMultiStoryBoardTrasnporteCircular(System.Windows.Shapes.Path transporte, bool invertirDireccion)
{
if (_visualRepresentation == null) return null;
if (transporte == null) return null;
Storyboard storyboard = new Storyboard();
var animation = new DoubleAnimation
{
From = invertirDireccion ? 20 : 0,
To = invertirDireccion ? 0 : 20, // Total Pixels Brush
Duration = TimeSpan.FromSeconds(PixelToMeter.Instance.calc.PixelsToMeters(20) * 60),
RepeatBehavior = RepeatBehavior.Forever
};
Storyboard.SetTarget(animation, transporte);
Storyboard.SetTargetProperty(animation, new PropertyPath("(Path.Fill).(VisualBrush.Transform).(TransformGroup.Children)[0].(TranslateTransform.Y)"));
storyboard.Children.Add(animation);
storyboard.Begin();
storyboard.SetSpeedRatio(0);
return storyboard;
}
protected Storyboard CrearAnimacionMultiStoryBoardTrasnporte(Storyboard storyboard, Rectangle transporte, bool invertirDireccion)
{
// Detener y eliminar el storyboard existente si hay uno
@ -1165,6 +1202,18 @@ namespace CtrEditor.ObjetosSim
return CrearAnimacionMultiStoryBoardTrasnporte(transporte, invertirDireccion);
}
protected Storyboard CrearAnimacionMultiStoryBoardTrasnporteCircular(Storyboard storyboard, System.Windows.Shapes.Path transporte, bool invertirDireccion)
{
// Detener y eliminar el storyboard existente si hay uno
if (storyboard != null)
{
storyboard.Stop();
storyboard.Children.Clear();
}
return CrearAnimacionMultiStoryBoardTrasnporteCircular(transporte, invertirDireccion);
}
protected void ActualizarAnimacionMultiStoryBoardTransporte(Storyboard storyboard, float velocidadActual)
{
if (_visualRepresentation == null) return;
@ -1181,6 +1230,14 @@ namespace CtrEditor.ObjetosSim
_storyboard = CrearAnimacionMultiStoryBoardTrasnporte(_storyboard, transporte, invertirDireccion);
}
protected void CrearAnimacionStoryBoardTrasnporteCircular(System.Windows.Shapes.Path transporte, bool invertirDireccion, float angulo)
{
if (angulo > 45 && angulo < 225)
_storyboard = CrearAnimacionMultiStoryBoardTrasnporteCircular(_storyboard, transporte, !invertirDireccion);
else
_storyboard = CrearAnimacionMultiStoryBoardTrasnporteCircular(_storyboard, transporte, invertirDireccion);
}
protected void ActualizarAnimacionStoryBoardTransporte(float velocidadActual)
{
ActualizarAnimacionMultiStoryBoardTransporte(_storyboard, velocidadActual);
@ -1601,7 +1658,31 @@ namespace CtrEditor.ObjetosSim
{
if (value is string stringValue)
{
return new BitmapImage(new Uri(stringValue, UriKind.RelativeOrAbsolute));
try
{
var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.UriSource = new Uri(stringValue, UriKind.RelativeOrAbsolute);
bitmapImage.EndInit();
return bitmapImage;
}
catch
{
// Si falla la carga de la imagen, usar imagen por defecto como fallback
try
{
var defaultImage = new BitmapImage();
defaultImage.BeginInit();
defaultImage.UriSource = new Uri("/Icons/unselect.png", UriKind.RelativeOrAbsolute);
defaultImage.EndInit();
return defaultImage;
}
catch
{
// Si incluso la imagen por defecto falla, devolver null
return null;
}
}
}
return null;
}

View File

@ -23,40 +23,47 @@ namespace CtrEditor.ObjetosSim
// Tamaño del área de simulación
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Ancho del área de simulación en metros")]
[property: Category("Simulación:")]
[property: Name("Ancho Simulación")]
private float anchoSimulacion = 10.0f;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Alto del área de simulación en metros")]
[property: Category("Simulación:")]
[property: Name("Alto Simulación")]
private float altoSimulacion = 10.0f;
// Propiedades del fluido
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Tamaño visual de las partículas")]
[property: Category("Visual:")]
[property: Name("Tamaño Partícula")]
private float tamañoParticula = 0.01f;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color del fluido")]
[property: Category("Visual:")]
[property: Name("Color Fluido")]
private Color colorFluido = Colors.CornflowerBlue;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Opacidad de las partículas")]
[property: Category("Visual:")]
[property: Name("Opacidad Partículas")]
private double opacidadParticulas = 0.7;
// Propiedades de gravedad
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Gravedad en X (m/s²)")]
[property: Category("Física:")]
[property: Name("Gravedad X")]
private float gravedadX = 0.0f;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Gravedad en Y (m/s²)")]
[property: Category("Física:")]
[property: Name("Gravedad Y")]
private float gravedadY = 9.8f;
partial void OnGravedadXChanged(float value)
@ -71,13 +78,15 @@ namespace CtrEditor.ObjetosSim
// Estadísticas de la simulación
[ObservableProperty]
[property: Category("Información")]
[property: Description("Número de partículas")]
[property: Category("Estadísticas:")]
[property: Name("Número Partículas")]
private int numeroParticulas;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Rendimiento en FPS")]
[property: Category("Estadísticas:")]
[property: Name("FPS")]
private double fps;
// Referencia a componentes (solo para la función Add)
@ -86,10 +95,14 @@ namespace CtrEditor.ObjetosSim
// Nombre de la clase para identificación
public static string NombreClase()
{
return "SistemaFluidos";
return "Sistema de Fluidos";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;

View File

@ -7,6 +7,7 @@ using CommunityToolkit.Mvvm.ComponentModel;
using LibS7Adv;
using CtrEditor.Simulacion;
using System.Windows.Input;
using System.ComponentModel;
namespace CtrEditor.ObjetosSim
@ -24,9 +25,13 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase()
{
return "Example";
return "Ejemplo Básico";
}
private string nombre = "Transporte TTOP";
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;
@ -34,6 +39,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Velocidad actual del transporte")]
[property: Name("Velocidad Actual")]
public float velocidadActual;
partial void OnVelocidadActualChanged(float value)
@ -42,6 +50,9 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Invierte el sentido de movimiento")]
[property: Name("Invertir Dirección")]
bool invertirDireccion;
partial void OnInvertirDireccionChanged(bool value)
@ -65,6 +76,9 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty]
[property: Category("Enlace PLC")]
[property: Description("Motor enlazado al transporte")]
[property: Name("Motor")]
public string motor;
partial void OnMotorChanged(string value)
@ -73,18 +87,45 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Ancho del transporte")]
[property: Name("Ancho")]
public float ancho;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Alto del transporte")]
[property: Name("Alto")]
public float alto;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Ángulo de rotación")]
[property: Name("Ángulo")]
public float angulo;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Coeficiente de fricción")]
[property: Name("Coeficiente Fricción")]
public float frictionCoefficient;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Velocidad máxima a 50Hz")]
[property: Name("Velocidad Max 50Hz")]
public float velMax50hz;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Tiempo de rampa")]
[property: Name("Tiempo Rampa")]
public float tiempoRampa;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Estado de marcha")]
[property: Name("En Marcha")]
public bool esMarcha;

View File

@ -57,8 +57,9 @@ namespace CtrEditor.ObjetosSim
// Propiedades visuales
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Diámetro de la tubería en metros")]
[property: Category("Dimensiones:")]
[property: Name("Diámetro")]
private float diametro = 0.05f;
partial void OnDiametroChanged(float value)
@ -72,28 +73,33 @@ namespace CtrEditor.ObjetosSim
}
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Diámetro interno para visualización del fluido")]
[property: Category("Visual:")]
[property: Name("Diámetro Interno")]
private float diametroInterno;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color de la tubería")]
[property: Category("Visual:")]
[property: Name("Color Tubería")]
private System.Windows.Media.Color color = System.Windows.Media.Colors.Gray;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color del fluido")]
[property: Category("Visual:")]
[property: Name("Color Fluido")]
private System.Windows.Media.Color colorFluido = System.Windows.Media.Colors.CornflowerBlue;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Datos del path para dibujar la tubería")]
[property: Category("Interno:")]
[property: Name("Path Data")]
private string pathData;
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Densidad del fluido (0-1)")]
[property: Category("Simulación:")]
[property: Name("Densidad Fluido")]
private double densidadFluido = 0.7;
// Lista de puntos que forman la tubería
@ -102,10 +108,14 @@ namespace CtrEditor.ObjetosSim
// Nombre de la clase para identificación
public static string NombreClase()
{
return "TuberiaFluido";
return "Tubería de Fluido";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;

View File

@ -58,35 +58,41 @@ namespace CtrEditor.ObjetosSim
// Propiedades dimensionales
[ObservableProperty]
[property: Category("Dimensiones:")]
[property: Category("Configuración")]
[property: Description("Ancho de la válvula en metros")]
[property: Name("Ancho")]
private float ancho = 0.1f;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Alto de la válvula en metros")]
[property: Category("Dimensiones:")]
[property: Name("Alto")]
private float alto = 0.06f;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Diámetro de la tubería conectada")]
[property: Category("Dimensiones:")]
[property: Name("Diámetro Tubería")]
private float diametroTuberia = 0.05f;
// Propiedades visuales
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color de la válvula")]
[property: Category("Visual:")]
[property: Name("Color")]
private Color color = Colors.Silver;
[ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color del indicador de apertura")]
[property: Category("Visual:")]
[property: Name("Color Indicador")]
private Color colorIndicador = Colors.CornflowerBlue;
// Propiedades de funcionamiento
[ObservableProperty]
[property: Category("Simulación")]
[property: Description("Apertura de la válvula (0-1)")]
[property: Category("Operación:")]
[property: Name("Apertura")]
private float apertura = 1.0f;
partial void OnAperturaChanged(float value)
@ -102,8 +108,9 @@ namespace CtrEditor.ObjetosSim
// Tag PLC para la válvula
[ObservableProperty]
[property: Description("Tag de lectura/escritura de la apertura (0-100%)")]
[property: Category("PLC:")]
[property: Category("Enlace PLC")]
[property: Description("Tag PLC para lectura/escritura de apertura (0-100%)")]
[property: Name("Tag Apertura")]
private string tagApertura;
// Propiedades calculadas para visualización
@ -122,10 +129,14 @@ namespace CtrEditor.ObjetosSim
// Nombre de la clase para identificación
public static string NombreClase()
{
return "ValvulaFluido";
return "Válvula de Fluido";
}
private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre
{
get => nombre;

View File

@ -0,0 +1,138 @@
# Script para estandarizar objetos derivados de osBase
# Ejecutar desde la raíz del proyecto CtrEditor
Write-Host "=== Estandarización de Objetos osBase ===" -ForegroundColor Green
# Mapeo de nombres de clase mejorados
$nombresClase = @{
# Transportes
"ucTransporteTTop" = "Transporte TTOP"
"ucTransporteTTopDualInverter" = "Transporte TTOP Dual Inverter"
"ucTransporteGuias" = "Transporte con Guías"
"ucTransporteGuiasUnion" = "Transporte con Guías Unión"
"ucTransporteCurva" = "Transporte Curva"
"ucTransporteCurvaGuias" = "Transporte Curva con Guías"
# Sensores
"ucPhotocell" = "Fotocélula"
"ucGearEncoder" = "Encoder de Engranaje"
"ucEncoderMotor" = "Encoder Motor"
"ucEncoderMotorLineal" = "Encoder Motor Lineal"
"ucSensTemperatura" = "Sensor de Temperatura"
"ucBoton" = "Botón"
# Actuadores
"ucVMmotorSim" = "Motor VetroMeccanica"
"ucValvulaFluido" = "Válvula de Fluido"
# Elementos Estáticos
"ucGuia" = "Guía"
"ucDescarte" = "Descarte"
# Emuladores
"ucBottGenerator" = "Generador de Botellas"
"ucFiller" = "Llenadora"
"ucTanque" = "Tanque"
# Señales
"ucAnalogTag" = "Tag Analógico"
"ucBoolTag" = "Tag Digital"
"ucConsensGeneric" = "Consenso Genérico"
# Datos
"ucExtraccionTag" = "Extracción de Tag"
"ucBuscarCoincidencias" = "Búsqueda de Coincidencias"
# Decorativos
"ucCustomImage" = "Imagen Personalizada"
"ucFramePlate" = "Marco"
"ucTextPlate" = "Placa de Texto"
# Fluidos
"ucTuberiaFluido" = "Tubería de Fluido"
"osSistemaFluidos" = "Sistema de Fluidos"
# Trazas
"ucTrace3" = "Traza 3 Puntos"
"ucTraceSimple" = "Traza Simple"
# Dinámicos
"ucBotella" = "Botella"
"ucBotellaCuello" = "Botella con Cuello"
# Ejemplo
"ucBasicExample" = "Ejemplo Básico"
}
# Mapeo de categorías estándar
$categoriasEstandar = @{
"Id:" = "Identificación"
"Layout:" = "Posición y Tamaño"
"Setup:" = "Configuración"
"Simulation:" = "Simulación"
"PLC link:" = "Enlace PLC"
"Debug:" = "Información"
"Encoder:" = "Encoder"
"General:" = "Identificación"
}
function Actualizar-NombreClase {
param(
[string]$archivo,
[string]$nuevoNombre
)
$contenido = Get-Content $archivo -Raw
$patron = 'return\s+"[^"]*";'
$reemplazo = "return `"$nuevoNombre`";"
if ($contenido -match $patron) {
$contenido = $contenido -replace $patron, $reemplazo
Set-Content $archivo $contenido -NoNewline
Write-Host "✓ Actualizado NombreClase en $archivo" -ForegroundColor Yellow
}
}
function Estandarizar-Categorias {
param([string]$archivo)
$contenido = Get-Content $archivo -Raw
$modificado = $false
foreach ($categoria in $categoriasEstandar.Keys) {
$patron = [regex]::Escape("Category(`"$categoria`")")
$reemplazo = "Category(`"$($categoriasEstandar[$categoria])`")"
if ($contenido -match $patron) {
$contenido = $contenido -replace $patron, $reemplazo
$modificado = $true
}
}
if ($modificado) {
Set-Content $archivo $contenido -NoNewline
Write-Host "✓ Estandarizadas categorías en $archivo" -ForegroundColor Cyan
}
}
# Buscar todos los archivos .cs en ObjetosSim
$archivos = Get-ChildItem -Path "ObjetosSim" -Filter "*.cs" -Recurse | Where-Object {
$_.Name -like "uc*.cs" -or $_.Name -like "os*.cs"
}
Write-Host "Encontrados $($archivos.Count) archivos para procesar" -ForegroundColor Blue
foreach ($archivo in $archivos) {
$nombreArchivo = [System.IO.Path]::GetFileNameWithoutExtension($archivo.Name)
# Actualizar nombre de clase si está en el mapeo
if ($nombresClase.ContainsKey($nombreArchivo)) {
Actualizar-NombreClase -archivo $archivo.FullName -nuevoNombre $nombresClase[$nombreArchivo]
}
# Estandarizar categorías
Estandarizar-Categorias -archivo $archivo.FullName
}
Write-Host "=== Proceso completado ===" -ForegroundColor Green
Write-Host "Revise los cambios y verifique que la compilación sea exitosa" -ForegroundColor Yellow

View File

@ -6,6 +6,7 @@ using System.Windows;
using CtrEditor.Simulacion;
using System.IO;
using System.Linq;
using System.Windows.Media;
namespace CtrEditor.Serialization
{
@ -254,8 +255,94 @@ namespace CtrEditor.Serialization
NullValueHandling = NullValueHandling.Ignore,
TypeNameHandling = TypeNameHandling.Auto,
ObjectCreationHandling = ObjectCreationHandling.Replace,
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
Error = HandleDeserializationError,
Converters = { new SafeImageSourceConverter() },
// Configuración para respetar atributos JsonIgnore de Newtonsoft.Json
ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver
{
IgnoreSerializableAttribute = false
}
};
}
private void HandleDeserializationError(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs e)
{
// Si es un error relacionado con ImagePath, ImageSource o osCustomImage, simplemente ignorarlo y continuar
if (e.ErrorContext.Error.Message.Contains("ImagePath") ||
e.ErrorContext.Error.Message.Contains("osCustomImage") ||
e.ErrorContext.Error.Message.Contains("ImageSource") ||
e.ErrorContext.Error.Message.Contains("lmageSource") || // posible typo en el mensaje de error
(e.ErrorContext.Path != null && e.ErrorContext.Path.Contains("ImageSource")) ||
(e.ErrorContext.Path != null && e.ErrorContext.Path.Contains("imagePath")) ||
(e.ErrorContext.Member != null && e.ErrorContext.Member.ToString().Contains("Image")))
{
e.ErrorContext.Handled = true;
// Si el contexto actual es un objeto osCustomImage y hay un error,
// intentar establecer valores por defecto
if (e.ErrorContext.OriginalObject is osCustomImage customImage)
{
try
{
// Establecer valores seguros por defecto
if (e.ErrorContext.Member?.ToString() == "ImagePath" ||
e.ErrorContext.Member?.ToString() == "imagePath")
{
customImage.ImagePath = ""; // Esto activará el fallback a imagen por defecto
}
}
catch
{
// Si incluso esto falla, simplemente ignorar
}
}
}
}
}
/// <summary>
/// Convertidor JSON seguro para ImageSource que nunca lanza excepciones
/// </summary>
public class SafeImageSourceConverter : JsonConverter<ImageSource>
{
public override ImageSource ReadJson(JsonReader reader, Type objectType, ImageSource existingValue, bool hasExistingValue, JsonSerializer serializer)
{
try
{
// Si el valor es null o string vacío, devolver null
if (reader.Value == null || reader.Value.ToString() == "")
return null;
// Intentar crear ImageSource desde el valor
string value = reader.Value.ToString();
// Limpiar caracteres problemáticos
value = value.Trim();
if (value.Contains("•"))
value = value.Replace("•", "");
if (value.StartsWith("filet///"))
value = value.Replace("filet///", "file:///");
// Si el valor limpio está vacío, devolver null
if (string.IsNullOrWhiteSpace(value))
return null;
// No intentar crear ImageSource aquí, simplemente devolver null
// La lógica de carga de imagen se manejará en el código de la aplicación
return null;
}
catch
{
// En caso de cualquier error, devolver null silenciosamente
return null;
}
}
public override void WriteJson(JsonWriter writer, ImageSource value, JsonSerializer serializer)
{
// Nunca serializar ImageSource, siempre escribir null
writer.WriteNull();
}
}
}