Se añadió un nuevo método para verificar si un objeto visual es un hijo visual de otro, mejorando la gestión de transformaciones en la clase osBase. Además, se implementaron mejoras en la obtención de coordenadas de rectángulos, incluyendo validaciones para asegurar que los rectángulos estén cargados y disponibles antes de realizar transformaciones. Se mejoró la lógica de creación de geometría en ucTransporteTTop, asegurando que el layout esté actualizado y manejando excepciones para evitar fallos en la creación de simulaciones.
This commit is contained in:
parent
58781c13a3
commit
fefc0a700d
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
// Use IntelliSense to find out which attributes exist for C# debugging
|
||||||
|
// Use hover for the description of the existing attributes
|
||||||
|
// For further information visit https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md
|
||||||
|
"name": ".NET Core Launch (console)",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "launch",
|
||||||
|
"preLaunchTask": "build",
|
||||||
|
// If you have changed target frameworks, make sure to update the program path.
|
||||||
|
"program": "${workspaceFolder}/bin/Debug/net8.0-windows8.0/CtrEditor.dll",
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
|
||||||
|
"console": "internalConsole",
|
||||||
|
"stopAtEntry": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": ".NET Core Attach",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "attach"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "build",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"build",
|
||||||
|
"${workspaceFolder}/CtrEditor.sln",
|
||||||
|
"/property:GenerateFullPaths=true",
|
||||||
|
"/consoleloggerparameters:NoSummary;ForceNoAlign"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "publish",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"publish",
|
||||||
|
"${workspaceFolder}/CtrEditor.sln",
|
||||||
|
"/property:GenerateFullPaths=true",
|
||||||
|
"/consoleloggerparameters:NoSummary;ForceNoAlign"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "watch",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"watch",
|
||||||
|
"run",
|
||||||
|
"--project",
|
||||||
|
"${workspaceFolder}/CtrEditor.sln"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -26,7 +26,7 @@ namespace CtrEditor.ObjetosSim
|
||||||
return "Transporte";
|
return "Transporte";
|
||||||
}
|
}
|
||||||
private string nombre = "Transporte TTOP";
|
private string nombre = "Transporte TTOP";
|
||||||
|
|
||||||
[property: Category("Id:")]
|
[property: Category("Id:")]
|
||||||
public override string Nombre
|
public override string Nombre
|
||||||
{
|
{
|
||||||
|
@ -77,7 +77,7 @@ namespace CtrEditor.ObjetosSim
|
||||||
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
|
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
|
||||||
string id_Motor;
|
string id_Motor;
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
private PropertyChangedEventHandler motorPropertyChangedHandler;
|
private PropertyChangedEventHandler motorPropertyChangedHandler;
|
||||||
|
|
||||||
partial void OnId_MotorChanged(string value)
|
partial void OnId_MotorChanged(string value)
|
||||||
|
@ -169,8 +169,54 @@ namespace CtrEditor.ObjetosSim
|
||||||
|
|
||||||
if (_visualRepresentation is ucTransporteTTop uc)
|
if (_visualRepresentation is ucTransporteTTop uc)
|
||||||
{
|
{
|
||||||
SimGeometria = AddRectangle(simulationManager, uc.Transporte, Alto, Ancho, Angulo);
|
try
|
||||||
CrearAnimacionStoryBoardTrasnporte(uc.Transporte, InvertirDireccion);
|
{
|
||||||
|
// Asegurar que el layout esté actualizado antes de crear la geometría
|
||||||
|
uc.UpdateLayout();
|
||||||
|
|
||||||
|
// Validar que el rectángulo esté disponible y tenga dimensiones válidas
|
||||||
|
if (uc.Transporte != null &&
|
||||||
|
(!double.IsNaN(uc.Transporte.ActualWidth) && uc.Transporte.ActualWidth > 0) ||
|
||||||
|
(!double.IsNaN(uc.Transporte.Width) && uc.Transporte.Width > 0))
|
||||||
|
{
|
||||||
|
SimGeometria = AddRectangle(simulationManager, uc.Transporte, Alto, Ancho, Angulo);
|
||||||
|
CrearAnimacionStoryBoardTrasnporte(uc.Transporte, InvertirDireccion);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Si el rectángulo no está listo, intentar después del próximo layout
|
||||||
|
uc.Dispatcher.BeginInvoke(new Action(() =>
|
||||||
|
{
|
||||||
|
if (uc.Transporte != null && simulationManager != null)
|
||||||
|
{
|
||||||
|
SimGeometria = AddRectangle(simulationManager, uc.Transporte, Alto, Ancho, Angulo);
|
||||||
|
CrearAnimacionStoryBoardTrasnporte(uc.Transporte, InvertirDireccion);
|
||||||
|
}
|
||||||
|
}), System.Windows.Threading.DispatcherPriority.Loaded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// Log del error para diagnóstico pero continuar sin fallar
|
||||||
|
System.Diagnostics.Debug.WriteLine($"Error al crear geometría de simulación: {ex.Message}");
|
||||||
|
|
||||||
|
// Intentar crear la geometría más tarde
|
||||||
|
uc.Dispatcher.BeginInvoke(new Action(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (uc.Transporte != null && simulationManager != null)
|
||||||
|
{
|
||||||
|
SimGeometria = AddRectangle(simulationManager, uc.Transporte, Alto, Ancho, Angulo);
|
||||||
|
CrearAnimacionStoryBoardTrasnporte(uc.Transporte, InvertirDireccion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex2)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.WriteLine($"Segundo intento falló: {ex2.Message}");
|
||||||
|
}
|
||||||
|
}), System.Windows.Threading.DispatcherPriority.ApplicationIdle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public override void ucUnLoaded()
|
public override void ucUnLoaded()
|
||||||
|
|
|
@ -1364,13 +1364,65 @@ namespace CtrEditor.ObjetosSim
|
||||||
return transformGroup;
|
return transformGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool IsVisualChild(Visual child, Visual parent)
|
||||||
|
{
|
||||||
|
if (child == null || parent == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Intentar obtener el ancestro común
|
||||||
|
var transform = child.TransformToAncestor(parent);
|
||||||
|
return transform != null;
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public (Vector2 TopLeft, Vector2 BottomRight) GetRectangleCoordinatesInMeter(Rectangle rect)
|
public (Vector2 TopLeft, Vector2 BottomRight) GetRectangleCoordinatesInMeter(Rectangle rect)
|
||||||
{
|
{
|
||||||
if (rect != null)
|
if (rect == null)
|
||||||
|
return (new Vector2(0, 0), new Vector2(0, 0));
|
||||||
|
|
||||||
|
var _canvasLeft = CanvasGetLeftinMeter();
|
||||||
|
var _canvasTop = CanvasGetTopinMeter();
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var _canvasLeft = CanvasGetLeftinMeter();
|
// Verificar que tanto el rectángulo como la representación visual estén cargados
|
||||||
var _canvasTop = CanvasGetTopinMeter();
|
if (!rect.IsLoaded || _visualRepresentation == null || !_visualRepresentation.IsLoaded)
|
||||||
|
{
|
||||||
|
// Fallback: usar las propiedades básicas de posición si la transformación no está disponible
|
||||||
|
float rectWidth = (float)rect.Width;
|
||||||
|
float rectHeight = (float)rect.Height;
|
||||||
|
|
||||||
|
if (double.IsNaN(rectWidth) || rectWidth == 0)
|
||||||
|
rectWidth = Ancho * PixelToMeter.Instance.calc.MetersToPixels(1);
|
||||||
|
if (double.IsNaN(rectHeight) || rectHeight == 0)
|
||||||
|
rectHeight = Alto * PixelToMeter.Instance.calc.MetersToPixels(1);
|
||||||
|
|
||||||
|
return (new Vector2(_canvasLeft, _canvasTop),
|
||||||
|
new Vector2(_canvasLeft + PixelToMeter.Instance.calc.PixelsToMeters(rectWidth),
|
||||||
|
_canvasTop + PixelToMeter.Instance.calc.PixelsToMeters(rectHeight)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forzar actualización del layout
|
||||||
|
_visualRepresentation.UpdateLayout();
|
||||||
|
|
||||||
|
// Verificar que el rectángulo sea un descendiente visual de _visualRepresentation
|
||||||
|
if (!IsVisualChild(rect, _visualRepresentation))
|
||||||
|
{
|
||||||
|
// Fallback: usar las dimensiones básicas
|
||||||
|
float rectWidth = (float)rect.ActualWidth;
|
||||||
|
float rectHeight = (float)rect.ActualHeight;
|
||||||
|
|
||||||
|
return (new Vector2(_canvasLeft, _canvasTop),
|
||||||
|
new Vector2(_canvasLeft + PixelToMeter.Instance.calc.PixelsToMeters(rectWidth),
|
||||||
|
_canvasTop + PixelToMeter.Instance.calc.PixelsToMeters(rectHeight)));
|
||||||
|
}
|
||||||
|
|
||||||
// Obtiene la transformada del objeto visual
|
// Obtiene la transformada del objeto visual
|
||||||
GeneralTransform transform = rect.TransformToAncestor(_visualRepresentation);
|
GeneralTransform transform = rect.TransformToAncestor(_visualRepresentation);
|
||||||
|
@ -1379,10 +1431,26 @@ namespace CtrEditor.ObjetosSim
|
||||||
Point topLeft = transform.Transform(new Point(0, 0));
|
Point topLeft = transform.Transform(new Point(0, 0));
|
||||||
Point bottomRight = transform.Transform(new Point(rect.ActualWidth, rect.ActualHeight));
|
Point bottomRight = transform.Transform(new Point(rect.ActualWidth, rect.ActualHeight));
|
||||||
|
|
||||||
return (new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)topLeft.X) + _canvasLeft, PixelToMeter.Instance.calc.PixelsToMeters((float)topLeft.Y) + _canvasTop),
|
return (new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)topLeft.X) + _canvasLeft,
|
||||||
new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)bottomRight.X) + _canvasLeft, PixelToMeter.Instance.calc.PixelsToMeters((float)bottomRight.Y) + _canvasTop));
|
PixelToMeter.Instance.calc.PixelsToMeters((float)topLeft.Y) + _canvasTop),
|
||||||
|
new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)bottomRight.X) + _canvasLeft,
|
||||||
|
PixelToMeter.Instance.calc.PixelsToMeters((float)bottomRight.Y) + _canvasTop));
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException)
|
||||||
|
{
|
||||||
|
// Fallback en caso de error de transformación
|
||||||
|
float rectWidth = (float)rect.ActualWidth;
|
||||||
|
float rectHeight = (float)rect.ActualHeight;
|
||||||
|
|
||||||
|
if (double.IsNaN(rectWidth) || rectWidth == 0)
|
||||||
|
rectWidth = Ancho * PixelToMeter.Instance.calc.MetersToPixels(1);
|
||||||
|
if (double.IsNaN(rectHeight) || rectHeight == 0)
|
||||||
|
rectHeight = Alto * PixelToMeter.Instance.calc.MetersToPixels(1);
|
||||||
|
|
||||||
|
return (new Vector2(_canvasLeft, _canvasTop),
|
||||||
|
new Vector2(_canvasLeft + PixelToMeter.Instance.calc.PixelsToMeters(rectWidth),
|
||||||
|
_canvasTop + PixelToMeter.Instance.calc.PixelsToMeters(rectHeight)));
|
||||||
}
|
}
|
||||||
else return (new Vector2(0, 0), new Vector2(0, 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public (Vector2 Start, Vector2 End) GetCenterLineVectors(Rectangle rect)
|
public (Vector2 Start, Vector2 End) GetCenterLineVectors(Rectangle rect)
|
||||||
|
@ -1396,27 +1464,56 @@ namespace CtrEditor.ObjetosSim
|
||||||
// Usar Dispatcher para asegurar la ejecución en el hilo correcto
|
// Usar Dispatcher para asegurar la ejecución en el hilo correcto
|
||||||
_visualRepresentation?.Dispatcher.Invoke(() =>
|
_visualRepresentation?.Dispatcher.Invoke(() =>
|
||||||
{
|
{
|
||||||
// Asegúrate de que el control está en el árbol visual y actualizado
|
try
|
||||||
if (_visualRepresentation.IsLoaded && rect.IsLoaded)
|
|
||||||
{
|
{
|
||||||
_visualRepresentation.UpdateLayout();
|
// Asegúrate de que el control está en el árbol visual y actualizado
|
||||||
|
if (_visualRepresentation.IsLoaded && rect.IsLoaded && IsVisualChild(rect, _visualRepresentation))
|
||||||
|
{
|
||||||
|
_visualRepresentation.UpdateLayout();
|
||||||
|
|
||||||
|
var _canvasLeft = CanvasGetLeftinMeter();
|
||||||
|
var _canvasTop = CanvasGetTopinMeter();
|
||||||
|
|
||||||
|
var transform = rect.TransformToAncestor(_visualRepresentation);
|
||||||
|
|
||||||
|
// Puntos en coordenadas locales del rectángulo no rotado
|
||||||
|
Point startLocal = new Point(0, rect.ActualHeight / 2);
|
||||||
|
Point endLocal = new Point(rect.ActualWidth, rect.ActualHeight / 2);
|
||||||
|
|
||||||
|
// Transformar estos puntos al sistema de coordenadas del ancestro
|
||||||
|
Point transformedStart = transform.Transform(startLocal);
|
||||||
|
Point transformedEnd = transform.Transform(endLocal);
|
||||||
|
|
||||||
|
// Convierte a unidades de Farseer (metros en este caso)
|
||||||
|
start = new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)transformedStart.X) + _canvasLeft, PixelToMeter.Instance.calc.PixelsToMeters((float)transformedStart.Y) + _canvasTop);
|
||||||
|
end = new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)transformedEnd.X) + _canvasLeft, PixelToMeter.Instance.calc.PixelsToMeters((float)transformedEnd.Y) + _canvasTop);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Fallback: usar coordenadas básicas
|
||||||
|
var _canvasLeft = CanvasGetLeftinMeter();
|
||||||
|
var _canvasTop = CanvasGetTopinMeter();
|
||||||
|
|
||||||
|
float rectWidth = (float)rect.ActualWidth;
|
||||||
|
if (double.IsNaN(rectWidth) || rectWidth == 0)
|
||||||
|
rectWidth = Ancho * PixelToMeter.Instance.calc.MetersToPixels(1);
|
||||||
|
|
||||||
|
start = new Vector2(_canvasLeft, _canvasTop + PixelToMeter.Instance.calc.PixelsToMeters(rectWidth / 2));
|
||||||
|
end = new Vector2(_canvasLeft + PixelToMeter.Instance.calc.PixelsToMeters(rectWidth), _canvasTop + PixelToMeter.Instance.calc.PixelsToMeters(rectWidth / 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException)
|
||||||
|
{
|
||||||
|
// Fallback en caso de error de transformación
|
||||||
var _canvasLeft = CanvasGetLeftinMeter();
|
var _canvasLeft = CanvasGetLeftinMeter();
|
||||||
var _canvasTop = CanvasGetTopinMeter();
|
var _canvasTop = CanvasGetTopinMeter();
|
||||||
|
|
||||||
var transform = rect.TransformToAncestor(_visualRepresentation);
|
float rectWidth = (float)rect.ActualWidth;
|
||||||
|
if (double.IsNaN(rectWidth) || rectWidth == 0)
|
||||||
|
rectWidth = Ancho * PixelToMeter.Instance.calc.MetersToPixels(1);
|
||||||
|
|
||||||
// Puntos en coordenadas locales del rectángulo no rotado
|
start = new Vector2(_canvasLeft, _canvasTop + PixelToMeter.Instance.calc.PixelsToMeters(rectWidth / 2));
|
||||||
Point startLocal = new Point(0, rect.ActualHeight / 2);
|
end = new Vector2(_canvasLeft + PixelToMeter.Instance.calc.PixelsToMeters(rectWidth), _canvasTop + PixelToMeter.Instance.calc.PixelsToMeters(rectWidth / 2));
|
||||||
Point endLocal = new Point(rect.ActualWidth, rect.ActualHeight / 2);
|
|
||||||
|
|
||||||
// Transformar estos puntos al sistema de coordenadas del ancestro
|
|
||||||
Point transformedStart = transform.Transform(startLocal);
|
|
||||||
Point transformedEnd = transform.Transform(endLocal);
|
|
||||||
|
|
||||||
// Convierte a unidades de Farseer (metros en este caso)
|
|
||||||
start = new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)transformedStart.X) + _canvasLeft, PixelToMeter.Instance.calc.PixelsToMeters((float)transformedStart.Y) + _canvasTop);
|
|
||||||
end = new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)transformedEnd.X) + _canvasLeft, PixelToMeter.Instance.calc.PixelsToMeters((float)transformedEnd.Y) + _canvasTop);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue