Add polygon shape

This commit is contained in:
Evgeny Redikultsev
2025-09-14 19:47:23 +05:00
parent c31e56869c
commit 35fccfaa11
56 changed files with 867 additions and 113 deletions

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework> <TargetFramework>net8.0-windows7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0-windows7.0</TargetFramework> <TargetFramework>net8.0-windows7.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<UseWPF>true</UseWPF> <UseWPF>true</UseWPF>
<ImplicitUsings>disable</ImplicitUsings> <ImplicitUsings>disable</ImplicitUsings>

View File

@@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows7.0</TargetFramework> <TargetFramework>net8.0-windows7.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms> <UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>disable</ImplicitUsings> <ImplicitUsings>disable</ImplicitUsings>

View File

@@ -24,6 +24,7 @@
<ResourceDictionary Source="Infrastructure/UI/Resources/ServiceColors.xaml"/> <ResourceDictionary Source="Infrastructure/UI/Resources/ServiceColors.xaml"/>
<ResourceDictionary Source="Infrastructure/UI/Resources/ScrollableWorkPlane.xaml"/> <ResourceDictionary Source="Infrastructure/UI/Resources/ScrollableWorkPlane.xaml"/>
<ResourceDictionary Source="Infrastructure/UI/Resources/BeamShearTemplate.xaml"/> <ResourceDictionary Source="Infrastructure/UI/Resources/BeamShearTemplate.xaml"/>
<ResourceDictionary Source="Infrastructure/UI/Resources/ShapeTemplates.xaml"/>
</ResourceDictionary.MergedDictionaries> </ResourceDictionary.MergedDictionaries>
</ResourceDictionary> </ResourceDictionary>
</Application.Resources> </Application.Resources>

View File

@@ -2,9 +2,10 @@
{ {
public enum PrimitiveType public enum PrimitiveType
{ {
Point, Point = 0,
Rectangle, Rectangle = 1,
Circle, Circle = 2,
Reinforcement Reinforcement = 3,
Polygon = 4
} }
} }

View File

@@ -29,15 +29,9 @@ namespace StructureHelper.Infrastructure.UI.DataContexts
public double PrimitiveLeft => DeltaX - Diameter / 2d; public double PrimitiveLeft => DeltaX - Diameter / 2d;
public double PrimitiveTop => DeltaY - Diameter / 2d; public double PrimitiveTop => DeltaY - Diameter / 2d;
public CircleViewPrimitive(INdmPrimitive primitive) : base(primitive) public CircleViewPrimitive(IEllipseNdmPrimitive primitive) : base(primitive)
{ {
if (primitive is not IEllipseNdmPrimitive) DivisionViewModel = new HasDivisionViewModel(primitive.DivisionSize);
{
throw new StructureHelperException(ErrorStrings.DataIsInCorrect + $"\nExpected: {nameof(IEllipseNdmPrimitive)}, But was: {nameof(primitive)}");
}
var circle = primitive as IEllipseNdmPrimitive;
this.primitive = circle;
DivisionViewModel = new HasDivisionViewModel(circle.DivisionSize);
} }
public override INdmPrimitive GetNdmPrimitive() public override INdmPrimitive GetNdmPrimitive()

View File

@@ -1,13 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelper.Infrastructure.UI.DataContexts
{
internal static class ViewPrimitiveFactory
{
// to do public static PrimitiveBase GetViewPrimitive() { }
}
}

View File

@@ -1,11 +1,5 @@
using System; using StructureHelperLogics.NdmCalculations.Primitives;
using StructureHelper.Infrastructure.Enums; using System;
using StructureHelper.UnitSystem.Systems;
using StructureHelper.Windows.MainWindow;
using StructureHelperLogics.Models.Primitives;
using StructureHelperLogics.Models.Materials;
using StructureHelperCommon.Models.Shapes;
using StructureHelperLogics.NdmCalculations.Primitives;
namespace StructureHelper.Infrastructure.UI.DataContexts namespace StructureHelper.Infrastructure.UI.DataContexts
{ {
@@ -38,10 +32,6 @@ namespace StructureHelper.Infrastructure.UI.DataContexts
public double Diameter { get => Math.Sqrt(primitive.Area / Math.PI) * 2; } public double Diameter { get => Math.Sqrt(primitive.Area / Math.PI) * 2; }
public override INdmPrimitive GetNdmPrimitive()
{
return primitive;
}
public override void Refresh() public override void Refresh()
{ {
RefreshPlacement(); RefreshPlacement();

View File

@@ -25,16 +25,18 @@ namespace StructureHelper.Infrastructure.UI.DataContexts
public static PrimitiveBase ConvertNdmPrimitiveToPrimitiveBase(INdmPrimitive primitive) public static PrimitiveBase ConvertNdmPrimitiveToPrimitiveBase(INdmPrimitive primitive)
{ {
PrimitiveBase viewItem; PrimitiveBase viewItem;
if (primitive is IRectangleNdmPrimitive) if (primitive is IRectangleNdmPrimitive rect)
{ {
var rect = primitive as IRectangleNdmPrimitive;
viewItem = new RectangleViewPrimitive(rect); viewItem = new RectangleViewPrimitive(rect);
} }
else if (primitive is IEllipseNdmPrimitive) else if (primitive is IEllipseNdmPrimitive circle)
{ {
var circle = primitive as IEllipseNdmPrimitive;
viewItem = new CircleViewPrimitive(circle); viewItem = new CircleViewPrimitive(circle);
} }
else if (primitive is IShapeNDMPrimitive shapeNDMPrimitive)
{
viewItem = new ShapeViewPrimitive(shapeNDMPrimitive);
}
else if (primitive is IPointNdmPrimitive & primitive is not RebarNdmPrimitive) else if (primitive is IPointNdmPrimitive & primitive is not RebarNdmPrimitive)
{ {
var point = primitive as IPointNdmPrimitive; var point = primitive as IPointNdmPrimitive;

View File

@@ -0,0 +1,59 @@
using FieldVisualizer.Entities.Values.Primitives;
using StructureHelper.Infrastructure.Enums;
using StructureHelper.Windows.ViewModels.NdmCrossSections;
using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Models.Shapes;
using StructureHelperLogics.NdmCalculations.Primitives;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Windows.Media;
namespace StructureHelper.Infrastructure.UI.DataContexts
{
public class ShapeViewPrimitive : PrimitiveBase
{
IShapeNDMPrimitive shapeNDMPrimitive;
public PathGeometry PathGeometry { get; set; }
public ShapeViewPrimitive(IShapeNDMPrimitive shapeNDMPrimitive) : base(shapeNDMPrimitive)
{
this.shapeNDMPrimitive = shapeNDMPrimitive;
DivisionViewModel = new HasDivisionViewModel(this.shapeNDMPrimitive.DivisionSize);
UpdatePath();
}
public override void Refresh()
{
UpdatePath();
OnPropertyChanged(nameof(CenterX));
OnPropertyChanged(nameof(CenterY));
OnPropertyChanged(nameof(PathGeometry));
base.Refresh();
}
private void UpdatePath()
{
var shape = shapeNDMPrimitive.Shape;
if (shape is not IPolygonShape polygon)
{
throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(shape));
}
var points = polygon.Vertices.Select(x => x.Point).ToList();
if (points.Count == 0) return;
IPoint2D StartPoint = points[0];
System.Windows.Point systemPoint = GetSystemPoint(StartPoint);
var figure = new PathFigure { StartPoint = systemPoint };
for (int i = 1; i < points.Count; i++)
figure.Segments.Add(new LineSegment(GetSystemPoint(points[i]), true));
figure.IsClosed = true;
PathGeometry = new PathGeometry(new[] { figure });
}
private System.Windows.Point GetSystemPoint(IPoint2D helperPoint)
{
return new(DeltaX + shapeNDMPrimitive.Center.X + helperPoint.X, DeltaY - shapeNDMPrimitive.Center.Y - helperPoint.Y);
}
}
}

View File

@@ -0,0 +1,23 @@
<UserControl x:Class="StructureHelper.Infrastructure.UI.DataTemplates.PolygonTemplate"
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:local="clr-namespace:StructureHelper"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:infrastructure="clr-namespace:StructureHelper.Infrastructure"
xmlns:mouseEventTriggers="clr-namespace:StructureHelper.Infrastructure.UI.Triggers.MouseEventTriggers"
xmlns:dataContexts="clr-namespace:StructureHelper.Infrastructure.UI.DataContexts"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance dataContexts:ShapeViewPrimitive}">
<StackPanel>
<Path Style="{StaticResource PolygonStyle}" d:DataContext="{d:DesignInstance dataContexts:ShapeViewPrimitive}">
<Path.RenderTransform>
<TransformGroup>
<TranslateTransform X="{Binding CenterX}" Y="{Binding InvertedCenterY}"/>
<RotateTransform/>
</TransformGroup>
</Path.RenderTransform>
</Path>
</StackPanel>
</UserControl>

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
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.Navigation;
using System.Windows.Shapes;
namespace StructureHelper.Infrastructure.UI.DataTemplates
{
/// <summary>
/// Логика взаимодействия для PolygonTemplate.xaml
/// </summary>
public partial class PolygonTemplate : UserControl
{
public PolygonTemplate()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,44 @@
using StructureHelper.Windows.Shapes;
using StructureHelper.Windows.UserControls;
using StructureHelperCommon.Models.Shapes;
using StructureHelperLogics.NdmCalculations.Primitives;
using System;
using System.Linq;
using System.Windows.Media;
using System.Windows.Shapes;
using PrimitiveVisualProperty = StructureHelperCommon.Models.VisualProperties.PrimitiveVisualProperty;
namespace StructureHelper.Infrastructure.UI.GraphicalPrimitives
{
public class PolygonShapePrimitive : IGraphicalPrimitive
{
private readonly PolygonShapeViewModel polygonShapeViewModel;
public string Name => "Polygon";
public PathGeometry PathGeometry { get; set; }
public PrimitiveVisualPropertyViewModel VisualProperty { get; } = new(new PrimitiveVisualProperty(Guid.Empty));
public PolygonShapePrimitive(PolygonShapeViewModel polygonShapeViewModel)
{
this.polygonShapeViewModel = polygonShapeViewModel;
VisualProperty.Color = (Color)ColorConverter.ConvertFromString("DarkGray");
VisualProperty.FactoredOpacity = 90;
var polygon = polygonShapeViewModel.GetPolygonShape();
var points = polygon.Vertices.Select(x => x.Point).ToList();
if (points.Count == 0) return;
IPoint2D StartPoint = points[0];
System.Windows.Point systemPoint = GetSystemPoint(StartPoint);
var figure = new PathFigure { StartPoint = systemPoint };
for (int i = 1; i < points.Count; i++)
figure.Segments.Add(new LineSegment(GetSystemPoint(points[i]), true));
figure.IsClosed = true;
PathGeometry = new PathGeometry(new[] { figure });
}
private System.Windows.Point GetSystemPoint(IPoint2D helperPoint)
{
return new(helperPoint.X, helperPoint.Y);
}
}
}

View File

@@ -101,9 +101,11 @@
<Color x:Key="ButtonLight" A="255" B="255" G="255" R="255"/> <Color x:Key="ButtonLight" A="255" B="255" G="255" R="255"/>
<Color x:Key="CalculatorColor" A="255" B="149" G="149" R="211"/> <Color x:Key="CalculatorColor" A="255" B="149" G="149" R="211"/>
<Color x:Key="CalculatorFrameColor" A="255" B="109" G="109" R="166"/> <Color x:Key="CalculatorFrameColor" A="255" B="109" G="109" R="166"/>
<Color x:Key="PrimitiveColor" A="255" B="190" G="120" R="120"/>
<Color x:Key="ResultColor" A="255" B="200" G="200" R="200"/> <Color x:Key="ResultColor" A="255" B="200" G="200" R="200"/>
<Color x:Key="ResultFrameColor" A="255" B="100" G="100" R="100"/> <Color x:Key="ResultFrameColor" A="255" B="100" G="100" R="100"/>
<SolidColorBrush x:Key="CalculatorCanvas" Color="{DynamicResource CalculatorColor}"/> <SolidColorBrush x:Key="CalculatorCanvas" Color="{DynamicResource CalculatorColor}"/>
<SolidColorBrush x:Key="PrimitiveCanvas" Color="{DynamicResource PrimitiveColor}"/>
<SolidColorBrush x:Key="CalculatorFrame" Color="{DynamicResource CalculatorFrameColor}"/> <SolidColorBrush x:Key="CalculatorFrame" Color="{DynamicResource CalculatorFrameColor}"/>
<SolidColorBrush x:Key="ResultCanvas" Color="{DynamicResource ResultColor}"/> <SolidColorBrush x:Key="ResultCanvas" Color="{DynamicResource ResultColor}"/>
<SolidColorBrush x:Key="ResultFrame" Color="{DynamicResource ResultFrameColor}"/> <SolidColorBrush x:Key="ResultFrame" Color="{DynamicResource ResultFrameColor}"/>
@@ -117,6 +119,9 @@
<Style x:Key="ButtonCalculatorCanvas" TargetType="Canvas" BasedOn="{StaticResource ButtonCanvas}"> <Style x:Key="ButtonCalculatorCanvas" TargetType="Canvas" BasedOn="{StaticResource ButtonCanvas}">
<Setter Property="Background" Value="{DynamicResource CalculatorCanvas}"/> <Setter Property="Background" Value="{DynamicResource CalculatorCanvas}"/>
</Style> </Style>
<Style x:Key="ButtonPrimitiveCanvas" TargetType="Canvas" BasedOn="{StaticResource ButtonCanvas}">
<Setter Property="Background" Value="{DynamicResource PrimitiveCanvas}"/>
</Style>
<Style x:Key="ButtonResultCanvas" TargetType="Canvas" BasedOn="{StaticResource ButtonCanvas}"> <Style x:Key="ButtonResultCanvas" TargetType="Canvas" BasedOn="{StaticResource ButtonCanvas}">
<Setter Property="Background" Value="{DynamicResource ResultCanvas}"/> <Setter Property="Background" Value="{DynamicResource ResultCanvas}"/>
@@ -525,6 +530,17 @@
</Canvas.Children> </Canvas.Children>
</Canvas> </Canvas>
</DataTemplate> </DataTemplate>
<DataTemplate x:Key="Polygon">
<Canvas Style="{DynamicResource ButtonPrimitiveCanvas}">
<Canvas.Children>
<Path Margin="4" Data="M6,6 l2,2 l6,-6 l6,6 l1,6 l-4,8 l-16,-5
z" Fill="DarkGray" Stroke="Black"/>
<Line X1="16" Y1="3" X2="16" Y2="29" Stroke="Black" StrokeThickness="0.5"/>
<Line X1="3" Y1="16" X2="29" Y2="16" Stroke="Black" StrokeThickness="0.5"/>
</Canvas.Children>
</Canvas>
</DataTemplate>
<DataTemplate x:Key="Prestrain"> <DataTemplate x:Key="Prestrain">
<Canvas Style="{DynamicResource ButtonResultCanvas}"> <Canvas Style="{DynamicResource ButtonResultCanvas}">
<Canvas.Children> <Canvas.Children>
@@ -769,6 +785,59 @@
</Canvas.Children> </Canvas.Children>
</Canvas> </Canvas>
</DataTemplate> </DataTemplate>
<DataTemplate x:Key="TableHeight">
<Canvas Style="{DynamicResource ButtonResultCanvas}">
<Canvas.Children>
<ContentControl ContentTemplate="{DynamicResource ButtonResultRectangle}"/>
<Line X1="4" Y1="7" X2="28" Y2="7" Stroke="Black"/>
<Line X1="4" Y1="10" X2="28" Y2="10" Stroke="Black"/>
<Line X1="4" Y1="13" X2="28" Y2="13" Stroke="DarkGray" StrokeThickness="0.5"/>
<Line X1="4" Y1="16" X2="28" Y2="16" Stroke="DarkGray" StrokeThickness="0.5"/>
<Line X1="4" Y1="19" X2="28" Y2="19" Stroke="DarkGray" StrokeThickness="0.5"/>
<Line X1="4" Y1="22" X2="28" Y2="22" Stroke="DarkGray" StrokeThickness="0.5"/>
<Line X1="4" Y1="25" X2="28" Y2="25" Stroke="DarkGray" StrokeThickness="0.5"/>
<Line X1="12" Y1="7" X2="12" Y2="28" Stroke="Black" StrokeThickness="0.5"/>
<Line X1="17" Y1="7" X2="17" Y2="28" Stroke="Black" StrokeThickness="0.5"/>
<Line X1="22" Y1="7" X2="22" Y2="28" Stroke="Black" StrokeThickness="0.5"/>
</Canvas.Children>
</Canvas>
</DataTemplate>
<DataTemplate x:Key="TableRowAdd">
<Canvas Style="{DynamicResource ButtonResultCanvas}">
<Canvas.Children>
<ContentControl ContentTemplate="{DynamicResource TableHeight}"/>
<Rectangle Canvas.Top="25" Canvas.Left="4" Height="3" Width="24" Fill="Black"/>
</Canvas.Children>
</Canvas>
</DataTemplate>
<DataTemplate x:Key="TableRowAddAfter">
<Canvas Style="{DynamicResource ButtonResultCanvas}">
<Canvas.Children>
<ContentControl ContentTemplate="{DynamicResource TableHeight}"/>
<Rectangle Canvas.Top="16" Canvas.Left="4" Height="3" Width="24" Fill="DarkGray"/>
<Rectangle Canvas.Top="19" Canvas.Left="4" Height="3" Width="24" Fill="Black"/>
</Canvas.Children>
</Canvas>
</DataTemplate>
<DataTemplate x:Key="TableRowAddBefore">
<Canvas Style="{DynamicResource ButtonResultCanvas}">
<Canvas.Children>
<ContentControl ContentTemplate="{DynamicResource TableHeight}"/>
<Rectangle Canvas.Top="16" Canvas.Left="4" Height="3" Width="24" Fill="Black"/>
<Rectangle Canvas.Top="19" Canvas.Left="4" Height="3" Width="24" Fill="DarkGray"/>
</Canvas.Children>
</Canvas>
</DataTemplate>
<DataTemplate x:Key="TableRowDelete">
<Canvas Style="{DynamicResource ButtonResultCanvas}">
<Canvas.Children>
<ContentControl ContentTemplate="{DynamicResource TableHeight}"/>
<Rectangle Canvas.Top="16" Canvas.Left="4" Height="3" Width="24" Fill="Black"/>
<Line X1="4" Y1="13" X2="28" Y2="22" Stroke="Black" StrokeThickness="1"/>
<Line X1="4" Y1="22" X2="28" Y2="13" Stroke="Black" StrokeThickness="1"/>
</Canvas.Children>
</Canvas>
</DataTemplate>
<DataTemplate x:Key="TreeGroup"> <DataTemplate x:Key="TreeGroup">
<Canvas Style="{DynamicResource ButtonResultCanvas}"> <Canvas Style="{DynamicResource ButtonResultCanvas}">
<Canvas.Children> <Canvas.Children>

View File

@@ -1,8 +1,6 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DataTemplate x:Key="RectangleShapeEdit"> <DataTemplate x:Key="RectangleShapeEdit">
<DataTemplate.Resources>
</DataTemplate.Resources>
<Grid> <Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="22"/> <RowDefinition Height="22"/>
@@ -19,8 +17,6 @@
</Grid> </Grid>
</DataTemplate> </DataTemplate>
<DataTemplate x:Key="CircleShapeEdit"> <DataTemplate x:Key="CircleShapeEdit">
<DataTemplate.Resources>
</DataTemplate.Resources>
<Grid> <Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="22"/> <RowDefinition Height="22"/>

View File

@@ -0,0 +1,20 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:primitives="clr-namespace:StructureHelper.Infrastructure.UI.GraphicalPrimitives">
<!-- Polygon template -->
<DataTemplate x:Key="PolygonShapeGraphTemplate"
DataType="primitives:PolygonShapePrimitive">
<Canvas>
<Path
Data ="{Binding PathGeometry}"
Stroke="Black"
StrokeThickness="0.005"
>
<Path.Fill>
<SolidColorBrush Color="{Binding VisualProperty.Color}" Opacity="{Binding VisualProperty.Opacity}"/>
</Path.Fill>
</Path>
</Canvas>
</DataTemplate>
</ResourceDictionary>

View File

@@ -20,6 +20,7 @@
</Style> </Style>
<Style TargetType="{x:Type Shape}" x:Key="ShapeStyle"> <Style TargetType="{x:Type Shape}" x:Key="ShapeStyle">
<Setter Property="Tag" Value="{Binding}"/>
<Setter Property="Fill"> <Setter Property="Fill">
<Setter.Value> <Setter.Value>
<SolidColorBrush Color="{Binding Color}"/> <SolidColorBrush Color="{Binding Color}"/>
@@ -39,6 +40,12 @@
</Style.Triggers> </Style.Triggers>
</Style> </Style>
<Style x:Key="PolygonStyle" TargetType="Path" BasedOn="{StaticResource ShapeStyle}">
<Style.Setters>
<Setter Property="Data" Value="{Binding PathGeometry}"/>
</Style.Setters>
</Style>
<Style x:Key="EllipseStyle" TargetType="Ellipse" BasedOn="{StaticResource ShapeStyle}"> <Style x:Key="EllipseStyle" TargetType="Ellipse" BasedOn="{StaticResource ShapeStyle}">
<Style.Setters> <Style.Setters>
<Setter Property="Width" Value="{Binding Diameter}"/> <Setter Property="Width" Value="{Binding Diameter}"/>

View File

@@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows7.0</TargetFramework> <TargetFramework>net8.0-windows7.0</TargetFramework>
<PublishSingleFile>true</PublishSingleFile> <PublishSingleFile>true</PublishSingleFile>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<UseWPF>true</UseWPF> <UseWPF>true</UseWPF>

View File

@@ -9,6 +9,9 @@
</ApplicationDefinition> </ApplicationDefinition>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Update="Infrastructure\UI\DataTemplates\PolygonTemplate.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Windows\Arrays\ArrayView.xaml.cs"> <Compile Update="Windows\Arrays\ArrayView.xaml.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
@@ -132,6 +135,9 @@
<Compile Update="Windows\Services\CopyByParameterView.xaml.cs"> <Compile Update="Windows\Services\CopyByParameterView.xaml.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Update="Windows\Shapes\PolygonShapeView.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Windows\UserControls\ButtonToolTipEh.xaml.cs"> <Compile Update="Windows\UserControls\ButtonToolTipEh.xaml.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>

View File

@@ -26,6 +26,9 @@
<DataTemplate DataType="{x:Type dataContexts:PointViewPrimitive}"> <DataTemplate DataType="{x:Type dataContexts:PointViewPrimitive}">
<dataTemplates:EllipseTemplate/> <dataTemplates:EllipseTemplate/>
</DataTemplate> </DataTemplate>
<DataTemplate DataType="{x:Type dataContexts:ShapeViewPrimitive}">
<dataTemplates:PolygonTemplate/>
</DataTemplate>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/> <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</Window.Resources> </Window.Resources>
<DockPanel> <DockPanel>
@@ -65,6 +68,16 @@
</Button> </Button>
</ToolBar> </ToolBar>
<ToolBar ToolTip="Base Primitives" DataContext="{Binding PrimitiveLogic}"> <ToolBar ToolTip="Base Primitives" DataContext="{Binding PrimitiveLogic}">
<Button Style="{DynamicResource ToolButton}" Command="{Binding Add}" CommandParameter="{x:Static enums:PrimitiveType.Polygon}" >
<Button.ToolTip>
<uc:ButtonToolTipEh HeaderText="Add polygon primitive"
IconContent="{StaticResource Polygon}"
DescriptionText="Add polygon primitive with default properties into cross-section"/>
</Button.ToolTip>
<Viewbox>
<ContentControl ContentTemplate="{StaticResource Polygon}"/>
</Viewbox>
</Button>
<Button Style="{StaticResource ToolButton}" Command="{Binding Add}" CommandParameter="{x:Static enums:PrimitiveType.Rectangle}" ToolTip="Add Rectangle Primitive"> <Button Style="{StaticResource ToolButton}" Command="{Binding Add}" CommandParameter="{x:Static enums:PrimitiveType.Rectangle}" ToolTip="Add Rectangle Primitive">
<Image Source="/Windows/MainWindow/Rectangle32.png"/> <Image Source="/Windows/MainWindow/Rectangle32.png"/>
</Button> </Button>

View File

@@ -62,43 +62,39 @@ namespace StructureHelper.Windows.ViewModels.NdmCrossSections
INdmPrimitive ndmPrimitive; INdmPrimitive ndmPrimitive;
if (primitiveType == PrimitiveType.Rectangle) if (primitiveType == PrimitiveType.Rectangle)
{ {
var primitive = new RectangleNdmPrimitive RectangleNdmPrimitive primitive = GetNewRectanglePrimitive();
{
Width = 0.4d,
Height = 0.6d
};
ndmPrimitive = primitive; ndmPrimitive = primitive;
viewPrimitive = new RectangleViewPrimitive(primitive); viewPrimitive = new RectangleViewPrimitive(primitive);
} }
else if (primitiveType == PrimitiveType.Reinforcement) else if (primitiveType == PrimitiveType.Reinforcement)
{ {
var primitive = new RebarNdmPrimitive RebarNdmPrimitive primitive = GetNewReinforcementPrimitive();
{
Area = 0.0005d
};
ndmPrimitive = primitive; ndmPrimitive = primitive;
viewPrimitive = new ReinforcementViewPrimitive(primitive); viewPrimitive = new ReinforcementViewPrimitive(primitive);
} }
else if (primitiveType == PrimitiveType.Point) else if (primitiveType == PrimitiveType.Point)
{ {
var primitive = new PointNdmPrimitive PointNdmPrimitive primitive = GetNewPointPrimitive();
{
Area = 0.0005d
};
ndmPrimitive = primitive; ndmPrimitive = primitive;
viewPrimitive = new PointViewPrimitive(primitive); viewPrimitive = new PointViewPrimitive(primitive);
} }
else if (primitiveType == PrimitiveType.Circle) else if (primitiveType == PrimitiveType.Circle)
{ {
var primitive = new EllipseNdmPrimitive EllipseNdmPrimitive primitive = GetNewCirclePrimitive();
{
Width = 0.5d
};
ndmPrimitive = primitive; ndmPrimitive = primitive;
viewPrimitive = new CircleViewPrimitive(primitive); viewPrimitive = new CircleViewPrimitive(primitive);
} }
else { throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknown + nameof(primitiveType)); } else if (primitiveType == PrimitiveType.Polygon)
{
ShapeNdmPrimitive primitive = GetNewPolygonPrimitive();
ndmPrimitive = primitive;
viewPrimitive = new ShapeViewPrimitive(primitive);
}
else
{
throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknown + nameof(primitiveType));
}
viewPrimitive.OnNext(this); viewPrimitive.OnNext(this);
repository.Primitives.Add(ndmPrimitive); repository.Primitives.Add(ndmPrimitive);
ndmPrimitive.CrossSection = section; ndmPrimitive.CrossSection = section;
@@ -107,6 +103,56 @@ namespace StructureHelper.Windows.ViewModels.NdmCrossSections
OnPropertyChanged(nameof(PrimitivesCount)); OnPropertyChanged(nameof(PrimitivesCount));
} }
private ShapeNdmPrimitive GetNewPolygonPrimitive()
{
PolygonShape polygon = new(Guid.NewGuid());
polygon.AddVertex(new Vertex(-0.2, 0.3));
polygon.AddVertex(new Vertex(0.2, 0.3));
polygon.AddVertex(new Vertex(0.1, 0));
polygon.AddVertex(new Vertex(0.2, -0.3));
polygon.AddVertex(new Vertex(-0.2, -0.3));
polygon.AddVertex(new Vertex(-0.1, 0));
ShapeNdmPrimitive shapeNdmPrimitive = new(Guid.NewGuid())
{
Name = "New polygon primitive"
};
shapeNdmPrimitive.SetShape(polygon);
return shapeNdmPrimitive;
}
private static EllipseNdmPrimitive GetNewCirclePrimitive()
{
return new EllipseNdmPrimitive
{
Width = 0.5d
};
}
private static PointNdmPrimitive GetNewPointPrimitive()
{
return new PointNdmPrimitive
{
Area = 0.0005d
};
}
private static RebarNdmPrimitive GetNewReinforcementPrimitive()
{
return new RebarNdmPrimitive
{
Area = 0.0005d
};
}
private static RectangleNdmPrimitive GetNewRectanglePrimitive()
{
return new RectangleNdmPrimitive
{
Width = 0.4d,
Height = 0.6d
};
}
public ICommand Delete public ICommand Delete
{ {
get get
@@ -201,7 +247,7 @@ namespace StructureHelper.Windows.ViewModels.NdmCrossSections
{ {
get get
{ {
return copyCommand ??= new RelayCommand( return copyCommand ??= new RelayCommand(
o => CopySelectedItem(SelectedItem.GetNdmPrimitive()), o => CopySelectedItem(SelectedItem.GetNdmPrimitive()),
o => SelectedItem != null o => SelectedItem != null
); );
@@ -242,19 +288,23 @@ namespace StructureHelper.Windows.ViewModels.NdmCrossSections
newPrimitive.Name += " copy"; newPrimitive.Name += " copy";
repository.Primitives.Add(newPrimitive); repository.Primitives.Add(newPrimitive);
PrimitiveBase primitiveBase; PrimitiveBase primitiveBase;
if (newPrimitive is IRectangleNdmPrimitive) if (newPrimitive is IRectangleNdmPrimitive rectangle)
{ {
primitiveBase = new RectangleViewPrimitive(newPrimitive as IRectangleNdmPrimitive); primitiveBase = new RectangleViewPrimitive(rectangle);
} }
else if (newPrimitive is IEllipseNdmPrimitive) else if (newPrimitive is IEllipseNdmPrimitive ellipse)
{ {
primitiveBase = new CircleViewPrimitive(newPrimitive as IEllipseNdmPrimitive); primitiveBase = new CircleViewPrimitive(ellipse);
}
else if (newPrimitive is IShapeNDMPrimitive shapeNDMPrimitive)
{
primitiveBase = new ShapeViewPrimitive(shapeNDMPrimitive);
} }
else if (newPrimitive is IPointNdmPrimitive) else if (newPrimitive is IPointNdmPrimitive)
{ {
if (newPrimitive is RebarNdmPrimitive) if (newPrimitive is RebarNdmPrimitive rebar)
{ {
primitiveBase = new ReinforcementViewPrimitive(newPrimitive as RebarNdmPrimitive); primitiveBase = new ReinforcementViewPrimitive(rebar);
} }
else else
{ {

View File

@@ -29,6 +29,16 @@
</Grid> </Grid>
</Expander> </Expander>
</DataTemplate> </DataTemplate>
<DataTemplate x:Key="PolygonProperties">
<Grid Height="22">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Polygon properties"/>
<Button Grid.Column="1" Content="Edit polygon" Command="{Binding ShapeEditCommand}"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="PointProperties"> <DataTemplate x:Key="PointProperties">
<Expander Header="Point" IsExpanded="True"> <Expander Header="Point" IsExpanded="True">
<Grid> <Grid>

View File

@@ -1,14 +1,10 @@
using StructureHelper.Infrastructure.Enums; using StructureHelper.Infrastructure.UI.DataContexts;
using StructureHelper.Infrastructure.UI.DataContexts;
using StructureHelper.Windows.ViewModels.PrimitiveProperties; using StructureHelper.Windows.ViewModels.PrimitiveProperties;
using StructureHelperLogics.Models.CrossSections; using StructureHelperLogics.Models.CrossSections;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Data; using System.Windows.Data;
using PointViewPrimitive = StructureHelper.Infrastructure.UI.DataContexts.PointViewPrimitive;
using RectangleViewPrimitive = StructureHelper.Infrastructure.UI.DataContexts.RectangleViewPrimitive;
namespace StructureHelper.Windows.PrimitivePropertiesWindow namespace StructureHelper.Windows.PrimitivePropertiesWindow
{ {
@@ -26,17 +22,15 @@ namespace StructureHelper.Windows.PrimitivePropertiesWindow
viewModel.ParentWindow = this; viewModel.ParentWindow = this;
this.DataContext = viewModel; this.DataContext = viewModel;
InitializeComponent(); InitializeComponent();
if (primitive is RectangleViewPrimitive) { AddPrimitiveProperties(PrimitiveType.Rectangle); } AddPrimitiveProperties();
else if (primitive is CircleViewPrimitive) { AddPrimitiveProperties(PrimitiveType.Circle); }
else if (primitive is PointViewPrimitive) { AddPrimitiveProperties(PrimitiveType.Point); }
else { throw new Exception("Type of object is unknown"); }
} }
private void AddPrimitiveProperties(PrimitiveType type) private void AddPrimitiveProperties()
{ {
List<string> templateNames = new List<string>(); List<string> templateNames = new List<string>();
if (primitive.DivisionViewModel is not null) { templateNames.Add("TriangulationProperties");} if (primitive.DivisionViewModel is not null) { templateNames.Add("TriangulationProperties");}
if (primitive is RectangleViewPrimitive) { templateNames.Add("RectangleProperties"); } if (primitive is RectangleViewPrimitive) { templateNames.Add("RectangleProperties"); }
if (primitive is CircleViewPrimitive) { templateNames.Add("CircleProperties"); } if (primitive is CircleViewPrimitive) { templateNames.Add("CircleProperties"); }
if (primitive is ShapeViewPrimitive) { templateNames.Add("PolygonProperties"); }
if (primitive is PointViewPrimitive) { templateNames.Add("PointProperties"); } if (primitive is PointViewPrimitive) { templateNames.Add("PointProperties"); }
if (primitive is ReinforcementViewPrimitive) { templateNames.Add("ReinforcementProperties"); } if (primitive is ReinforcementViewPrimitive) { templateNames.Add("ReinforcementProperties"); }
foreach (var name in templateNames) foreach (var name in templateNames)

View File

@@ -2,6 +2,7 @@
using StructureHelper.Infrastructure.UI.DataContexts; using StructureHelper.Infrastructure.UI.DataContexts;
using StructureHelper.Models.Materials; using StructureHelper.Models.Materials;
using StructureHelper.Windows.MainWindow.Materials; using StructureHelper.Windows.MainWindow.Materials;
using StructureHelper.Windows.Shapes;
using StructureHelper.Windows.ViewModels.NdmCrossSections; using StructureHelper.Windows.ViewModels.NdmCrossSections;
using StructureHelperCommon.Infrastructures.Exceptions; using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Models.Shapes; using StructureHelperCommon.Models.Shapes;
@@ -23,6 +24,10 @@ namespace StructureHelper.Windows.ViewModels.PrimitiveProperties
{ {
private PrimitiveBase primitive; private PrimitiveBase primitive;
private ICrossSectionRepository sectionRepository; private ICrossSectionRepository sectionRepository;
private RelayCommand shapeEditCommand;
private INdmPrimitive ndmPrimitive => primitive.GetNdmPrimitive();
private IShape shape => ndmPrimitive.Shape;
public ICommand EditColorCommand { get; private set; } public ICommand EditColorCommand { get; private set; }
public ICommand EditMaterialCommand { get; private set; } public ICommand EditMaterialCommand { get; private set; }
@@ -291,21 +296,40 @@ namespace StructureHelper.Windows.ViewModels.PrimitiveProperties
public string Error => throw new NotImplementedException(); public string Error => throw new NotImplementedException();
public ICommand ShapeEditCommand => shapeEditCommand ??= new RelayCommand(ShapeEdit, o => true);
private void ShapeEdit(object obj)
{
if (shape is IPolygonShape polygon)
{
var viewModel = new PolygonShapeViewModel(polygon, new Point2D() { X = CenterX, Y = CenterY});
var window = new PolygonView(viewModel);
window.ShowDialog();
if (window.DialogResult == true)
{
var newPolygon = viewModel.GetPolygonShape();
var updateStrategy = new PolygonShapeUpdateStrategy();
updateStrategy.Update(polygon, newPolygon);
primitive.Refresh();
}
}
else
{
throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(shape));
}
}
public PrimitivePropertiesViewModel(PrimitiveBase primitive, ICrossSectionRepository sectionRepository) public PrimitivePropertiesViewModel(PrimitiveBase primitive, ICrossSectionRepository sectionRepository)
{ {
this.primitive = primitive; this.primitive = primitive;
this.sectionRepository = sectionRepository; this.sectionRepository = sectionRepository;
HeadMaterials = new ObservableCollection<IHeadMaterial>(); HeadMaterials = [.. sectionRepository.HeadMaterials];
foreach (var material in sectionRepository.HeadMaterials)
{
HeadMaterials.Add(material);
}
EditColorCommand = new RelayCommand(o => EditColor(), o => !SetMaterialColor); EditColorCommand = new RelayCommand(o => EditColor(), o => !SetMaterialColor);
EditMaterialCommand = new RelayCommand(o => EditMaterial()); EditMaterialCommand = new RelayCommand(o => EditMaterial());
HostPrimitives = new ObservableCollection<PrimitiveBase>(); HostPrimitives = new ObservableCollection<PrimitiveBase>();
foreach (var item in sectionRepository.Primitives) foreach (var item in sectionRepository.Primitives)
{ {
if (item is RectangleNdmPrimitive || item is EllipseNdmPrimitive) if (item is IHasDivisionSize)
{ {
CheckHost(primitive, item); CheckHost(primitive, item);
HostPrimitives.Add(PrimitiveOperations.ConvertNdmPrimitiveToPrimitiveBase(item)); HostPrimitives.Add(PrimitiveOperations.ConvertNdmPrimitiveToPrimitiveBase(item));

View File

@@ -0,0 +1,29 @@
using StructureHelper.Infrastructure.UI.GraphicalPrimitives;
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models.Shapes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelper.Windows.Shapes.Logics
{
public class PolygonShapeToGraphicPrimitveConvertStrategy : IObjectConvertStrategy<List<IGraphicalPrimitive>, IPolygonShape>
{
private PolygonShapeViewModel polygonShapeViewModel;
public PolygonShapeToGraphicPrimitveConvertStrategy(PolygonShapeViewModel polygonShapeViewModel)
{
this.polygonShapeViewModel = polygonShapeViewModel;
}
public List<IGraphicalPrimitive> Convert(IPolygonShape source)
{
List<IGraphicalPrimitive> primitives = new();
var polygonPrimitive = new PolygonShapePrimitive(polygonShapeViewModel);
primitives.Add(polygonPrimitive);
return primitives;
}
}
}

View File

@@ -0,0 +1,55 @@
using StructureHelper.Infrastructure;
using StructureHelperCommon.Models.Shapes;
using System;
namespace StructureHelper.Windows.Shapes
{
public class Point2DViewModel : ViewModelBase
{
private readonly IPoint2D center;
private readonly IPoint2D point;
public double X
{
get => point.X - center.X;
set
{
try
{
double val = value;
point.X = val + center.X;
}
catch (Exception ex)
{
//Nothing to do
}
}
}
public double Y
{
get => point.Y - center.Y;
set
{
try
{
double val = value;
point.Y = val + center.Y;
}
catch (Exception ex)
{
//Nothing to do
}
}
}
public Point2DViewModel(IPoint2D point, IPoint2D center)
{
this.point = point;
this.center = center;
}
public Point2DViewModel(IPoint2D point) : this (point, new Point2D() { X = 0, Y = 0})
{ }
}
}

View File

@@ -0,0 +1,111 @@
<Window x:Class="StructureHelper.Windows.Shapes.PolygonView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:StructureHelper.Windows.Shapes"
xmlns:uc="clr-namespace:StructureHelper.Windows.UserControls"
xmlns:ucwp="clr-namespace:StructureHelper.Windows.UserControls.WorkPlanes"
d:DataContext="{d:DesignInstance local:PolygonShapeViewModel}"
mc:Ignorable="d"
Title="Polygon" Height="450" Width="800" MinHeight="250" MinWidth="400" MaxHeight="800" MaxWidth="1200" WindowStartupLocation="CenterScreen">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="35"/>
</Grid.RowDefinitions>
<DockPanel>
<ToolBarTray DockPanel.Dock="Top">
<ToolBar>
<Button Style="{StaticResource ToolButton}" Command="{Binding RedrawCommand}">
<Button.ToolTip>
<uc:ButtonToolTipEh HeaderText="Redraw polygon draft"
IconContent="{StaticResource Renew}"
DescriptionText="Redraws draft of polygon"/>
</Button.ToolTip>
<Viewbox>
<ContentControl ContentTemplate="{StaticResource Renew}"/>
</Viewbox>
</Button>
</ToolBar>
<ToolBar Name="Add">
<Button Style="{DynamicResource ToolButton}" Command="{Binding AddVertexCommand}">
<Button.ToolTip>
<uc:ButtonToolTipEh HeaderText="Add vertex"
IconContent="{StaticResource TableRowAdd}"
DescriptionText="Adds new vertex in the and of polygon"/>
</Button.ToolTip>
<Viewbox>
<ContentControl ContentTemplate="{StaticResource TableRowAdd}"/>
</Viewbox>
</Button>
<Button Style="{DynamicResource ToolButton}" Command="{Binding AddVertexBeforeCommand}">
<Button.ToolTip>
<uc:ButtonToolTipEh HeaderText="Add vertex before"
IconContent="{StaticResource TableRowAddBefore}"
DescriptionText="Adds new vertex before selected one"/>
</Button.ToolTip>
<Viewbox>
<ContentControl ContentTemplate="{StaticResource TableRowAddBefore}"/>
</Viewbox>
</Button>
<Button Style="{DynamicResource ToolButton}" Command="{Binding AddVertexAfterCommand}">
<Button.ToolTip>
<uc:ButtonToolTipEh HeaderText="Add vertex after"
IconContent="{StaticResource TableRowAddAfter}"
DescriptionText="Add vertex after selected one"/>
</Button.ToolTip>
<Viewbox>
<ContentControl ContentTemplate="{StaticResource TableRowAddAfter}"/>
</Viewbox>
</Button>
</ToolBar>
<ToolBar Name="Delete">
<Button Style="{DynamicResource ToolButton}" Command="{Binding DeleteVertexCommand}">
<Button.ToolTip>
<uc:ButtonToolTipEh HeaderText="Delete vertex"
IconContent="{StaticResource TableRowDelete}"
DescriptionText="Removes selected vertex"/>
</Button.ToolTip>
<Viewbox>
<ContentControl ContentTemplate="{StaticResource TableRowDelete}"/>
</Viewbox>
</Button>
</ToolBar>
</ToolBarTray>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" MinWidth="100" MaxWidth="250"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel>
<TextBlock Text="Center"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="22"/>
<RowDefinition Height="22"/>
</Grid.RowDefinitions>
<TextBlock Text="x = "/>
<TextBox Grid.Column="1" Margin="2" Text="{Binding Center.X, Converter={StaticResource LengthConverter}, ValidatesOnDataErrors=True}" IsEnabled="False"/>
<TextBlock Grid.Row="1" Text="y = "/>
<TextBox Grid.Column="1" Margin="2" Grid.Row="1" Text="{Binding Center.Y, Converter={StaticResource LengthConverter}, ValidatesOnDataErrors=True}" IsEnabled="False"/>
</Grid>
<DataGrid ItemsSource="{Binding Vertices}" SelectedItem="{Binding SelectedVertex}" AutoGenerateColumns="False"
CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Width="5" Foreground="DarkGray"/>
<DataGridTextColumn Width="100" Header="X" Binding="{Binding Point.X}" CanUserSort="False"/>
<DataGridTextColumn Width="100" Header="Y" Binding="{Binding Point.Y}" CanUserSort="False"/>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
<ucwp:WorkPlaneRoot x:Name="WorkPlaneRootPanel" Grid.Column="1" DataContext="{Binding WorkPlaneRoot}"/>
</Grid>
</DockPanel>
<ContentControl Grid.Row="1" ContentTemplate="{StaticResource OkCancelButtons}" Content="{Binding}"/>
</Grid>
</Window>

View File

@@ -0,0 +1,19 @@
using System.Windows;
namespace StructureHelper.Windows.Shapes
{
/// <summary>
/// Логика взаимодействия для PolygonView.xaml
/// </summary>
public partial class PolygonView : Window
{
private PolygonShapeViewModel viewModel;
public PolygonView(PolygonShapeViewModel viewModel)
{
InitializeComponent();
this.viewModel = viewModel;
viewModel.ParentWindow = this;
this.DataContext = viewModel;
}
}
}

View File

@@ -0,0 +1,131 @@
using StructureHelper.Infrastructure;
using StructureHelper.Infrastructure.UI.GraphicalPrimitives;
using StructureHelper.Windows.Shapes.Logics;
using StructureHelper.Windows.UserControls.WorkPlanes;
using StructureHelper.Windows.ViewModels;
using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models.Shapes;
using StructureHelperLogics.Models.BeamShears;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Input;
namespace StructureHelper.Windows.Shapes
{
public class PolygonShapeViewModel : OkCancelViewModelBase
{
private const int minVertexCount = 3;
private readonly IPoint2D center;
private readonly IPolygonShape polygonShape;
private IObjectConvertStrategy<List<IGraphicalPrimitive>, IPolygonShape> logic;
public Point2DViewModel Center { get; }
public PolygonShapeViewModel(IPolygonShape 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();
public PolygonShapeViewModel(IPolygonShape polygonShape, IPoint2D center)
{
this.polygonShape = polygonShape;
this.center = center;
Center = new(this.center);
foreach (var item in this.polygonShape.Vertices)
{
Vertices.Add(new VertexViewModel(item, this.center));
}
Redraw(null);
}
private RelayCommand addVertexCommand;
public ICommand AddVertexCommand => addVertexCommand ??= new RelayCommand(AddVertex);
public IPolygonShape GetPolygonShape()
{
IPolygonShape polygonShape = new PolygonShape(Guid.NewGuid());
polygonShape.Clear();
foreach (var item in Vertices)
{
Vertex vertex = new(Guid.NewGuid());
vertex.Point.X = item.Point.X;
vertex.Point.Y = item.Point.Y;
polygonShape.AddVertex(vertex);
}
return polygonShape;
}
private void AddVertex(object commandParameter)
{
VertexViewModel vertexViewModel = GetNewVertexViewModel();
Vertices.Add(vertexViewModel);
Redraw(null);
}
private static VertexViewModel GetNewVertexViewModel()
{
Vertex vertex = new(Guid.Empty);
VertexViewModel vertexViewModel = new(vertex);
return vertexViewModel;
}
private RelayCommand redrawCommand;
public ICommand RedrawCommand => redrawCommand ??= new RelayCommand(Redraw);
private void Redraw(object commandParameter)
{
logic = new PolygonShapeToGraphicPrimitveConvertStrategy(this);
WorkPlaneRoot.PrimitiveCollection.Primitives.Clear();
var polygon = GetPolygonShape();
WorkPlaneRoot.PrimitiveCollection.Primitives.Add(logic.Convert(polygon)[0]);
}
private RelayCommand addVertexBeforeCommand;
public ICommand AddVertexBeforeCommand => addVertexBeforeCommand ??= new RelayCommand(AddVertexBefore,
o => SelectedVertex is not null);
private void AddVertexBefore(object commandParameter)
{
int index = CheckVertexExists(SelectedVertex);
VertexViewModel vertexViewModel = GetNewVertexViewModel();
Vertices.Insert(index, vertexViewModel);
Redraw(null);
}
private int CheckVertexExists(VertexViewModel vertex)
{
int index = Vertices.IndexOf(vertex);
if (index == -1)
{
throw new StructureHelperException("The specified vertex was not found in the polygon.");
}
return index;
}
private RelayCommand addVertexAfterCommand;
public ICommand AddVertexAfterCommand => addVertexAfterCommand ??= new RelayCommand(AddVertexAfter,
o => SelectedVertex is not null);
private void AddVertexAfter(object commandParameter)
{
int index = CheckVertexExists(SelectedVertex);
VertexViewModel vertexViewModel = GetNewVertexViewModel();
Vertices.Insert(index+1, vertexViewModel);
Redraw(null);
}
private RelayCommand deleteVertexCommand;
public ICommand DeleteVertexCommand => deleteVertexCommand ??= new RelayCommand(DeleteVertex,
o => SelectedVertex is not null && Vertices.Count >= minVertexCount);
private void DeleteVertex(object commandParameter)
{
if (SelectedVertex is not null)
{
Vertices.Remove(SelectedVertex);
}
Redraw(null);
}
}
}

View File

@@ -0,0 +1,20 @@
using StructureHelper.Infrastructure;
using StructureHelperCommon.Models.Shapes;
namespace StructureHelper.Windows.Shapes
{
public class VertexViewModel : ViewModelBase
{
private readonly IVertex vertex;
public Point2DViewModel Point { get; private set; }
public VertexViewModel(IVertex vertex, IPoint2D center)
{
this.vertex = vertex;
Point = new(this.vertex.Point, center);
}
public VertexViewModel(Vertex vertex) : this(vertex, new Point2D())
{
}
}
}

View File

@@ -61,6 +61,13 @@
<Image Style="{StaticResource ButtonImage16}" Source="/Windows/MainWindow/Circle32.png" /> <Image Style="{StaticResource ButtonImage16}" Source="/Windows/MainWindow/Circle32.png" />
</MenuItem.Icon> </MenuItem.Icon>
</MenuItem> </MenuItem>
<MenuItem Header="Polygon" Command="{Binding Add}" CommandParameter="{x:Static enums:PrimitiveType.Polygon}">
<MenuItem.Icon>
<Viewbox Height="16" Width="16">
<ContentControl ContentTemplate="{StaticResource Polygon}"/>
</Viewbox>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Rebar" Command="{Binding Add}" CommandParameter="{x:Static enums:PrimitiveType.Reinforcement}"> <MenuItem Header="Rebar" Command="{Binding Add}" CommandParameter="{x:Static enums:PrimitiveType.Reinforcement}">
<MenuItem.Icon> <MenuItem.Icon>
<Image Style="{StaticResource ButtonImage16}" Source="/Windows/MainWindow/Rebar32.png" /> <Image Style="{StaticResource ButtonImage16}" Source="/Windows/MainWindow/Rebar32.png" />

View File

@@ -13,6 +13,7 @@ namespace StructureHelper.Windows.UserControls.WorkPlanes
public DataTemplate StirrupByInclinedRebarTemplate { get; set; } public DataTemplate StirrupByInclinedRebarTemplate { get; set; }
public DataTemplate ConcentratedForceTemplate { get; set; } public DataTemplate ConcentratedForceTemplate { get; set; }
public DataTemplate DistributedLoadTemplate { get; set; } public DataTemplate DistributedLoadTemplate { get; set; }
public DataTemplate PolygonShapeTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container) public override DataTemplate SelectTemplate(object item, DependencyObject container)
{ {
@@ -25,6 +26,7 @@ namespace StructureHelper.Windows.UserControls.WorkPlanes
StirrupByInclinedRebarPrimitive => StirrupByInclinedRebarTemplate, StirrupByInclinedRebarPrimitive => StirrupByInclinedRebarTemplate,
ConcentratedForcePrimitive => ConcentratedForceTemplate, ConcentratedForcePrimitive => ConcentratedForceTemplate,
DistributedLoadPrimitive => DistributedLoadTemplate, DistributedLoadPrimitive => DistributedLoadTemplate,
PolygonShapePrimitive => PolygonShapeTemplate,
_ => base.SelectTemplate(item, container) _ => base.SelectTemplate(item, container)
}; };
} }

View File

@@ -89,6 +89,7 @@
StirrupByInclinedRebarTemplate="{StaticResource StirrupByInclinedRebarPrimitiveTemplate}" StirrupByInclinedRebarTemplate="{StaticResource StirrupByInclinedRebarPrimitiveTemplate}"
ConcentratedForceTemplate="{StaticResource ConcentratedForcePrimitiveTemplate}" ConcentratedForceTemplate="{StaticResource ConcentratedForcePrimitiveTemplate}"
DistributedLoadTemplate="{StaticResource DistributedLoadPrimitiveTemplate}" DistributedLoadTemplate="{StaticResource DistributedLoadPrimitiveTemplate}"
PolygonShapeTemplate="{StaticResource PolygonShapeGraphTemplate}"
/> />
</ItemsControl.ItemTemplateSelector> </ItemsControl.ItemTemplateSelector>

View File

@@ -98,7 +98,8 @@ namespace StructureHelperCommon.Infrastructures.Settings
{ {
VersionNumber = 1, VersionNumber = 1,
//SubVersionNumber = 2 //Add Beam shear analysis //SubVersionNumber = 2 //Add Beam shear analysis
SubVersionNumber = 3 //Add stirrup group and inclined rebar //SubVersionNumber = 3 //Add stirrup group and inclined rebar
SubVersionNumber = 4 //Add polygonshape primitive
}; };
} }
} }

View File

@@ -9,6 +9,18 @@ namespace StructureHelperCommon.Models.Shapes
{ {
public static class PolygonGeometryUtils public static class PolygonGeometryUtils
{ {
public static IPolygonShape GetTratsfromedPolygon(IPolygonShape polygon, double dx, double dy)
{
IPolygonShape newPolygon = new PolygonShape(Guid.Empty);
var updateLogic = new PolygonShapeUpdateStrategy();
updateLogic.Update(newPolygon, polygon);
foreach (var item in newPolygon.Vertices)
{
item.Point.X += dx;
item.Point.Y += dy;
}
return newPolygon;
}
public static bool DoPolygonsEdgesIntersect(IPolygonShape polygon) public static bool DoPolygonsEdgesIntersect(IPolygonShape polygon)
{ {
var vertices = polygon.Vertices; var vertices = polygon.Vertices;

View File

@@ -9,7 +9,7 @@ using System.Windows.Shapes;
namespace StructureHelperCommon.Models.Shapes namespace StructureHelperCommon.Models.Shapes
{ {
public class PolygonUpdateStrategy : IUpdateStrategy<IPolygonShape> public class PolygonShapeUpdateStrategy : IUpdateStrategy<IPolygonShape>
{ {
public void Update(IPolygonShape targetObject, IPolygonShape sourceObject) public void Update(IPolygonShape targetObject, IPolygonShape sourceObject)
{ {

View File

@@ -7,7 +7,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace StructureHelperCommon.Models.Shapes.Logics namespace StructureHelperCommon.Models.Shapes
{ {
public class ShapeUpdateStrategy : IUpdateStrategy<IShape> public class ShapeUpdateStrategy : IUpdateStrategy<IShape>
{ {
@@ -24,12 +24,29 @@ namespace StructureHelperCommon.Models.Shapes.Logics
{ {
ProcessCircles(targetObject, sourceCircle); ProcessCircles(targetObject, sourceCircle);
} }
else if (sourceObject is IPolygonShape sourcePolygon)
{
ProcessPolygon(targetObject, sourcePolygon);
}
else else
{ {
throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknown); throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknown);
} }
} }
private void ProcessPolygon(IShape targetObject, IPolygonShape sourcePolygon)
{
if (targetObject is IPolygonShape targetPolygon)
{
var updateLogic = new PolygonShapeUpdateStrategy();
updateLogic.Update(targetPolygon, sourcePolygon);
}
else
{
throw new StructureHelperException(ErrorStrings.DataIsInCorrect + ": target object is not a polygon");
}
}
private static void ProcessCircles(IShape targetObject, ICircleShape sourceCircle) private static void ProcessCircles(IShape targetObject, ICircleShape sourceCircle)
{ {
if (targetObject is ICircleShape targetCircle) if (targetObject is ICircleShape targetCircle)

View File

@@ -10,7 +10,7 @@ namespace StructureHelperCommon.Models.Shapes
public Guid Id { get; } public Guid Id { get; }
public IReadOnlyList<IVertex> Vertices => _vertices; public IReadOnlyList<IVertex> Vertices => _vertices;
public bool IsClosed { get; set; } public bool IsClosed { get; set; } = true;
public PolygonShape(Guid id) public PolygonShape(Guid id)
{ {
@@ -62,7 +62,6 @@ namespace StructureHelperCommon.Models.Shapes
{ {
throw new StructureHelperException("The specified vertex was not found in the polygon."); throw new StructureHelperException("The specified vertex was not found in the polygon.");
} }
return index; return index;
} }

View File

@@ -11,8 +11,17 @@ namespace StructureHelperCommon.Models.Shapes
{ {
Id = id; Id = id;
} }
/// <summary>
/// Creates new vertex with id = new Guid
/// </summary>
/// <param name="x">Coordinate x of vertex</param>
/// <param name="y">Coordinate y of vertex</param>
public Vertex(double x, double y) : this(Guid.NewGuid())
{
Point = new Point2D() { X = x, Y = y };
}
public IPoint2D Point { get; set; } public IPoint2D Point { get; set; } = new Point2D(Guid.NewGuid()) { X = 0, Y = 0};
} }

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework> <TargetFramework>net8.0-windows7.0</TargetFramework>
<ImplicitUsings>disable</ImplicitUsings> <ImplicitUsings>disable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<UseWPF>true</UseWPF> <UseWPF>true</UseWPF>

View File

@@ -27,6 +27,10 @@ namespace StructureHelperLogics.NdmCalculations.Primitives
{ {
new EllipsePrimitiveUpdateStrategy().Update(circle, (EllipseNdmPrimitive)sourceObject); new EllipsePrimitiveUpdateStrategy().Update(circle, (EllipseNdmPrimitive)sourceObject);
} }
else if (targetObject is IShapeNDMPrimitive shapePrimitive)
{
new ShapeNDMPrimitiveUpdateStrategy().Update(shapePrimitive, (IShapeNDMPrimitive)sourceObject);
}
else else
{ {
ErrorCommonProcessor.ObjectTypeIsUnknown(typeof(INdmPrimitive), sourceObject.GetType()); ErrorCommonProcessor.ObjectTypeIsUnknown(typeof(INdmPrimitive), sourceObject.GetType());

View File

@@ -1,12 +1,6 @@
using StructureHelperCommon.Infrastructures.Interfaces; using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models.Shapes; using StructureHelperCommon.Models.Shapes;
using StructureHelperCommon.Models.Shapes.Logics;
using StructureHelperCommon.Services; using StructureHelperCommon.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperLogics.NdmCalculations.Primitives namespace StructureHelperLogics.NdmCalculations.Primitives
{ {

View File

@@ -1,6 +1,5 @@
using StructureHelperCommon.Infrastructures.Interfaces; using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models.Shapes; using StructureHelperCommon.Models.Shapes;
using StructureHelperCommon.Models.Shapes.Logics;
using StructureHelperCommon.Services; using StructureHelperCommon.Services;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -18,12 +17,20 @@ namespace StructureHelperLogics.NdmCalculations.Primitives
public ShapeNDMPrimitiveUpdateStrategy( public ShapeNDMPrimitiveUpdateStrategy(
IUpdateStrategy<INdmPrimitive> basePrimitiveUpdateStrategy, IUpdateStrategy<INdmPrimitive> basePrimitiveUpdateStrategy,
IUpdateStrategy<IDivisionSize> divisionPropsUpdateStrategy, IUpdateStrategy<IShape> shapeUpdateStrategy,
IUpdateStrategy<IShape> shapeUpdateStrategy) IUpdateStrategy<IDivisionSize> divisionPropsUpdateStrategy)
{ {
this.basePrimitiveUpdateStrategy = basePrimitiveUpdateStrategy; this.basePrimitiveUpdateStrategy = basePrimitiveUpdateStrategy;
this.divisionPropsUpdateStrategy = divisionPropsUpdateStrategy;
this.shapeUpdateStrategy = shapeUpdateStrategy; this.shapeUpdateStrategy = shapeUpdateStrategy;
this.divisionPropsUpdateStrategy = divisionPropsUpdateStrategy;
}
public ShapeNDMPrimitiveUpdateStrategy() : this(
new BaseUpdateStrategy(),
new ShapeUpdateStrategy(),
new DivisionSizeUpdateStrategy())
{
} }
public void Update(IShapeNDMPrimitive targetObject, IShapeNDMPrimitive sourceObject) public void Update(IShapeNDMPrimitive targetObject, IShapeNDMPrimitive sourceObject)

View File

@@ -11,7 +11,7 @@ namespace StructureHelperLogics.NdmCalculations.Primitives
{ {
public class RectangleNdmPrimitive : IRectangleNdmPrimitive public class RectangleNdmPrimitive : IRectangleNdmPrimitive
{ {
private readonly RectanglePrimitiveUpdateStrategy updateStrategy = new(); private RectanglePrimitiveUpdateStrategy updateStrategy;
private readonly RectangleShape rectangleShape = new(); private readonly RectangleShape rectangleShape = new();
public Guid Id { get;} public Guid Id { get;}
public string Name { get; set; } public string Name { get; set; }
@@ -43,6 +43,7 @@ namespace StructureHelperLogics.NdmCalculations.Primitives
public object Clone() public object Clone()
{ {
var primitive = new RectangleNdmPrimitive(); var primitive = new RectangleNdmPrimitive();
updateStrategy ??= new();
updateStrategy.Update(primitive, this); updateStrategy.Update(primitive, this);
return primitive; return primitive;
} }

View File

@@ -1,4 +1,6 @@
using LoaderCalculator.Data.Ndms; using LoaderCalculator.Data.Ndms;
using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models.Shapes; using StructureHelperCommon.Models.Shapes;
using StructureHelperLogics.Models.CrossSections; using StructureHelperLogics.Models.CrossSections;
using StructureHelperLogics.NdmCalculations.Triangulations; using StructureHelperLogics.NdmCalculations.Triangulations;
@@ -13,6 +15,7 @@ namespace StructureHelperLogics.NdmCalculations.Primitives
public class ShapeNdmPrimitive : IShapeNDMPrimitive public class ShapeNdmPrimitive : IShapeNDMPrimitive
{ {
private IShape shape; private IShape shape;
private IUpdateStrategy<IShapeNDMPrimitive> updateStrategy;
public Guid Id { get; } public Guid Id { get; }
public string? Name { get; set; } = string.Empty; public string? Name { get; set; } = string.Empty;
@@ -30,7 +33,12 @@ namespace StructureHelperLogics.NdmCalculations.Primitives
public object Clone() public object Clone()
{ {
throw new NotImplementedException(); var primitive = new ShapeNdmPrimitive(Guid.NewGuid());
PolygonShape polygon = new(Guid.NewGuid());
primitive.SetShape(polygon);
updateStrategy ??= new ShapeNDMPrimitiveUpdateStrategy();
updateStrategy.Update(primitive, this);
return primitive;
} }
public IEnumerable<INdm> GetNdms(ITriangulationOptions triangulationOptions) public IEnumerable<INdm> GetNdms(ITriangulationOptions triangulationOptions)
@@ -69,7 +77,16 @@ namespace StructureHelperLogics.NdmCalculations.Primitives
public bool IsPointInside(IPoint2D point) public bool IsPointInside(IPoint2D point)
{ {
throw new NotImplementedException(); if (shape is IPolygonShape polygon)
{
var newShape = PolygonGeometryUtils.GetTratsfromedPolygon(polygon, Center.X, Center.Y);
var calculator = new PolygonCalculator();
return calculator.ContainsPoint(newShape, point);
}
else
{
throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(shape));
}
} }
public void SetShape(IShape shape) public void SetShape(IShape shape)

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework> <TargetFramework>net8.0-windows7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework> <TargetFramework>net8.0-windows7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo> <GenerateAssemblyInfo>false</GenerateAssemblyInfo>