CustomImage con imagen por defecto. Creada visualizcion de tiempo de ciclo. Modificada logica de Preserve_Outside_Transport. Agregada opcion a osFramePlate de showPlate

This commit is contained in:
Miguel 2025-02-24 16:33:27 +01:00
parent 5e95459e3e
commit 621ee8be39
12 changed files with 176 additions and 43 deletions

View File

@ -21,6 +21,7 @@
TargetType="{x:Type osExtraccion:osBuscarCoincidencias}" /> TargetType="{x:Type osExtraccion:osBuscarCoincidencias}" />
<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"/>
</Application.Resources> </Application.Resources>
</Application> </Application>

View File

@ -33,6 +33,10 @@ namespace CtrEditor
private double stopwatch_SimPLC_last; private double stopwatch_SimPLC_last;
private double stopwatch_SimModel_last; private double stopwatch_SimModel_last;
private double accumulatedSimTime;
private double accumulatedPlcTime;
private int simSampleCount;
private int plcSampleCount;
private float TiempoDesdeStartSimulacion; private float TiempoDesdeStartSimulacion;
private bool Debug_SimulacionCreado = false; private bool Debug_SimulacionCreado = false;
@ -41,6 +45,7 @@ namespace CtrEditor
private readonly DispatcherTimer _timerSimulacion; private readonly DispatcherTimer _timerSimulacion;
private readonly DispatcherTimer _timerPLCUpdate; private readonly DispatcherTimer _timerPLCUpdate;
private readonly DispatcherTimer _timerDisplayUpdate;
public Canvas MainCanvas; public Canvas MainCanvas;
@ -327,7 +332,7 @@ namespace CtrEditor
PLCViewModel = new PLCViewModel(); PLCViewModel = new PLCViewModel();
_timerPLCUpdate = new DispatcherTimer(); _timerPLCUpdate = new DispatcherTimer();
_timerPLCUpdate.Interval = TimeSpan.FromMilliseconds(10); // ajusta el intervalo según sea necesario _timerPLCUpdate.Interval = TimeSpan.FromMilliseconds(10); // Restaurado a 10ms
_timerPLCUpdate.Tick += OnRefreshEvent; _timerPLCUpdate.Tick += OnRefreshEvent;
InitializeTipoSimulableList(); InitializeTipoSimulableList();
@ -335,9 +340,15 @@ namespace CtrEditor
ItemDoubleClickCommand = new ParameterizedRelayCommand(ExecuteDoubleClick); ItemDoubleClickCommand = new ParameterizedRelayCommand(ExecuteDoubleClick);
_timerSimulacion = new DispatcherTimer(); _timerSimulacion = new DispatcherTimer();
_timerSimulacion.Interval = TimeSpan.FromMilliseconds(10); // ajusta el intervalo según sea necesario _timerSimulacion.Interval = TimeSpan.FromMilliseconds(10); // Restaurado a 10ms
_timerSimulacion.Tick += OnTickSimulacion; _timerSimulacion.Tick += OnTickSimulacion;
// Nuevo timer para actualización de display
_timerDisplayUpdate = new DispatcherTimer();
_timerDisplayUpdate.Interval = TimeSpan.FromMilliseconds(250);
_timerDisplayUpdate.Tick += OnDisplayUpdate;
_timerDisplayUpdate.Start();
StartSimulationCommand = new RelayCommand(StartSimulation); StartSimulationCommand = new RelayCommand(StartSimulation);
StopSimulationCommand = new RelayCommand(StopSimulation); StopSimulationCommand = new RelayCommand(StopSimulation);
@ -636,6 +647,9 @@ namespace CtrEditor
{ {
IsSimulationRunning = true; IsSimulationRunning = true;
// Ocultar rectángulos de selección antes de iniciar la simulación
_objectManager.UpdateSelectionVisuals();
foreach (var objetoSimulable in ObjetosSimulables) foreach (var objetoSimulable in ObjetosSimulables)
objetoSimulable.UpdateGeometryStart(); objetoSimulable.UpdateGeometryStart();
@ -660,6 +674,9 @@ namespace CtrEditor
Debug_SimulacionCreado = false; Debug_SimulacionCreado = false;
} }
_timerSimulacion.Stop(); _timerSimulacion.Stop();
// Restaurar los rectángulos de selección si hay objetos seleccionados
_objectManager.UpdateSelectionVisuals();
} }
private void OnTickSimulacion(object sender, EventArgs e) private void OnTickSimulacion(object sender, EventArgs e)
@ -670,6 +687,10 @@ namespace CtrEditor
var elapsedMilliseconds = stopwatch_Sim.Elapsed.TotalMilliseconds - stopwatch_SimModel_last; var elapsedMilliseconds = stopwatch_Sim.Elapsed.TotalMilliseconds - stopwatch_SimModel_last;
stopwatch_SimModel_last = stopwatch_Sim.Elapsed.TotalMilliseconds; stopwatch_SimModel_last = stopwatch_Sim.Elapsed.TotalMilliseconds;
// Acumular tiempo para el promedio
accumulatedSimTime += elapsedMilliseconds;
simSampleCount++;
// Eliminar el diseño de Debug luego de 2 segundos // Eliminar el diseño de Debug luego de 2 segundos
if (TiempoDesdeStartSimulacion > 12000) if (TiempoDesdeStartSimulacion > 12000)
simulationManager.Debug_ClearSimulationShapes(); simulationManager.Debug_ClearSimulationShapes();
@ -724,6 +745,10 @@ namespace CtrEditor
var elapsedMilliseconds = stopwatch_Sim.Elapsed.TotalMilliseconds - stopwatch_SimPLC_last; var elapsedMilliseconds = stopwatch_Sim.Elapsed.TotalMilliseconds - stopwatch_SimPLC_last;
stopwatch_SimPLC_last = stopwatch_Sim.Elapsed.TotalMilliseconds; stopwatch_SimPLC_last = stopwatch_Sim.Elapsed.TotalMilliseconds;
// Acumular tiempo para el promedio
accumulatedPlcTime += elapsedMilliseconds;
plcSampleCount++;
// Reiniciar el cronómetro para la próxima medición // Reiniciar el cronómetro para la próxima medición
var remainingObjetosSimulables = ObjetosSimulables.Except(objetosSimulablesLlamados).ToList(); var remainingObjetosSimulables = ObjetosSimulables.Except(objetosSimulablesLlamados).ToList();
@ -897,6 +922,29 @@ namespace CtrEditor
inhibitSaveChangesControl = false; inhibitSaveChangesControl = false;
} }
} }
[ObservableProperty]
private double simulationSpeed;
[ObservableProperty]
private double plcUpdateSpeed;
private void OnDisplayUpdate(object? sender, EventArgs e)
{
if (simSampleCount > 0)
{
SimulationSpeed = accumulatedSimTime / simSampleCount;
accumulatedSimTime = 0;
simSampleCount = 0;
}
if (plcSampleCount > 0)
{
PlcUpdateSpeed = accumulatedPlcTime / plcSampleCount;
accumulatedPlcTime = 0;
plcSampleCount = 0;
}
}
} }
public class SimulationData public class SimulationData
{ {

View File

@ -105,6 +105,7 @@
<ToolBarTray Grid.Row="0"> <ToolBarTray Grid.Row="0">
<ToolBar> <ToolBar>
<StackPanel Orientation="Horizontal">
<Button Command="{Binding TBStartSimulationCommand}" ToolTip="Iniciar Simulación" <Button Command="{Binding TBStartSimulationCommand}" ToolTip="Iniciar Simulación"
Style="{StaticResource StartStopButtonStyle}"> Style="{StaticResource StartStopButtonStyle}">
<StackPanel> <StackPanel>
@ -112,6 +113,19 @@
<TextBlock Text="Iniciar" /> <TextBlock Text="Iniciar" />
</StackPanel> </StackPanel>
</Button> </Button>
<!-- Grid para el indicador de Simulación -->
<Grid Width="15" Margin="2,0">
<TextBlock Text="{Binding SimulationSpeed, StringFormat={}{0:F1}}"
RenderTransformOrigin="0.5,0.5" TextAlignment="Center"
Background="{DynamicResource {x:Static SystemColors.ActiveCaptionBrushKey}}">
<TextBlock.LayoutTransform>
<RotateTransform Angle="-90"/>
</TextBlock.LayoutTransform>
</TextBlock>
</Grid>
</StackPanel>
<Button Command="{Binding TBStopSimulationCommand}" ToolTip="Detener Simulación"> <Button Command="{Binding TBStopSimulationCommand}" ToolTip="Detener Simulación">
<StackPanel> <StackPanel>
<Image Source="Icons/stop.png" Width="24" Height="24" /> <Image Source="Icons/stop.png" Width="24" Height="24" />
@ -124,17 +138,30 @@
<TextBlock Text="Guardar" /> <TextBlock Text="Guardar" />
</StackPanel> </StackPanel>
</Button> </Button>
<StackPanel Orientation="Horizontal">
<Button Command="{Binding TBTogglePLCConnectionCommand}" <Button Command="{Binding TBTogglePLCConnectionCommand}"
ToolTip="{Binding IsConnected, Converter={StaticResource ConnectStateToBtnTextConverter}}" ToolTip="{Binding IsConnected, Converter={StaticResource ConnectStateToBtnTextConverter}}"
Style="{StaticResource ConnectDisconnectButtonStyle}"> Style="{StaticResource ConnectDisconnectButtonStyle}">
<StackPanel> <StackPanel>
<Image <Image Source="{Binding IsConnected, Converter={StaticResource ConnectStateToImageConverter}}"
Source="{Binding IsConnected, Converter={StaticResource ConnectStateToImageConverter}}"
Width="24" Height="24" /> Width="24" Height="24" />
<TextBlock <TextBlock Text="{Binding IsConnected, Converter={StaticResource ConnectStateToBtnTextConverter}}" />
Text="{Binding IsConnected, Converter={StaticResource ConnectStateToBtnTextConverter}}" />
</StackPanel> </StackPanel>
</Button> </Button>
<!-- Grid para el indicador de PLC -->
<Grid Width="15" Margin="2,0">
<TextBlock Text="{Binding PlcUpdateSpeed, StringFormat={}{0:F1}}"
RenderTransformOrigin="0.5,0.5" TextAlignment="Center"
Background="{DynamicResource {x:Static SystemColors.ActiveCaptionBrushKey}}">
<TextBlock.LayoutTransform>
<RotateTransform Angle="-90"/>
</TextBlock.LayoutTransform>
</TextBlock>
</Grid>
</StackPanel>
<Button Command="{Binding TBMultiPageAnalizeCommand}" <Button Command="{Binding TBMultiPageAnalizeCommand}"
ToolTip="Analyze Tags in multiple pages."> ToolTip="Analyze Tags in multiple pages.">
<StackPanel> <StackPanel>

View File

@ -253,7 +253,7 @@ namespace CtrEditor
double minZoomFactor = Math.Min( double minZoomFactor = Math.Min(
ImagenEnTrabajoScrollViewer.ViewportWidth / ImagenEnTrabajoCanvas.ActualWidth, ImagenEnTrabajoScrollViewer.ViewportWidth / ImagenEnTrabajoCanvas.ActualWidth,
ImagenEnTrabajoScrollViewer.ViewportHeight / ImagenEnTrabajoCanvas.ActualHeight)/1.5; ImagenEnTrabajoScrollViewer.ViewportHeight / ImagenEnTrabajoCanvas.ActualHeight) / 1.5;
_targetZoomFactor = e.Delta > 0 ? _targetZoomFactor = e.Delta > 0 ?
_initialZoomFactor * 1.4 : _initialZoomFactor * 1.4 :

View File

@ -133,11 +133,15 @@ namespace CtrEditor
RemoveResizeRectangles(); RemoveResizeRectangles();
if (_selectedObjects.Any()) if (_selectedObjects.Any())
{
// Verificar si la simulación está activa
if (_mainWindow.DataContext is MainViewModel viewModel && !viewModel.IsSimulationRunning)
{ {
AddResizeRectangles(_selectedObjects); AddResizeRectangles(_selectedObjects);
UpdateSelectionHighlights(); UpdateSelectionHighlights();
} }
} }
}
public void SuscribirEventos(UserControl userControl) public void SuscribirEventos(UserControl userControl)
{ {
@ -262,6 +266,7 @@ namespace CtrEditor
private void AddResizeHandles(FuncionesBase.MutableRect rectBox, double defaultRectSize, private void AddResizeHandles(FuncionesBase.MutableRect rectBox, double defaultRectSize,
Cursor rotationCursorRx, Cursor rotationCursorSx) Cursor rotationCursorRx, Cursor rotationCursorSx)
{ {
// Calcular el tamaño apropiado para los manejadores basado en el tamaño del objeto // Calcular el tamaño apropiado para los manejadores basado en el tamaño del objeto
double minObjectDimension = Math.Min(rectBox.Width, rectBox.Height); double minObjectDimension = Math.Min(rectBox.Width, rectBox.Height);
double rectSize = Math.Min(defaultRectSize, minObjectDimension / 3); double rectSize = Math.Min(defaultRectSize, minObjectDimension / 3);
@ -362,6 +367,7 @@ namespace CtrEditor
private void HandleObjectSelection(UserControl userControl, osBase datos) private void HandleObjectSelection(UserControl userControl, osBase datos)
{ {
PurgeDeletedObjects(); PurgeDeletedObjects();
var viewModel = _mainWindow.DataContext as MainViewModel; var viewModel = _mainWindow.DataContext as MainViewModel;
if (viewModel == null) return; if (viewModel == null) return;
@ -493,7 +499,7 @@ namespace CtrEditor
} }
} }
private void RemoveAllSelectionHighlights() public void RemoveAllSelectionHighlights()
{ {
foreach (var pair in _selectionHighlightPairs) foreach (var pair in _selectionHighlightPairs)
{ {

View File

@ -6,8 +6,23 @@
<vm:osCustomImage /> <vm:osCustomImage />
</UserControl.DataContext> </UserControl.DataContext>
<Grid RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<TransformGroup>
<RotateTransform Angle="{Binding Angulo}"/>
</TransformGroup>
</Grid.RenderTransform>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Image Source="{Binding ImageSource_oculta}" <Image Source="{Binding ImageSource_oculta}"
Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}" Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}"
Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}" Stretch="Fill" /> Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}"
Stretch="Fill"
RenderTransformOrigin="0.5,0.5" />
</Grid>
</UserControl> </UserControl>

View File

@ -44,12 +44,19 @@ namespace CtrEditor.ObjetosSim
{ {
ImageSource_oculta = ImageFromPath(value); ImageSource_oculta = ImageFromPath(value);
} }
else
{
// Si no hay path, usar la imagen por defecto
ImageSource_oculta = ImageFromPath("/Icons/unselect.png");
}
} }
public osCustomImage() public osCustomImage()
{ {
Ancho = 0.30f; Ancho = 0.30f;
Alto = 0.30f; Alto = 0.30f;
// Establecer la imagen por defecto al crear el objeto
ImageSource_oculta = ImageFromPath("/Icons/unselect.png");
} }
public override void ucLoaded() public override void ucLoaded()
@ -59,6 +66,11 @@ namespace CtrEditor.ObjetosSim
{ {
ImageSource_oculta = ImageFromPath(ImagePath); ImageSource_oculta = ImageFromPath(ImagePath);
} }
else
{
// Si no hay path al cargar, usar la imagen por defecto
ImageSource_oculta = ImageFromPath("/Icons/unselect.png");
}
} }
} }

View File

@ -22,7 +22,8 @@
<Rectangle Grid.Row="1" Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}" <Rectangle Grid.Row="1" Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}"
Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}" Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}"
Fill="{Binding Color, Converter={StaticResource ColorToBrushConverter}}" Stroke="Blue" Fill="{Binding Color, Converter={StaticResource ColorToBrushConverter}}" Stroke="Blue"
StrokeThickness="0.2" /> StrokeThickness="0.2"
Visibility="{Binding ShowPlate, Converter={StaticResource BooleanToVisibilityConverter}}" />
</Grid> </Grid>
</UserControl> </UserControl>

View File

@ -137,6 +137,11 @@ namespace CtrEditor.ObjetosSim
offsetX = newValue - oldValue; offsetX = newValue - oldValue;
} }
[ObservableProperty]
[property: Description("Show/Hide the plate background")]
[property: Category("Appearance:")]
private bool showPlate;
public osFramePlate() public osFramePlate()
{ {
Ancho = 0.5f; Ancho = 0.5f;
@ -145,6 +150,7 @@ namespace CtrEditor.ObjetosSim
Color = Colors.WhiteSmoke; Color = Colors.WhiteSmoke;
Titulo = "Frame"; Titulo = "Frame";
Zindex_FramePlate = 0; Zindex_FramePlate = 0;
ShowPlate = true; // Default value
} }
public override void ucLoaded() public override void ucLoaded()

View File

@ -124,13 +124,12 @@ namespace CtrEditor.ObjetosSim
} }
public override void UpdateControl(int elapsedMilliseconds) public override void UpdateControl(int elapsedMilliseconds)
{ {
SetCentro(SimGeometria.Center); SetCentro(SimGeometria.Center);
if (SimGeometria.isRestricted) if (SimGeometria.isRestricted)
ColorButton_oculto = Brushes.Yellow; ColorButton_oculto = Brushes.Yellow;
else else
{ {
if (SimGeometria.isOnTransports > 0) if (SimGeometria.IsOnAnyTransport())
ColorButton_oculto = Brushes.Red; ColorButton_oculto = Brushes.Red;
else else
ColorButton_oculto = Brushes.Gray; ColorButton_oculto = Brushes.Gray;
@ -141,7 +140,7 @@ namespace CtrEditor.ObjetosSim
RemoverDesdeSimulacion = true; RemoverDesdeSimulacion = true;
// Eliminar la botella si esta fuera de un transporte // Eliminar la botella si esta fuera de un transporte
if (!Preserve_Outside_Transport && Porcentaje_Traccion == 0 && Math.Abs(SimGeometria.Body.LinearVelocity.X) <= 0.001 && Math.Abs(SimGeometria.Body.LinearVelocity.Y) <= 0.001) if (!Preserve_Outside_Transport && !SimGeometria.IsOnAnyTransport())
RemoverDesdeSimulacion = true; RemoverDesdeSimulacion = true;
Velocidad_desde_simulacion = SimGeometria.Body.LinearVelocity.ToString(); Velocidad_desde_simulacion = SimGeometria.Body.LinearVelocity.ToString();

View File

@ -754,6 +754,11 @@ namespace CtrEditor.Simulacion
return lineStart + projectionLength * lineDirection; return lineStart + projectionLength * lineDirection;
} }
public bool IsOnAnyTransport()
{
return isOnTransports > 0;
}
} }
public class SimulationManagerFP public class SimulationManagerFP

View File

@ -639,4 +639,17 @@ namespace CtrEditor
Scale = newScale; Scale = newScale;
} }
} }
public class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (bool)value ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return (value is Visibility visibility) && visibility == Visibility.Visible;
}
}
} }