using System; using System.Collections.Generic; using System.Text; using System.Windows; using System.Windows.Controls; using CtrEditor.FuncionesBase; using CtrEditor.Simulacion.Fluids.Components; using nkast.Aether.Physics2D.Common; using CommunityToolkit.Mvvm.ComponentModel; using System.ComponentModel; namespace CtrEditor.ObjetosSim { /// /// Lógica para ucTuberiaFluido.xaml /// public partial class ucTuberiaFluido : UserControl, IDataContainer { public osBase? Datos { get; set; } public int zIndex_fromFrames { get; set; } public ucTuberiaFluido() { 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; } } /// /// ViewModel para la tubería de fluidos /// public partial class osTuberiaFluido : osBase, IosBase { // Tubería en la simulación de fluidos private Tuberia _tuberia; // Referencia al sistema de fluidos private osSistemaFluidos _sistemaFluidos; // Propiedades visuales [ObservableProperty] [property: Description("Diámetro de la tubería en metros")] [property: Category("Dimensiones:")] private float diametro = 0.05f; partial void OnDiametroChanged(float value) { // Actualizar geometría si la tubería ya existe if (_tuberia != null) { // No es posible cambiar el diámetro directamente, recrear la tubería ReconstruirTuberia(); } } [ObservableProperty] [property: Description("Diámetro interno para visualización del fluido")] [property: Category("Visual:")] private float diametroInterno; [ObservableProperty] [property: Description("Color de la tubería")] [property: Category("Visual:")] private System.Windows.Media.Color color = System.Windows.Media.Colors.Gray; [ObservableProperty] [property: Description("Color del fluido")] [property: Category("Visual:")] private System.Windows.Media.Color colorFluido = System.Windows.Media.Colors.CornflowerBlue; [ObservableProperty] [property: Description("Datos del path para dibujar la tubería")] [property: Category("Interno:")] private string pathData; [ObservableProperty] [property: Description("Densidad del fluido (0-1)")] [property: Category("Simulación:")] private double densidadFluido = 0.7; // Lista de puntos que forman la tubería private List _puntos = new List(); // Nombre de la clase para identificación public static string NombreClase() { return "TuberiaFluido"; } private string nombre = NombreClase(); public override string Nombre { get => nombre; set => SetProperty(ref nombre, value); } /// /// Agrega un punto a la tubería /// public void AgregarPunto(float x, float y) { _puntos.Add(new Vector2(x, y)); ActualizarPathData(); // Si la tubería ya está creada, agregar el punto a la simulación if (_tuberia != null) { _tuberia.AgregarPunto(new Vector2(x, y)); } } /// /// Actualiza la representación visual de la tubería /// private void ActualizarPathData() { if (_puntos.Count < 2) return; var converter = new MeterToPixelConverter(); StringBuilder sb = new StringBuilder(); // Iniciar el path sb.Append($"M {converter.Convert(_puntos[0].X, null, null, null)} {converter.Convert(_puntos[0].Y, null, null, null)} "); // Añadir los demás puntos for (int i = 1; i < _puntos.Count; i++) { sb.Append($"L {converter.Convert(_puntos[i].X, null, null, null)} {converter.Convert(_puntos[i].Y, null, null, null)} "); } PathData = sb.ToString(); } /// /// Reconstruye la tubería en la simulación /// private void ReconstruirTuberia() { if (_sistemaFluidos != null) { // Eliminar la tubería existente if (_tuberia != null) { _sistemaFluidos.EliminarComponente(_tuberia); } // Crear nueva tubería _tuberia = _sistemaFluidos.CrearTuberia(Diametro); // Agregar todos los puntos existentes foreach (var punto in _puntos) { _tuberia.AgregarPunto(punto); } } } /// /// Constructor /// public osTuberiaFluido() { DiametroInterno = Diametro * 0.8f; } public override void OnMove(float LeftPixels, float TopPixels) { // Mover todos los puntos de la tubería if (_puntos.Count > 0) { Vector2 delta = new Vector2(Left - CanvasGetLeftinMeter(), Top - CanvasGetTopinMeter()); for (int i = 0; i < _puntos.Count; i++) { _puntos[i] += delta; } ActualizarPathData(); ReconstruirTuberia(); } } public override void ucLoaded() { base.ucLoaded(); // Buscar el sistema de fluidos en la simulación if (_mainViewModel?.ObjetosSimulables != null) { foreach (var obj in _mainViewModel.ObjetosSimulables) { if (obj is osSistemaFluidos sistemaFluidos) { _sistemaFluidos = sistemaFluidos; break; } } } // Si no hay puntos, agregar dos puntos iniciales if (_puntos.Count == 0) { _puntos.Add(new Vector2(Left, Top)); _puntos.Add(new Vector2(Left + Ancho, Top)); ActualizarPathData(); } // Crear la tubería en la simulación ReconstruirTuberia(); } public override void ucUnLoaded() { // Eliminar la tubería de la simulación if (_sistemaFluidos != null && _tuberia != null) { _sistemaFluidos.EliminarComponente(_tuberia); _tuberia = null; } } public override void UpdateControl(int elapsedMilliseconds) { // Actualizar la densidad del fluido basada en la simulación if (_sistemaFluidos != null && _sistemaFluidos._simFluidos != null && _puntos.Count > 0) { // Calcular el centro aproximado de la tubería Vector2 centro = Vector2.Zero; foreach (var punto in _puntos) { centro += punto; } centro /= _puntos.Count; // Obtener densidad en esa posición DensidadFluido = _sistemaFluidos._simFluidos.ObtenerDensidadEnPosicion(centro); } } } }