Add polycon shape to field viewer

This commit is contained in:
Evgeny Redikultsev
2025-10-28 22:02:59 +05:00
parent 09dcf4e7e9
commit c84dc47134
12 changed files with 198 additions and 38 deletions

View File

@@ -1,9 +1,5 @@
using StructureHelperCommon.Models.Shapes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FieldVisualizer.Entities.Values.Primitives
{

View File

@@ -241,7 +241,7 @@ namespace FieldVisualizer.ViewModels.FieldViewerViewModels
// Create the PathFigure using triangle vertices.
var figure = new PathFigure
{
StartPoint = new Point(triangle.Point1.X, triangle.Point1.Y),
StartPoint = new Point(triangle.Point1.X, - triangle.Point1.Y),
IsClosed = true,
IsFilled = true
};
@@ -249,8 +249,8 @@ namespace FieldVisualizer.ViewModels.FieldViewerViewModels
// Add the remaining vertices as LineSegments
var segments = new PathSegmentCollection
{
new LineSegment(new Point(triangle.Point2.X, triangle.Point2.Y), true),
new LineSegment(new Point(triangle.Point3.X, triangle.Point3.Y), true)
new LineSegment(new Point(triangle.Point2.X, - triangle.Point2.Y), true),
new LineSegment(new Point(triangle.Point3.X, - triangle.Point3.Y), true)
// Closing is handled by IsClosed = true, so we don't need to add a segment back to Point1
};
figure.Segments = segments;

View File

@@ -1,19 +1,8 @@
using FieldVisualizer.Entities.Values.Primitives;
using FieldVisualizer.Windows.UserControls;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace FieldVisualizer.Windows
{

View File

@@ -53,7 +53,8 @@ namespace StructureHelper.Infrastructure.UI.DataContexts
private System.Windows.Point GetSystemPoint(IPoint2D helperPoint)
{
return new(DeltaX + shapeNDMPrimitive.Center.X + helperPoint.X, DeltaY - shapeNDMPrimitive.Center.Y - helperPoint.Y);
//return new(DeltaX + shapeNDMPrimitive.Center.X + helperPoint.X, DeltaY - shapeNDMPrimitive.Center.Y - helperPoint.Y);
return new(DeltaX + helperPoint.X, DeltaY - helperPoint.Y);
}
}
}

View File

@@ -337,6 +337,15 @@
</Canvas.Children>
</Canvas>
</DataTemplate>
<DataTemplate x:Key="ExportToDxf">
<Canvas Style="{DynamicResource ButtonResultCanvas}">
<Canvas.Children>
<Rectangle Canvas.Left="2" Canvas.Top="2" Width="28" Height="12" Fill="White" Stroke="Black"/>
<TextBlock Text="DXF" FontSize="8" FontWeight="Bold" Margin="4,2,0,2"/>
<TextBlock Text="to" FontSize="12" FontWeight="Bold" FontStyle="Italic" Margin="2,14,0,2"/>
</Canvas.Children>
</Canvas>
</DataTemplate>
<DataTemplate x:Key="ExportToNewAnalysis">
<Canvas Style="{DynamicResource ButtonResultCanvas}">
<Canvas.Children>
@@ -395,6 +404,24 @@
</Canvas.Children>
</Canvas>
</DataTemplate>
<DataTemplate x:Key="FlipVertical">
<Canvas Style="{DynamicResource ButtonResultCanvas}">
<Canvas.Children>
<Line X1="16" Y1="2" X2="16" Y2="30" Stroke="Black" StrokeThickness="0.5"/>
<Path Margin="4" Data="M 15 4 l 9 20 l -9 0 z" Fill="White" Stroke="Black" StrokeThickness="1"/>
<Path Margin="4" Data="M 9 4 l -9 20 l 9 0 z" Fill="DarkGray" Stroke="Black" StrokeThickness="1"/>
</Canvas.Children>
</Canvas>
</DataTemplate>
<DataTemplate x:Key="FlipHorizontal">
<Canvas Style="{DynamicResource ButtonResultCanvas}">
<Canvas.Children>
<Line X1="2" Y1="16" X2="30" Y2="16" Stroke="Black" StrokeThickness="0.5"/>
<Path Margin="4" Data="M 4 15 l 20 9 l 0 -9 z" Fill="White" Stroke="Black" StrokeThickness="1"/>
<Path Margin="4" Data="M 4 9 l 20 -9 l 0 9 z" Fill="DarkGray" Stroke="Black" StrokeThickness="1"/>
</Canvas.Children>
</Canvas>
</DataTemplate>
<DataTemplate x:Key="ForceTable">
<Canvas Style="{DynamicResource ButtonResultCanvas}">
<Canvas.Children>
@@ -444,6 +471,15 @@
</Canvas.Children>
</Canvas>
</DataTemplate>
<DataTemplate x:Key="ImportFromDxf">
<Canvas Style="{DynamicResource ButtonResultCanvas}">
<Canvas.Children>
<Rectangle Canvas.Left="2" Canvas.Top="2" Width="28" Height="12" Fill="White" Stroke="Black"/>
<TextBlock Text="DXF" FontSize="8" FontWeight="Bold" Margin="4,2,0,2"/>
<TextBlock Text="from" FontSize="12" FontWeight="Bold" FontStyle="Italic" Margin="2,14,0,2"/>
</Canvas.Children>
</Canvas>
</DataTemplate>
<DataTemplate x:Key="InteractionDiagram">
<Canvas Style="{DynamicResource ButtonResultCanvas}">
<Canvas.Children>

View File

@@ -2,8 +2,6 @@
using FieldVisualizer.WindowsOperation;
using LoaderCalculator.Data.Matrix;
using LoaderCalculator.Data.Ndms;
using LoaderCalculator.Data.ResultData;
using LoaderCalculator.Logics;
using StructureHelperCommon.Infrastructures.Enums;
using StructureHelperCommon.Models.Shapes;
using StructureHelperCommon.Services;
@@ -11,9 +9,6 @@ using StructureHelperLogics.NdmCalculations.Cracking;
using StructureHelperLogics.NdmCalculations.Triangulations;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelper.Services.ResultViewers
{

View File

@@ -68,6 +68,7 @@
<PackageReference Include="LiveCharts.Wpf.Core" Version="0.9.8" />
<PackageReference Include="LiveCharts.Wpf.NetCore3" Version="0.9.8" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
<PackageReference Include="netDxf" Version="2023.11.10" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="System.Windows.Interactivity.WPF" Version="2.0.20525" />
</ItemGroup>

View File

@@ -12,13 +12,14 @@ namespace StructureHelper.Windows.Shapes
public double X
{
get => point.X - center.X;
get => point.X + center.X;
set
{
try
{
double val = value;
point.X = val + center.X;
point.X = val - center.X;
OnPropertyChanged(nameof(X));
}
catch (Exception ex)
{
@@ -29,13 +30,14 @@ namespace StructureHelper.Windows.Shapes
public double Y
{
get => point.Y - center.Y;
get => point.Y + center.Y;
set
{
try
{
double val = value;
point.Y = val + center.Y;
point.Y = val - center.Y;
OnPropertyChanged(nameof(Y));
}
catch (Exception ex)
{
@@ -44,6 +46,13 @@ namespace StructureHelper.Windows.Shapes
}
}
public void Refresh()
{
OnPropertyChanged(nameof(X));
OnPropertyChanged(nameof(Y));
}
public Point2DViewModel(IPoint2D point, IPoint2D center)
{
this.point = point;

View File

@@ -72,6 +72,50 @@
</Viewbox>
</Button>
</ToolBar>
<ToolBar Name="Flip">
<Button Style="{DynamicResource ToolButton}" Command="{Binding FlipVerticalCommand}">
<Button.ToolTip>
<uc:ButtonToolTipEh HeaderText="Flip vertical"
IconContent="{StaticResource FlipVertical}"
DescriptionText="Flips poligon vertical"/>
</Button.ToolTip>
<Viewbox>
<ContentControl ContentTemplate="{StaticResource FlipVertical}"/>
</Viewbox>
</Button>
<Button Style="{DynamicResource ToolButton}" Command="{Binding FlipHorizontalCommand}">
<Button.ToolTip>
<uc:ButtonToolTipEh HeaderText="Flip horizontal"
IconContent="{StaticResource FlipHorizontal}"
DescriptionText="Flips poligon horizontal"/>
</Button.ToolTip>
<Viewbox>
<ContentControl ContentTemplate="{StaticResource FlipHorizontal}"/>
</Viewbox>
</Button>
</ToolBar>
<ToolBar Name="DxfOperation">
<Button Style="{DynamicResource ToolButton}" Command="{Binding ExportToDxfCommand}">
<Button.ToolTip>
<uc:ButtonToolTipEh HeaderText="Export to *.dxf file"
IconContent="{StaticResource ExportToDxf}"
DescriptionText="Exports poligon to new *.dxf file"/>
</Button.ToolTip>
<Viewbox>
<ContentControl ContentTemplate="{StaticResource ExportToDxf}"/>
</Viewbox>
</Button>
<Button Style="{DynamicResource ToolButton}" Command="{Binding ImportFromDxfCommand}">
<Button.ToolTip>
<uc:ButtonToolTipEh HeaderText="Import from *.dxf file"
IconContent="{StaticResource ImportFromDxf}"
DescriptionText="Imports poligon from *.dxf file"/>
</Button.ToolTip>
<Viewbox>
<ContentControl ContentTemplate="{StaticResource ImportFromDxf}"/>
</Viewbox>
</Button>
</ToolBar>
</ToolBarTray>
<Grid>
<Grid.ColumnDefinitions>

View File

@@ -1,4 +1,7 @@
using StructureHelper.Infrastructure;
using netDxf;
using netDxf.Entities;
using netDxf.Header;
using StructureHelper.Infrastructure;
using StructureHelper.Infrastructure.UI.GraphicalPrimitives;
using StructureHelper.Windows.Shapes.Logics;
using StructureHelper.Windows.UserControls.WorkPlanes;
@@ -18,12 +21,15 @@ namespace StructureHelper.Windows.Shapes
public class PolygonShapeViewModel : OkCancelViewModelBase
{
private const int minVertexCount = 3;
private readonly IPoint2D center;
private readonly IPoint2D absoluteCenter;
private readonly IPoint2D localCenter;
private readonly ILinePolygonShape polygonShape;
private IReadOnlyList<IVertex> vertices => polygonShape.Vertices;
private IObjectConvertStrategy<List<IGraphicalPrimitive>, ILinePolygonShape> logic;
private RelayCommand importFromDxfCommand;
private RelayCommand exportToDxfCommand;
public Point2DViewModel Center { get; }
public PolygonShapeViewModel(ILinePolygonShape polygonShape) : this(polygonShape, new Point2D() { X = 0, Y = 0 }) { }
public VertexViewModel SelectedVertex { get; set; }
public ObservableCollection<VertexViewModel> Vertices { get;} = new();
public WorkPlaneRootViewModel WorkPlaneRoot { get;} = new();
@@ -31,17 +37,85 @@ namespace StructureHelper.Windows.Shapes
public PolygonShapeViewModel(ILinePolygonShape polygonShape, IPoint2D center)
{
this.polygonShape = polygonShape;
this.center = center;
Center = new(this.center);
this.absoluteCenter = center;
this.localCenter = new Point2D();
Center = new(this.absoluteCenter);
ReloadVertices();
Redraw(null);
}
private void ReloadVertices()
{
Vertices.Clear();
foreach (var item in this.polygonShape.Vertices)
{
Vertices.Add(new VertexViewModel(item, this.center));
Vertices.Add(new VertexViewModel(item, localCenter));
}
Redraw(null);
}
private RelayCommand addVertexCommand;
public ICommand AddVertexCommand => addVertexCommand ??= new RelayCommand(AddVertex);
public ICommand FlipVerticalCommand => flipVerticalCommand ??= new RelayCommand(FlipVertical);
public ICommand FlipHorizontalCommand => flipHorizontalCommand ??= new RelayCommand(FlipHorizontal);
public ICommand ImportFromDxfCommand => importFromDxfCommand ??= new RelayCommand(ImportFromDxf);
private void ImportFromDxf(object commandParameter)
{
// your DXF file name
string file = "sample.dxf";
// this check is optional but recommended before loading a DXF file
DxfVersion dxfVersion = DxfDocument.CheckDxfFileVersion(file);
// netDxf is only compatible with AutoCad2000 and higher DXF versions
if (dxfVersion < DxfVersion.AutoCad2000) return;
// load file
DxfDocument loaded = DxfDocument.Load(file);
}
public ICommand ExportToDxfCommand => exportToDxfCommand ??= new RelayCommand(ExportToDxf);
private void ExportToDxf(object commandParameter)
{
// your DXF file name
string file = "sample.dxf";
// create a new document, by default it will create an AutoCad2000 DXF version
DxfDocument doc = new DxfDocument();
// an entity
List<Polyline2DVertex> polylineVertices = [];
foreach (var item in vertices)
{
Polyline2DVertex vertex = new Polyline2DVertex(item.Point.X, item.Point.Y);
polylineVertices.Add(vertex);
}
Polyline2D polyline2D = new Polyline2D(polylineVertices) { IsClosed = true};
//polyline2D.Layer =
// add your entities here
doc.Entities.Add(polyline2D);
// save to file
doc.Save(file);
}
private void FlipHorizontal(object obj)
{
foreach (var item in vertices)
{
item.Point.Y = - item.Point.Y;
}
ReloadVertices();
Redraw(null);
}
private void FlipVertical(object obj)
{
foreach (var item in vertices)
{
item.Point.X = - item.Point.X;
}
ReloadVertices();
Redraw(null);
}
public ILinePolygonShape GetPolygonShape()
{
ILinePolygonShape polygonShape = new LinePolygonShape(Guid.NewGuid());
@@ -49,8 +123,8 @@ namespace StructureHelper.Windows.Shapes
foreach (var item in Vertices)
{
Vertex vertex = new(Guid.NewGuid());
vertex.Point.X = item.Point.X;
vertex.Point.Y = item.Point.Y;
vertex.Point.X = item.Point.X - localCenter.X;
vertex.Point.Y = item.Point.Y - localCenter.Y;
polygonShape.AddVertex(vertex);
}
return polygonShape;
@@ -79,6 +153,10 @@ namespace StructureHelper.Windows.Shapes
WorkPlaneRoot.PrimitiveCollection.Primitives.Clear();
var polygon = GetPolygonShape();
WorkPlaneRoot.PrimitiveCollection.Primitives.Add(logic.Convert(polygon)[0]);
//foreach (var item in Vertices)
//{
// item.Refresh();
//}
}
private RelayCommand addVertexBeforeCommand;
@@ -116,6 +194,9 @@ namespace StructureHelper.Windows.Shapes
}
private RelayCommand deleteVertexCommand;
private RelayCommand flipVerticalCommand;
private RelayCommand flipHorizontalCommand;
public ICommand DeleteVertexCommand => deleteVertexCommand ??= new RelayCommand(DeleteVertex,
o => SelectedVertex is not null && Vertices.Count >= minVertexCount);

View File

@@ -6,13 +6,21 @@ namespace StructureHelper.Windows.Shapes
public class VertexViewModel : ViewModelBase
{
private readonly IVertex vertex;
public Point2DViewModel Point { get; private set; }
public VertexViewModel(IVertex vertex) : this(vertex, new Point2D()) { }
public VertexViewModel(IVertex vertex, IPoint2D center)
{
this.vertex = vertex;
Point = new(this.vertex.Point, center);
}
public void Refresh()
{
Point.Refresh();
}
public VertexViewModel(Vertex vertex) : this(vertex, new Point2D())
{
}

View File

@@ -62,7 +62,7 @@ namespace StructureHelperLogics.NdmCalculations.Triangulations
var contour = new List<TriangleNet.Geometry.Vertex>();
foreach (var vertex in vertices)
{
contour.Add(new TriangleNet.Geometry.Vertex(vertex.Point.X, vertex.Point.Y));
contour.Add(new TriangleNet.Geometry.Vertex(vertex.Point.X + options.Center.X, vertex.Point.Y + options.Center.Y));
}
// Add contour to polygon — this automatically defines the connecting segments