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:SubclassFilterConverter x:Key="SubclassFilterConverterosVMMotor" TargetType="{x:Type os:osVMmotorSim}" />
<local:UnsavedChangesConverter x:Key="UnsavedChangesConverter"/> <local:UnsavedChangesConverter x:Key="UnsavedChangesConverter"/>
<local:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/> <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.Resources>
</Application> </Application>

View File

@ -18,6 +18,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Remove="Documentation\PlantillaEstandarizacion.cs" />
<Compile Remove="ObjetosSim\ucBasicExample.xaml.cs" /> <Compile Remove="ObjetosSim\ucBasicExample.xaml.cs" />
<Compile Remove="ObjetosSim\ucTransporteCurva.xaml.cs" /> <Compile Remove="ObjetosSim\ucTransporteCurva.xaml.cs" />
<Compile Remove="Simulacion\FPhysics.cs" /> <Compile Remove="Simulacion\FPhysics.cs" />
@ -70,6 +71,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="Documentation\PlantillaEstandarizacion.cs" />
<None Include="ObjetosSim\ucBasicExample.xaml" /> <None Include="ObjetosSim\ucBasicExample.xaml" />
<None Include="ObjetosSim\ucBasicExample.xaml.cs" /> <None Include="ObjetosSim\ucBasicExample.xaml.cs" />
<None Include="Simulacion\FPhysics.cs" /> <None Include="Simulacion\FPhysics.cs" />
@ -85,8 +87,9 @@
<PackageReference Include="Emgu.CV.UI" Version="4.9.0.5494" /> <PackageReference Include="Emgu.CV.UI" Version="4.9.0.5494" />
<PackageReference Include="Extended.Wpf.Toolkit" Version="4.7.25104.5739" /> <PackageReference Include="Extended.Wpf.Toolkit" Version="4.7.25104.5739" />
<PackageReference Include="LanguageDetection" Version="1.2.0" /> <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="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="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Ookii.Dialogs.Wpf" Version="5.0.1" /> <PackageReference Include="Ookii.Dialogs.Wpf" Version="5.0.1" />
<PackageReference Include="PaddleOCRSharp" Version="4.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) // Mostrar como modeless (no modal)
libraryWindow.Show(); libraryWindow.Show();
} }
} }
public class SimulationData public class SimulationData

View File

@ -260,7 +260,8 @@ namespace CtrEditor
// Calcular el bounding box que contenga todos los objetos seleccionados // Calcular el bounding box que contenga todos los objetos seleccionados
Rect boundingBox = CalculateTotalBoundingBox(selectedObjects); Rect boundingBox = CalculateTotalBoundingBox(selectedObjects);
if (_selectedObjectsAreVisible) { if (_selectedObjectsAreVisible)
{
FuncionesBase.MutableRect rectBox = new FuncionesBase.MutableRect(boundingBox); FuncionesBase.MutableRect rectBox = new FuncionesBase.MutableRect(boundingBox);
rectBox.Left -= (float)rectHighlightSize; rectBox.Left -= (float)rectHighlightSize;
@ -303,7 +304,7 @@ namespace CtrEditor
foreach (var obj in selectedObjects) foreach (var obj in selectedObjects)
{ {
if (obj.VisualRepresentation != null && obj.VisualRepresentation.Visibility!=Visibility.Collapsed) if (obj.VisualRepresentation != null && obj.VisualRepresentation.Visibility != Visibility.Collapsed)
{ {
// Obtener el bounding box del objeto actual // Obtener el bounding box del objeto actual
Rect objectBounds = VisualTreeHelper.GetDescendantBounds(obj.VisualRepresentation); Rect objectBounds = VisualTreeHelper.GetDescendantBounds(obj.VisualRepresentation);
@ -1125,6 +1126,9 @@ namespace CtrEditor
RemoveAllSelectionHighlights(); // Remover antes de rotar 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 // Calcular el ángulo respecto al centro del bounding box que contiene todos los objetos seleccionados
double deltaX = currentPosition.X - _transformedBoundingBoxCenter.X; double deltaX = currentPosition.X - _transformedBoundingBoxCenter.X;
double deltaY = currentPosition.Y - _transformedBoundingBoxCenter.Y; double deltaY = currentPosition.Y - _transformedBoundingBoxCenter.Y;
@ -1137,11 +1141,48 @@ namespace CtrEditor
else else
{ {
double deltaAngle = angle - _lastAngle; double deltaAngle = angle - _lastAngle;
foreach (var selectedObject in _selectedObjects)
if (isShiftPressed)
{ {
selectedObject.Rotate(deltaAngle); // 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;
} }
_lastAngle = (float)angle;
} }
UpdateAllSelectionHighlights(); UpdateAllSelectionHighlights();

View File

@ -16,48 +16,103 @@ namespace CtrEditor.ObjetosSim
{ {
public static string NombreClase() public static string NombreClase()
{ {
return "Custom Image"; return "Imagen Personalizada";
} }
private string nombre = NombreClase(); private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre public override string Nombre
{ {
get => nombre; get => nombre;
set => SetProperty(ref nombre, value); 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] [ObservableProperty]
[NotifyPropertyChangedFor(nameof(ImageSource_oculta))] [property: Description("Voltear la imagen horizontalmente")]
[property: Description("Path to the image file")] [property: Category("Configuración")]
[property: Category("Image:")] [property: Name("Voltear Horizontal")]
private string imagePath;
[ObservableProperty]
[property: Description("Flip the image horizontally")]
[property: Category("Image:")]
private bool horizontal_Flip; private bool horizontal_Flip;
[ObservableProperty] [ObservableProperty]
[property: Description("Flip the image vertically")] [property: Description("Voltear la imagen verticalmente")]
[property: Category("Image:")] [property: Category("Configuración")]
[property: Name("Voltear Vertical")]
private bool vertical_Flip; private bool vertical_Flip;
[JsonIgnore]
[ObservableProperty] [ObservableProperty]
[property: JsonIgnore]
[property: Category("Apariencia")]
[property: Description("Imagen visual del objeto")]
[property: Name("Imagen")]
public ImageSource imageSource_oculta; public ImageSource imageSource_oculta;
partial void OnImagePathChanged(string value) private void OnImagePathChanged(string value)
{ {
if (!string.IsNullOrEmpty(value)) try
{ {
ImageSource_oculta = ImageFromPath(value); if (!string.IsNullOrEmpty(value))
{
ImageSource_oculta = ImageFromPath(value);
}
else
{
// Si no hay path, usar la imagen por defecto
ImageSource_oculta = ImageFromPath("/Icons/unselect.png");
}
} }
else catch
{ {
// Si no hay path, usar la imagen por defecto // Si hay cualquier error, usar la imagen por defecto
ImageSource_oculta = ImageFromPath("/Icons/unselect.png"); try
{
ImageSource_oculta = ImageFromPath("/Icons/unselect.png");
}
catch
{
// Si incluso la imagen por defecto falla, establecer como null
ImageSource_oculta = null;
}
} }
} }
@ -82,14 +137,30 @@ namespace CtrEditor.ObjetosSim
public override void ucLoaded() public override void ucLoaded()
{ {
base.ucLoaded(); base.ucLoaded();
if (!string.IsNullOrEmpty(ImagePath)) try
{ {
ImageSource_oculta = ImageFromPath(ImagePath); if (!string.IsNullOrEmpty(ImagePath))
{
ImageSource_oculta = ImageFromPath(ImagePath);
}
else
{
// Si no hay path al cargar, usar la imagen por defecto
ImageSource_oculta = ImageFromPath("/Icons/unselect.png");
}
} }
else catch
{ {
// Si no hay path al cargar, usar la imagen por defecto // Si hay cualquier error, usar la imagen por defecto
ImageSource_oculta = ImageFromPath("/Icons/unselect.png"); try
{
ImageSource_oculta = ImageFromPath("/Icons/unselect.png");
}
catch
{
// Si incluso la imagen por defecto falla, establecer como null
ImageSource_oculta = null;
}
} }
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -23,9 +23,13 @@ namespace CtrEditor.ObjetosSim
public static string NombreClase() 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 public override string Nombre
{ {
get => nombre; get => nombre;
@ -33,6 +37,9 @@ namespace CtrEditor.ObjetosSim
} }
[ObservableProperty] [ObservableProperty]
[property: Category("Simulación")]
[property: Description("Velocidad actual del transporte en m/s")]
[property: Name("Velocidad Actual")]
public float velocidadActual; public float velocidadActual;
partial void OnVelocidadActualChanged(float value) partial void OnVelocidadActualChanged(float value)
@ -41,11 +48,19 @@ namespace CtrEditor.ObjetosSim
} }
[ObservableProperty] [ObservableProperty]
[property: Category("Configuración")]
[property: Description("Invierte el sentido de movimiento del transporte")]
[property: Name("Invertir Dirección")]
bool invertirDireccion; bool invertirDireccion;
partial void OnInvertirDireccionChanged(bool value) partial void OnInvertirDireccionChanged(bool value)
{ {
SetSpeed(); SetSpeed();
if (_visualRepresentation is ucTransporteCurva uc)
{
CrearAnimacionStoryBoardTrasnporteCircular(uc.Transporte.TransportePath, InvertirDireccion, Angulo);
ActualizarAnimacionStoryBoardTransporte(VelocidadActual);
}
} }
void SetSpeed() void SetSpeed()
@ -54,9 +69,13 @@ namespace CtrEditor.ObjetosSim
Simulation_TransporteCurva?.SetSpeed(-VelocidadActual); Simulation_TransporteCurva?.SetSpeed(-VelocidadActual);
else else
Simulation_TransporteCurva?.SetSpeed(VelocidadActual); Simulation_TransporteCurva?.SetSpeed(VelocidadActual);
ActualizarAnimacionStoryBoardTransporte(VelocidadActual);
} }
[ObservableProperty] [ObservableProperty]
[property: Category("Configuración")]
[property: Description("Radio exterior de la curva en metros")]
[property: Name("Radio Exterior")]
private float radioExterno; private float radioExterno;
partial void OnRadioExternoChanged(float value) partial void OnRadioExternoChanged(float value)
@ -75,18 +94,21 @@ namespace CtrEditor.ObjetosSim
} }
[ObservableProperty] [ObservableProperty]
[property: Category("Configuración")]
[property: Description("Radio interior de la curva en metros")]
[property: Name("Radio Interior")]
private float radioInterno; private float radioInterno;
[ObservableProperty] [ObservableProperty]
[property: Description("Bit to enable Link to Motor")] [property: Description("Tag de bit para activar enlace con motor")]
[property: Category("PLC link:")] [property: Category("Enlace PLC")]
[property: Name("Tag Activación Motor")]
string tag_ReleActivatedMotor; string tag_ReleActivatedMotor;
[ObservableProperty] [ObservableProperty]
[property: Description("Link to Motor")] [property: Description("Seleccionar motor para enlazar")]
[property: Category("PLC link:")] [property: Category("Enlace PLC")]
[property: Name("Motor Enlazado")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))] [property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
string id_Motor; string id_Motor;
@ -127,14 +149,14 @@ namespace CtrEditor.ObjetosSim
[Hidden] [Hidden]
public float AnguloFinal public float AnguloFinal
{ {
get => Angulo+Arco_en_grados; get => Angulo + Arco_en_grados;
} }
private void ActualizarGeometrias() private void ActualizarGeometrias()
{ {
if (_visualRepresentation is ucTransporteCurva uc) if (_visualRepresentation is ucTransporteCurva uc)
{ {
UpdateCurve(Simulation_TransporteCurva, RadioInterno, RadioExterno, Angulo, Angulo+Arco_en_grados); UpdateCurve(Simulation_TransporteCurva, RadioInterno, RadioExterno, Angulo, Angulo + Arco_en_grados);
SetSpeed(); SetSpeed();
} }
} }
@ -205,9 +227,14 @@ namespace CtrEditor.ObjetosSim
{ {
// Se llama antes de la simulacion // Se llama antes de la simulacion
ActualizarGeometrias(); ActualizarGeometrias();
} }
public override void SimulationStop()
{
// Se llama al detener la simulacion
ActualizarAnimacionStoryBoardTransporte(VelocidadActual);
}
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds) public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{ {
if (Motor != null) if (Motor != null)
@ -225,13 +252,13 @@ namespace CtrEditor.ObjetosSim
// El UserControl ya se ha cargado y podemos obtener las coordenadas para // El UserControl ya se ha cargado y podemos obtener las coordenadas para
// crear el objeto de simulacion // crear el objeto de simulacion
base.ucLoaded(); base.ucLoaded();
OnId_MotorChanged(Id_Motor); // Link Id_Motor = Motor OnId_MotorChanged(Id_Motor); // Link Id_Motor = Motor
if (_visualRepresentation is ucTransporteCurva uc) if (_visualRepresentation is ucTransporteCurva uc)
Simulation_TransporteCurva = AddCurve(RadioInterno,RadioExterno, Angulo, Angulo + Arco_en_grados); {
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() 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() public static string NombreClase()
{ {
return "Transporte Guias"; return "Transporte con Guías";
} }
private string nombre = NombreClase(); private string nombre = NombreClase();
[property: Category("Identificación")]
[property: Description("Nombre identificativo del objeto")]
[property: Name("Nombre")]
public override string Nombre public override string Nombre
{ {
get => nombre; get => nombre;
@ -36,6 +39,9 @@ namespace CtrEditor.ObjetosSim
} }
[ObservableProperty] [ObservableProperty]
[property: Category("Simulación")]
[property: Description("Velocidad actual del transporte")]
[property: Name("Velocidad Actual")]
public float velocidadActual; public float velocidadActual;
partial void OnVelocidadActualChanged(float value) partial void OnVelocidadActualChanged(float value)
@ -44,6 +50,9 @@ namespace CtrEditor.ObjetosSim
} }
[ObservableProperty] [ObservableProperty]
[property: Category("Configuración")]
[property: Description("Invierte el sentido de movimiento")]
[property: Name("Invertir Dirección")]
bool invertirDireccion; bool invertirDireccion;
partial void OnInvertirDireccionChanged(bool value) partial void OnInvertirDireccionChanged(bool value)
@ -67,16 +76,21 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty] [ObservableProperty]
[property: Category("Apariencia")]
[property: Description("Color del transporte")]
[property: Name("Color")]
Color color = Colors.Blue; Color color = Colors.Blue;
[ObservableProperty] [ObservableProperty]
[property: Description("Bit to enable Link to Motor")] [property: Category("Enlace PLC")]
[property: Category("PLC link:")] [property: Description("Tag para activar enlace con motor")]
[property: Name("Tag Activación Motor")]
string tag_ReleActivatedMotor; string tag_ReleActivatedMotor;
[ObservableProperty] [ObservableProperty]
[property: Description("Link to Motor")] [property: Category("Enlace PLC")]
[property: Category("PLC link:")] [property: Description("Motor enlazado al transporte")]
[property: Name("Motor Enlazado")]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))] [property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
string id_Motor; string id_Motor;
@ -111,6 +125,9 @@ namespace CtrEditor.ObjetosSim
} }
[ObservableProperty] [ObservableProperty]
[property: Category("Configuración")]
[property: Description("Actuar como freno")]
[property: Name("Es Freno")]
public bool esFreno; public bool esFreno;
partial void OnEsFrenoChanged(bool value) partial void OnEsFrenoChanged(bool value)
@ -120,16 +137,39 @@ namespace CtrEditor.ObjetosSim
} }
[ObservableProperty] [ObservableProperty]
[property: Category("Configuración")]
[property: Description("Coeficiente de fricción")]
[property: Name("Coeficiente Fricción")]
public float frictionCoefficient; public float frictionCoefficient;
[ObservableProperty] [ObservableProperty]
[property: Category("Configuración")]
[property: Description("Velocidad máxima a 50Hz")]
[property: Name("Velocidad Max 50Hz")]
public float velMax50hz; public float velMax50hz;
[ObservableProperty] [ObservableProperty]
[property: Category("Configuración")]
[property: Description("Tiempo de rampa")]
[property: Name("Tiempo Rampa")]
public float tiempoRampa; public float tiempoRampa;
[ObservableProperty] [ObservableProperty]
[property: Category("Información")]
[property: Description("Estado de marcha")]
[property: Name("En Marcha")]
public bool esMarcha; public bool esMarcha;
[ObservableProperty] [ObservableProperty]
[property: Category("Configuración")]
[property: Description("Distancia entre guías")]
[property: Name("Distancia")]
private float distance; private float distance;
[ObservableProperty] [ObservableProperty]
[property: Category("Configuración")]
[property: Description("Alto de las guías")]
[property: Name("Alto Guía")]
private float altoGuia; private float altoGuia;
private void ActualizarGeometrias() private void ActualizarGeometrias()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,3 +1,4 @@
using System;
using System.ComponentModel; using System.ComponentModel;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
@ -12,9 +13,26 @@ namespace CtrEditor.ObjetosSim
/// <summary> /// <summary>
/// Atributo para marcar propiedades que deben usar el editor de etiquetas /// Atributo para marcar propiedades que deben usar el editor de etiquetas
/// </summary> /// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class TagEditorAttribute : Attribute 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> /// <summary>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -190,12 +190,26 @@ namespace CtrEditor.ObjetosSim
continue; continue;
var displayNameAttr = property.Attributes.OfType<DisplayNameAttribute>().FirstOrDefault(); 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 var propertyDefinition = new PropertyDefinition
{ {
TargetProperties = new[] { property.Name }, TargetProperties = new[] { property.Name },
DisplayName = displayNameAttr != null DisplayName = displayName
? displayNameAttr.DisplayName
: property.Name.Replace("_", " ")
}; };
// Aquí se añaden todas las propiedades; para "ImagePath" no se requiere // 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:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:CtrEditor.ObjetosSim.UserControls" xmlns:local="clr-namespace:CtrEditor.ObjetosSim.UserControls"
mc:Ignorable="d" Name="circularSegmentControl"> mc:Ignorable="d" Name="circularSegmentControl">
<Canvas> <Canvas Name="mainCanvas">
<Path Name="path" Stroke="Black" Fill="LightBlue" StrokeThickness="1"> <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> <Path.RenderTransform>
<RotateTransform Angle="{Binding Angle, ElementName=circularSegmentControl}"/> <RotateTransform Angle="{Binding Angle, ElementName=circularSegmentControl}"/>
</Path.RenderTransform> </Path.RenderTransform>

View File

@ -1,6 +1,7 @@
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Shapes;
namespace CtrEditor.ObjetosSim.UserControls namespace CtrEditor.ObjetosSim.UserControls
{ {
@ -54,21 +55,95 @@ namespace CtrEditor.ObjetosSim.UserControls
public static readonly DependencyProperty EndAngleProperty = public static readonly DependencyProperty EndAngleProperty =
DependencyProperty.Register("EndAngle", typeof(double), typeof(CircularSegment), new PropertyMetadata(90.0, OnPropertyChanged)); 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() public CircularSegment()
{ {
InitializeComponent(); 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) private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{ {
(d as CircularSegment)?.DrawSegment(); (d as CircularSegment)?.DrawSegment();
} }
private static void OnGuidePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as CircularSegment)?.DrawSegment();
}
private void DrawSegment() private void DrawSegment()
{ {
System.Diagnostics.Debug.WriteLine($"DrawSegment called - ShowGuides: {ShowGuides}");
if (OuterRadius <= 0 || InnerRadius <= 0 || StartAngle == EndAngle) if (OuterRadius <= 0 || InnerRadius <= 0 || StartAngle == EndAngle)
return; 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(); PathGeometry geometry = new PathGeometry();
PathFigure figure = new PathFigure(); PathFigure figure = new PathFigure();
@ -100,5 +175,76 @@ namespace CtrEditor.ObjetosSim.UserControls
geometry.Figures.Add(figure); geometry.Figures.Add(figure);
path.Data = geometry; 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] [JsonIgnore]
private System.Threading.Timer timer = null; private System.Threading.Timer timer = null;
[JsonIgnore]
[ObservableProperty] [ObservableProperty]
[property: JsonIgnore]
[property: Hidden] [property: Hidden]
public bool isVisFilter; public bool isVisFilter;
@ -80,13 +80,15 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty] [ObservableProperty]
[property: Description("Lock object to mouse movement.")] [property: Category("Configuración")]
[property: Category("Layout:")] [property: Description("Bloquear movimiento del objeto")]
[property: Name("Bloquear Movimiento")]
private bool lock_movement; private bool lock_movement;
[ObservableProperty] [ObservableProperty]
[property: Description("X coordinate.")] [property: Category("Configuración")]
[property: Category("Layout:")] [property: Description("Coordenada X del objeto")]
[property: Name("Izquierda")]
private float left; private float left;
public void CheckData() public void CheckData()
@ -114,8 +116,9 @@ namespace CtrEditor.ObjetosSim
public virtual void LeftChanging(float oldValue, float newValue) { } public virtual void LeftChanging(float oldValue, float newValue) { }
[ObservableProperty] [ObservableProperty]
[property: Description("Y coordinate.")] [property: Category("Configuración")]
[property: Category("Layout:")] [property: Description("Coordenada Y del objeto")]
[property: Name("Superior")]
private float top; private float top;
partial void OnTopChanged(float value) partial void OnTopChanged(float value)
@ -137,8 +140,9 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty] [ObservableProperty]
[property: Description("Widht.")] [property: Category("Configuración")]
[property: Category("Layout:")] [property: Description("Ancho del objeto")]
[property: Name("Ancho")]
private float ancho; private float ancho;
partial void OnAnchoChanged(float value) partial void OnAnchoChanged(float value)
@ -148,8 +152,9 @@ namespace CtrEditor.ObjetosSim
public virtual void AnchoChanged(float value) { } public virtual void AnchoChanged(float value) { }
[ObservableProperty] [ObservableProperty]
[property: Description("Height.")] [property: Category("Configuración")]
[property: Category("Layout:")] [property: Description("Alto del objeto")]
[property: Name("Alto")]
private float alto; private float alto;
partial void OnAltoChanged(float value) partial void OnAltoChanged(float value)
@ -160,8 +165,9 @@ namespace CtrEditor.ObjetosSim
[ObservableProperty] [ObservableProperty]
[property: Description("Angle.")] [property: Category("Configuración")]
[property: Category("Layout:")] [property: Description("Ángulo de rotación del objeto")]
[property: Name("Ángulo")]
private float angulo; private float angulo;
partial void OnAnguloChanged(float value) partial void OnAnguloChanged(float value)
@ -177,8 +183,9 @@ namespace CtrEditor.ObjetosSim
public virtual void AnguloChanging(float oldValue, float newValue) { } public virtual void AnguloChanging(float oldValue, float newValue) { }
[ObservableProperty] [ObservableProperty]
[property: Category("Identificación")]
[property: Description("Etiquetas para clasificar el objeto. Use # antes de cada etiqueta (ej: #motor #bomba #critico)")] [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: Editor(typeof(TagPropertyEditor), typeof(TagPropertyEditor))]
[property: TagEditor] [property: TagEditor]
private string etiquetas = ""; private string etiquetas = "";
@ -290,8 +297,9 @@ namespace CtrEditor.ObjetosSim
// Group as FacePlate // Group as FacePlate
[ObservableProperty] [ObservableProperty]
[property: Description("This is a link to a faceplate. It works like an anchor.")] [property: Category("Agrupación")]
[property: Category("Group:")] [property: Description("Enlace a una placa de texto como ancla")]
[property: Name("Panel Grupo")]
[property: ItemsSource(typeof(osBaseItemsSource<osTextPlate>))] [property: ItemsSource(typeof(osBaseItemsSource<osTextPlate>))]
private string group_Panel; private string group_Panel;
@ -333,8 +341,9 @@ namespace CtrEditor.ObjetosSim
// Group as FacePlate // Group as FacePlate
[ObservableProperty] [ObservableProperty]
[property: Description("This is a link to a FromPlate that moves automatically. It works like an anchor.")] [property: Category("Agrupación")]
[property: Category("Group:")] [property: Description("Enlace a un marco que se mueve automáticamente como ancla")]
[property: Name("Panel Marco")]
[property: ItemsSource(typeof(osBaseItemsSource<osFramePlate>))] [property: ItemsSource(typeof(osBaseItemsSource<osFramePlate>))]
private string group_FramePanel; private string group_FramePanel;
@ -344,28 +353,28 @@ namespace CtrEditor.ObjetosSim
private bool isUpdatingFromFramePlate = false; private bool isUpdatingFromFramePlate = false;
// Variables para rotación orbital alrededor del FramePlate // Variables para rotación orbital alrededor del FramePlate
[JsonIgnore]
[ObservableProperty] [ObservableProperty]
[property: JsonIgnore]
[property: Hidden] [property: Hidden]
private float framePlate_RelativeX; private float framePlate_RelativeX;
[JsonIgnore]
[ObservableProperty] [ObservableProperty]
[property: JsonIgnore]
[property: Hidden] [property: Hidden]
private float framePlate_RelativeY; private float framePlate_RelativeY;
[JsonIgnore]
[ObservableProperty] [ObservableProperty]
[property: JsonIgnore]
[property: Hidden] [property: Hidden]
private float framePlate_InitialAngle; private float framePlate_InitialAngle;
[JsonIgnore]
[ObservableProperty] [ObservableProperty]
[property: JsonIgnore]
[property: Hidden] [property: Hidden]
private float framePlate_PivotX; private float framePlate_PivotX;
[JsonIgnore]
[ObservableProperty] [ObservableProperty]
[property: JsonIgnore]
[property: Hidden] [property: Hidden]
private float framePlate_PivotY; private float framePlate_PivotY;
@ -754,8 +763,9 @@ namespace CtrEditor.ObjetosSim
// All Pages Objects // All Pages Objects
[NotifyPropertyChangedFor(nameof(Show_On_This_Page))] [NotifyPropertyChangedFor(nameof(Show_On_This_Page))]
[ObservableProperty] [ObservableProperty]
[property: Description("Enable this object to be used in all pages.")] [property: Category("Configuración")]
[property: Category("Layout:")] [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; private bool enable_On_All_Pages;
@ -779,8 +789,9 @@ namespace CtrEditor.ObjetosSim
// Local Data for Global Objects // Local Data for Global Objects
[NotifyPropertyChangedFor(nameof(Show_On_This_Page))] [NotifyPropertyChangedFor(nameof(Show_On_This_Page))]
[ObservableProperty] [ObservableProperty]
[property: Description("Enable local data of this global Object on all pages.")] [property: Category("Configuración")]
[property: Category("Layout:")] [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; private bool enable_Local_Data_for_All;
partial void OnEnable_Local_Data_for_AllChanged(bool value) partial void OnEnable_Local_Data_for_AllChanged(bool value)
@ -795,8 +806,9 @@ namespace CtrEditor.ObjetosSim
// Local Data for Global Objects // Local Data for Global Objects
[NotifyPropertyChangedFor(nameof(Show_On_This_Page))] [NotifyPropertyChangedFor(nameof(Show_On_This_Page))]
[ObservableProperty] [ObservableProperty]
[property: Description("Enable local data of this global Object on this page.")] [property: Category("Configuración")]
[property: Category("Layout:")] [property: Description("Habilitar datos locales de este objeto global en esta página")]
[property: Name("Datos Locales")]
[property: JsonIgnore] [property: JsonIgnore]
private bool enable_Local_Data; private bool enable_Local_Data;
@ -910,7 +922,9 @@ namespace CtrEditor.ObjetosSim
private List<string> showOnThisPagesList; private List<string> showOnThisPagesList;
private bool show_On_This_Page; 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 public bool Show_On_This_Page
{ {
get get
@ -958,13 +972,15 @@ namespace CtrEditor.ObjetosSim
} }
[ObservableProperty] [ObservableProperty]
[property: Description("Autocreated and cloned with Search Templates")] [property: Category("Datos")]
[property: Category("Tag Extraction:")] [property: Description("Creado automáticamente y clonado con plantillas de búsqueda")]
[property: Name("Clonado")]
bool cloned; bool cloned;
[ObservableProperty] [ObservableProperty]
[property: Description("Autocreated and cloned with Search Templates")] [property: Category("Datos")]
[property: Category("Tag Extraction:")] [property: Description("ID del objeto del cual fue clonado")]
[property: Name("Clonado Desde")]
[property: Hidden] [property: Hidden]
UniqueId cloned_from; UniqueId cloned_from;
@ -1153,6 +1169,27 @@ namespace CtrEditor.ObjetosSim
return storyboard; 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) protected Storyboard CrearAnimacionMultiStoryBoardTrasnporte(Storyboard storyboard, Rectangle transporte, bool invertirDireccion)
{ {
// Detener y eliminar el storyboard existente si hay uno // Detener y eliminar el storyboard existente si hay uno
@ -1165,6 +1202,18 @@ namespace CtrEditor.ObjetosSim
return CrearAnimacionMultiStoryBoardTrasnporte(transporte, invertirDireccion); 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) protected void ActualizarAnimacionMultiStoryBoardTransporte(Storyboard storyboard, float velocidadActual)
{ {
if (_visualRepresentation == null) return; if (_visualRepresentation == null) return;
@ -1181,6 +1230,14 @@ namespace CtrEditor.ObjetosSim
_storyboard = CrearAnimacionMultiStoryBoardTrasnporte(_storyboard, transporte, invertirDireccion); _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) protected void ActualizarAnimacionStoryBoardTransporte(float velocidadActual)
{ {
ActualizarAnimacionMultiStoryBoardTransporte(_storyboard, velocidadActual); ActualizarAnimacionMultiStoryBoardTransporte(_storyboard, velocidadActual);
@ -1601,7 +1658,31 @@ namespace CtrEditor.ObjetosSim
{ {
if (value is string stringValue) 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; return null;
} }

View File

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

View File

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

View File

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

View File

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