Add inclined section visualization

This commit is contained in:
RedikultsevEvg
2025-08-07 22:42:46 +05:00
parent 466c57feef
commit 2f6c35482b
56 changed files with 1392 additions and 150 deletions

View File

@@ -3,6 +3,7 @@ using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Materials;
using StructureHelperCommon.Models.Shapes;
using StructureHelperCommon.Models.VisualProperties;
using StructureHelperLogics.Models.BeamShears;
using StructureHelperLogics.Models.Materials;
@@ -15,6 +16,7 @@ namespace DataAccess.DTOs
private IConvertStrategy<ConcreteLibMaterial, ConcreteLibMaterialDTO> concreteConvertStrategy;
private IConvertStrategy<ReinforcementLibMaterial, ReinforcementLibMaterialDTO> reinforcementConvertStrategy;
private IUpdateStrategy<IHelperMaterial> safetyFactorUpdateStrategy;
private IUpdateStrategy<IHasVisualProperty> visualUpdateStrategy;
public BeamShearSectionFromDTOConvertStrategy(Dictionary<(Guid id, Type type), ISaveable> referenceDictionary, IShiftTraceLogger traceLogger) : base(referenceDictionary, traceLogger)
@@ -38,6 +40,7 @@ namespace DataAccess.DTOs
throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(source.ReinforcementMaterial));
}
NewItem.ReinforcementMaterial = reinforcementConvertStrategy.Convert(reinforcement);
visualUpdateStrategy.Update(NewItem, source);
return NewItem;
}
@@ -57,6 +60,7 @@ namespace DataAccess.DTOs
TraceLogger = TraceLogger
};
safetyFactorUpdateStrategy = new HelperMaterialDTOSafetyFactorUpdateStrategy(new MaterialSafetyFactorsFromDTOLogic());
visualUpdateStrategy = new HasVisualPropertyFromDTOUpdateStrategy(ReferenceDictionary, TraceLogger);
}
}
}

View File

@@ -2,6 +2,7 @@
using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Materials;
using StructureHelperCommon.Models.Shapes;
using StructureHelperCommon.Models.VisualProperties;
using StructureHelperLogics.Models.BeamShears;
using StructureHelperLogics.Models.Materials;
@@ -14,6 +15,7 @@ namespace DataAccess.DTOs
private IConvertStrategy<ConcreteLibMaterialDTO, IConcreteLibMaterial> concreteConvertStrategy;
private ReinforcementLibMaterialToDTOConvertStrategy reinforcementConvertStrategy;
private IUpdateStrategy<IHelperMaterial> safetyFactorUpdateStrategy;
private IUpdateStrategy<IHasVisualProperty> visualUpdateStrategy;
public BeamShearSectionToDTOConvertStrategy(Dictionary<(Guid id, Type type), ISaveable> referenceDictionary, IShiftTraceLogger traceLogger)
: base(referenceDictionary, traceLogger)
@@ -46,6 +48,7 @@ namespace DataAccess.DTOs
NewItem.ReinforcementMaterial = reinforcementConvertStrategy.Convert(source.ReinforcementMaterial);
safetyFactorUpdateStrategy.Update(NewItem.ReinforcementMaterial, source.ReinforcementMaterial);
TraceLogger?.AddMessage($"Beam shear section converting Id = {NewItem.Id} has been finished succesfully", TraceLogStatuses.Debug);
visualUpdateStrategy.Update(NewItem, source);
}
private void InitializeStrategies()
@@ -62,6 +65,7 @@ namespace DataAccess.DTOs
TraceLogger = TraceLogger
};
safetyFactorUpdateStrategy = new HelperMaterialDTOSafetyFactorUpdateStrategy(new MaterialSafetyFactorToDTOLogic());
visualUpdateStrategy = new HasVisualPropertyToDTOUpdateStrategy(ReferenceDictionary, TraceLogger);
}
}
}

View File

@@ -11,6 +11,7 @@ namespace DataAccess.DTOs
private IShiftTraceLogger traceLogger;
private IConvertStrategy<PrimitiveVisualPropertyDTO, IPrimitiveVisualProperty> convertStrategy;
public HasVisualPropertyToDTOUpdateStrategy(Dictionary<(Guid id, Type type), ISaveable> referenceDictionary, IShiftTraceLogger traceLogger)
{
this.referenceDictionary = referenceDictionary;

View File

@@ -1,7 +1,9 @@
using Newtonsoft.Json;
using StructureHelperCommon.Models.Shapes;
using StructureHelperCommon.Models.VisualProperties;
using StructureHelperLogics.Models.BeamShears;
using StructureHelperLogics.Models.Materials;
using System.Windows.Media;
//Copyright (c) 2025 Redikultsev Evgeny, Ekaterinburg, Russia
//All rights reserved.
@@ -24,10 +26,15 @@ namespace DataAccess.DTOs
public double ReinforcementArea { get; set; }
[JsonProperty("ReinforcementMaterial")]
public IReinforcementLibMaterial ReinforcementMaterial { get; set; } = new ReinforcementLibMaterial(Guid.NewGuid());
public IPrimitiveVisualProperty VisualProperty { get; set; }
public BeamShearSectionDTO(Guid id)
{
Id = id;
VisualProperty = new PrimitiveVisualPropertyDTO(Guid.NewGuid())
{
Color = (Color)ColorConverter.ConvertFromString("DarkGray")
};
}
public object Clone()

View File

@@ -36,7 +36,7 @@ namespace DataAccess.DTOs
Id = id;
VisualProperty = new PrimitiveVisualPropertyDTO(Guid.NewGuid())
{
Color = (Color)ColorConverter.ConvertFromString("Black")
Color = (Color)ColorConverter.ConvertFromString("Brown")
};
}

View File

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

View File

@@ -0,0 +1,38 @@
using StructureHelperCommon.Models.VisualProperties;
using StructureHelperLogics.Models.BeamShears;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelper.Infrastructure.UI.GraphicalPrimitives
{
public class BeamShearSectionPrimitive : IGraphicalPrimitive
{
private IBeamShearSection beamShearSection;
private IInclinedSection inclinedSection;
public double CenterX { get; set; } = 0;
public double CenterY { get; set; } = 0;
public double FullDepth => inclinedSection.FullDepth;
public double EffectiveDepth => inclinedSection.EffectiveDepth;
public double BottomCover => FullDepth - EffectiveDepth;
public double PositiveLength => inclinedSection.EffectiveDepth * 3.5;
public double NegativeLength { get; set; } = -0.1;
public double SupportHeight { get; set; } = 0.1;
public double SupportWidth { get; set; } = 0.2;
public double SupportStartX => -SupportWidth / 2;
public double SupportStartY => -SupportHeight;
public string SupportPathData => $"M 0 0 L {SupportWidth / 2} {-SupportHeight} L {-SupportWidth / 2} {-SupportHeight} Z";
public IPrimitiveVisualProperty VisualProperty => beamShearSection.VisualProperty;
public BeamShearSectionPrimitive(IBeamShearSection beamShearSection, IInclinedSection inclinedSection)
{
this.beamShearSection = beamShearSection;
this.inclinedSection = inclinedSection;
}
}
}

View File

@@ -0,0 +1,15 @@
using FieldVisualizer.Entities.Values.Primitives;
using StructureHelperCommon.Models.VisualProperties;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelper.Infrastructure.UI.GraphicalPrimitives
{
public interface IGraphicalPrimitive : ICenter
{
IPrimitiveVisualProperty VisualProperty { get; }
}
}

View File

@@ -0,0 +1,39 @@
using StructureHelperCommon.Models.VisualProperties;
using StructureHelperLogics.Models.BeamShears;
using System;
using System.Windows.Media;
namespace StructureHelper.Infrastructure.UI.GraphicalPrimitives
{
public class InclinedSectionPrimitive : IGraphicalPrimitive
{
private IBeamShearSectionLogicResult source;
private IInclinedSection inclinedSection => source.InputData.InclinedSection;
public double SectionStartX => inclinedSection.StartCoord;
public double SectionEndX => inclinedSection.EndCoord;
public double SectionStartY => inclinedSection.FullDepth - inclinedSection.EffectiveDepth;
public double SectionEndY => inclinedSection.FullDepth;
public double FactorOfUsing => source.FactorOfUsing;
public double EffectiveDepth => inclinedSection.EffectiveDepth;
public double SpanRatio => (inclinedSection.EndCoord - inclinedSection.StartCoord) / inclinedSection.EffectiveDepth;
public double CenterX => 0;
public double CenterY => 0;
public IPrimitiveVisualProperty VisualProperty { get; private set; } = new PrimitiveVisualProperty(Guid.Empty);
public InclinedSectionPrimitive(IBeamShearSectionLogicResult source)
{
this.source = source;
if (source.FactorOfUsing >= 1)
{
VisualProperty.Color = (Color)ColorConverter.ConvertFromString("Red");
}
else
{
VisualProperty.Color = (Color)ColorConverter.ConvertFromString("Green");
}
}
}
}

View File

@@ -0,0 +1,117 @@
<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"
>
<!-- Beam shear section -->
<DataTemplate x:Key="BeamShearSectionPrimitiveTemplate"
DataType="primitives:BeamShearSectionPrimitive">
<Canvas>
<Rectangle
Width="{Binding PositiveLength}"
Height="{Binding FullDepth}"
Stroke="Black"
StrokeThickness="0.02"
>
<Rectangle.Fill>
<SolidColorBrush Color="{Binding VisualProperty.Color}" Opacity="{Binding VisualProperty.Opacity}"/>
</Rectangle.Fill>
<Rectangle.ToolTip>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<TextBlock Text="Beam shear section"/>
<TextBlock Grid.Row="1" Text="Full depth"/>
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding FullDepth, Converter={StaticResource LengthConverter}}"/>
<TextBlock Grid.Row="2" Text="Effective depth"/>
<TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding EffectiveDepth, Converter={StaticResource LengthConverter}}"/>
</Grid>
</Rectangle.ToolTip>
</Rectangle>
<Line
X1="0"
X2="{Binding PositiveLength}"
Y1="{Binding BottomCover}"
Y2="{Binding BottomCover}"
Stroke="DarkGray"
StrokeThickness="0.02"
/>
<Rectangle
Canvas.Left="{Binding SupportStartX}"
Canvas.Top="{Binding SupportStartY}"
Width="{Binding SupportWidth}"
Height="{Binding SupportHeight}"
Fill="LightGray"
Stroke="Black"
StrokeThickness="0.01"
/>
<Path
Data ="M 0 0 L 0.1 -0.1 L -0.1 -0.1 Z"
Fill="DarkGray"
Stroke="Black"
StrokeThickness="0.005"
/>
</Canvas>
</DataTemplate>
<DataTemplate x:Key="InclinedSectionPrimitiveTemplate"
DataType="primitives:InclinedSectionPrimitive">
<Canvas>
<Line
X1="{Binding SectionStartX}"
X2="{Binding SectionEndX}"
Y1="{Binding SectionStartY}"
Y2="{Binding SectionEndY}"
StrokeThickness="0.02"
>
<Line.Stroke>
<SolidColorBrush Color="{Binding VisualProperty.Color}" Opacity="{Binding VisualProperty.Opacity}"/>
</Line.Stroke>
<Line.ToolTip>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<TextBlock Text="Inclinated section"/>
<TextBlock Grid.Row="1" Text="Start coordinate"/>
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding SectionStartX, Converter={StaticResource LengthConverter}}"/>
<TextBlock Grid.Row="2" Text="End coordinate"/>
<TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding SectionEndX, Converter={StaticResource LengthConverter}}"/>
<TextBlock Grid.Row="3" Text="Factor of using"/>
<TextBlock Grid.Row="3" Grid.Column="1" Text="{Binding FactorOfUsing, Converter={StaticResource PlainDouble}}"/>
<TextBlock Grid.Row="4" Text="Effective depth"/>
<TextBlock Grid.Row="4" Grid.Column="1" Text="{Binding EffectiveDepth, Converter={StaticResource LengthConverter}}"/>
<TextBlock Grid.Row="5" Text="Span c/d ratio"/>
<TextBlock Grid.Row="5" Grid.Column="1" Text="{Binding SpanRatio, Converter={StaticResource PlainDouble}}"/>
</Grid>
</Line.ToolTip>
</Line>
<Line
X1="{Binding SectionStartX}"
X2="{Binding SectionStartX}"
Y1="0"
Y2="{Binding SectionStartY}"
StrokeThickness="0.02"
>
<Line.Stroke>
<SolidColorBrush Color="{Binding VisualProperty.Color}" Opacity="{Binding VisualProperty.Opacity}"/>
</Line.Stroke>
</Line>
</Canvas>
</DataTemplate>
</ResourceDictionary>

View File

@@ -170,6 +170,15 @@
</Canvas>
</DataTemplate>
<DataTemplate x:Key="BeamShearInclinedSection">
<Canvas Style="{DynamicResource ButtonResultCanvas}">
<Canvas.Children>
<Path Data="M2,26 v-8 h10 v2 l-8,6 z" Fill="DarkGray" Stroke="Black" StrokeThickness="1"/>
<Path Data="M14,22 v-2 h16 v8 h-24 z" Fill="DarkGray" Stroke="Black" StrokeThickness="1"/>
</Canvas.Children>
</Canvas>
</DataTemplate>
<DataTemplate x:Key="ButtonCalculatorRectangle">
<Rectangle Style="{DynamicResource ButtonRect}" Stroke="{DynamicResource CalculatorFrame}">
<Rectangle.Fill>

View File

@@ -33,6 +33,9 @@
<Compile Update="Windows\BeamShears\DistributedLoadView.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Windows\BeamShears\InclinedSectionViewerView.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Windows\BeamShears\SectionView.xaml.cs">
<SubType>Code</SubType>
</Compile>
@@ -144,9 +147,21 @@
<Compile Update="Windows\UserControls\MultiplyDouble.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Windows\UserControls\PrimitiveVisualProperty.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Windows\UserControls\WorkPlane.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Windows\UserControls\WorkPlanes\AxisLayer.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Windows\UserControls\WorkPlanes\GridLayer.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Windows\UserControls\WorkPlanes\WorkPlaneRoot.xaml.cs">
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Page Update="Infrastructure\UI\Resources\ContextMenus.xaml">

View File

@@ -31,6 +31,16 @@
<ContentControl ContentTemplate="{StaticResource MomentCurvatureDiagram}"/>
</Viewbox>
</Button>
<Button Style="{DynamicResource ToolButton}" Command="{Binding ShowGraphResultsCommand}">
<Button.ToolTip>
<uc:ButtonToolTipEh HeaderText="Show inclined section"
IconContent="{StaticResource BeamShearInclinedSection}"
DescriptionText="Shows graphical results for inclined section"/>
</Button.ToolTip>
<Viewbox>
<ContentControl ContentTemplate="{StaticResource BeamShearInclinedSection}"/>
</Viewbox>
</Button>
</ToolBar>
</ToolBarTray>
<Grid>

View File

@@ -12,6 +12,7 @@ namespace StructureHelper.Windows.BeamShears
private IBeamShearActionResult result;
private RelayCommand showTraceCommand;
private RelayCommand showDiagramCommand;
private RelayCommand showGraphResultsCommand;
public IBeamShearSectionLogicResult SelectedResult { get; set; }
public List<IBeamShearSectionLogicResult> SectionResults => result.SectionResults;
@@ -25,6 +26,13 @@ namespace StructureHelper.Windows.BeamShears
public ICommand ShowTraceCommand => showTraceCommand ??= new RelayCommand(ShowTrace, o => SelectedResult != null);
public ICommand ShowDiagramCommand => showDiagramCommand ??= new RelayCommand(Show2DDiagram, o => SelectedResult != null);
public ICommand ShowGraphResultsCommand => showGraphResultsCommand ??= new RelayCommand(ShowGraphResults, o => SelectedResult != null);
private void ShowGraphResults(object obj)
{
var window = new InclinedSectionViewerView(SelectedResult);
window.ShowDialog();
}
private void ShowTrace(object obj)
{

View File

@@ -41,6 +41,16 @@
<ContentControl ContentTemplate="{StaticResource ExportToXLS}"/>
</Viewbox>
</Button>
<Button Style="{DynamicResource ToolButton}" Command="{Binding ShowGraphResultsCommand}">
<Button.ToolTip>
<uc:ButtonToolTipEh HeaderText="Show inclined section"
IconContent="{StaticResource BeamShearInclinedSection}"
DescriptionText="Shows graphical results for inclined section where factor of using is maximum"/>
</Button.ToolTip>
<Viewbox>
<ContentControl ContentTemplate="{StaticResource BeamShearInclinedSection}"/>
</Viewbox>
</Button>
</ToolBar>
</ToolBarTray>
<Grid>

View File

@@ -2,9 +2,8 @@
using StructureHelper.Services.Exports;
using StructureHelper.Windows.CalculationWindows.CalculatorsViews;
using StructureHelperLogics.Models.BeamShears;
using StructureHelperLogics.NdmCalculations.Analyses;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Input;
@@ -16,6 +15,7 @@ namespace StructureHelper.Windows.BeamShears
private RelayCommand showSectionResultsCommand;
private RelayCommand showDiagramCommand;
private RelayCommand exportToExcelCommand;
private RelayCommand showGraphResultsCommand;
public IBeamShearActionResult SelectedResult { get; set; }
public List<IBeamShearActionResult> ActionResults => result.ActionResults;
@@ -28,8 +28,22 @@ namespace StructureHelper.Windows.BeamShears
}
public ICommand ShowSectionResultsCommand => showSectionResultsCommand ??= new RelayCommand(ShowSectionResults, o=>SelectedResult != null);
public ICommand ShowDiagramCommand => showDiagramCommand ??= new RelayCommand(Show2DDiagram, o=>SelectedResult != null);
public ICommand ExportToExcelCommand => exportToExcelCommand ??= new RelayCommand(ExportToExcel, o=>SelectedResult != null);
public ICommand ShowGraphResultsCommand => showGraphResultsCommand ??= new RelayCommand(ShowGraphResults, o => SelectedResult != null);
private void ShowGraphResults(object obj)
{
if (SelectedResult is null) {return; }
if (SelectedResult.SectionResults is null) {return; }
var sectionResult = SelectedResult.SectionResults
.OrderByDescending(x => x.FactorOfUsing)
.FirstOrDefault();
var window = new InclinedSectionViewerView(sectionResult);
window.ShowDialog();
}
private void ExportToExcel(object obj)
{

View File

@@ -0,0 +1,14 @@
<Window x:Class="StructureHelper.Windows.BeamShears.InclinedSectionViewerView"
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.BeamShears"
xmlns:ucwp="clr-namespace:StructureHelper.Windows.UserControls.WorkPlanes"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance local:InclinedSectionViewerViewModel}"
Title="Inclined Section Viewer" Height="650" Width="1000" WindowStartupLocation="CenterScreen">
<Grid DataContext="{Binding WorkPlaneRoot}">
<ucwp:WorkPlaneRoot/>
</Grid>
</Window>

View File

@@ -0,0 +1,35 @@
using StructureHelperLogics.Models.BeamShears;
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.Shapes;
namespace StructureHelper.Windows.BeamShears
{
/// <summary>
/// Логика взаимодействия для InclinedSectionViewerView.xaml
/// </summary>
public partial class InclinedSectionViewerView : Window
{
private InclinedSectionViewerViewModel viewModel;
public InclinedSectionViewerView(InclinedSectionViewerViewModel viewModel)
{
InitializeComponent();
this.viewModel = viewModel;
this.DataContext = this.viewModel;
}
public InclinedSectionViewerView(IBeamShearSectionLogicResult sectionResult) : this(new InclinedSectionViewerViewModel(sectionResult))
{
}
}
}

View File

@@ -0,0 +1,34 @@
using StructureHelper.Infrastructure;
using StructureHelper.Infrastructure.UI.GraphicalPrimitives;
using StructureHelper.Windows.UserControls.WorkPlanes;
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperLogics.Models.BeamShears;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelper.Windows.BeamShears
{
public class InclinedSectionViewerViewModel : ViewModelBase
{
private IBeamShearSectionLogicResult sectionResult;
private IObjectConvertStrategy<List<IGraphicalPrimitive>, IBeamShearSectionLogicResult> logic;
public WorkPlaneRootViewModel WorkPlaneRoot { get; private set; }
public InclinedSectionViewerViewModel(IBeamShearSectionLogicResult sectionResult)
{
this.sectionResult = sectionResult;
WorkPlaneRoot = new();
logic = new SectionResultToGraphicalPrimitivesConvertLogic();
var primitives = logic.Convert(sectionResult);
primitives.ForEach(primitive =>
{
WorkPlaneRoot.PrimitiveCollection.Primitives.Add(primitive);
});
}
}
}

View File

@@ -0,0 +1,20 @@
using StructureHelper.Infrastructure.UI.GraphicalPrimitives;
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperLogics.Models.BeamShears;
using System.Collections.Generic;
namespace StructureHelper.Windows.BeamShears
{
public class SectionResultToGraphicalPrimitivesConvertLogic : IObjectConvertStrategy<List<IGraphicalPrimitive>, IBeamShearSectionLogicResult>
{
public List<IGraphicalPrimitive> Convert(IBeamShearSectionLogicResult source)
{
List<IGraphicalPrimitive> graphicalPrimitives = new List<IGraphicalPrimitive>();
BeamShearSectionPrimitive beamShearSectionPrimitive = new(source.InputData.InclinedSection.BeamShearSection, source.InputData.InclinedSection);
graphicalPrimitives.Add(beamShearSectionPrimitive);
InclinedSectionPrimitive inclinedSectionPrimitive = new(source);
graphicalPrimitives.Add((inclinedSectionPrimitive));
return graphicalPrimitives;
}
}
}

View File

@@ -4,6 +4,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:StructureHelper.Windows.BeamShears"
xmlns:uc="clr-namespace:StructureHelper.Windows.UserControls"
d:DataContext="{d:DesignInstance local:SectionViewModel}"
mc:Ignorable="d"
Title="Beam shear section" Height="400" Width="300" ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
@@ -55,6 +56,9 @@
<ContentControl Grid.Row="2" Grid.ColumnSpan="2" ContentTemplate="{StaticResource ReinforcementMaterial}" Content="{Binding ReinforcementMaterial}"/>
</Grid>
</TabItem>
<TabItem Header="Visual">
<uc:PrimitiveVisualProperty ObjectVisual="{Binding VisualProperty}"/>
</TabItem>
</TabControl>
<ContentControl Grid.Row="1" ContentTemplate="{StaticResource OkCancelButtons}" Content="{Binding}"/>
</Grid>

View File

@@ -1,8 +1,10 @@
using StructureHelper.Windows.ViewModels;
using StructureHelper.Windows.UserControls;
using StructureHelper.Windows.ViewModels;
using StructureHelper.Windows.ViewModels.Materials;
using StructureHelperCommon.Models.Shapes;
using StructureHelperLogics.Models.BeamShears;
using System;
using System.Windows.Media;
//Copyright (c) 2025 Redikultsev Evgeny, Ekaterinburg, Russia
//All rights reserved.
@@ -12,6 +14,7 @@ namespace StructureHelper.Windows.BeamShears
public class SectionViewModel : OkCancelViewModelBase
{
private readonly IBeamShearSection beamShearSection;
private PrimitiveVisualPropertyViewModel visual;
public string Name
{
@@ -41,6 +44,17 @@ namespace StructureHelper.Windows.BeamShears
beamShearSection.CenterCover = value;
}
}
public PrimitiveVisualPropertyViewModel VisualProperty
{
get => visual;
private set
{
visual = value;
OnPropertyChanged(nameof(VisualProperty));
}
}
public IShape Shape { get; }
public ConcreteViewModel ConcreteMaterial { get; }
public ReinforcementViewModel ReinforcementMaterial { get; }
@@ -57,6 +71,7 @@ namespace StructureHelper.Windows.BeamShears
};
Shape = beamShearSection.Shape;
ReinforcementMaterial = new(beamShearSection.ReinforcementMaterial) { MaterialLogicVisibility = false };
VisualProperty = new(this.beamShearSection.VisualProperty);
}
}
}

View File

@@ -4,6 +4,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:StructureHelper.Windows.BeamShears"
xmlns:uc="clr-namespace:StructureHelper.Windows.UserControls"
d:DataContext="{d:DesignInstance local:StirrupByDensityViewModel}"
mc:Ignorable="d"
Title="Stirrups by uniform density" Height="200" Width="300" ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
@@ -47,6 +48,9 @@
<TextBox Grid.Row="1" Grid.Column="1" Style="{StaticResource ValidatedError}" Text="{Binding EndCoordinate, Converter={StaticResource LengthConverter},ValidatesOnDataErrors=True}"/>
</Grid>
</TabItem>
<TabItem Header="Visual">
<uc:PrimitiveVisualProperty ObjectVisual="{Binding VisualProperty}"/>
</TabItem>
</TabControl>
<ContentControl Grid.Row="1" ContentTemplate="{StaticResource OkCancelButtons}" Content="{Binding}"/>
</Grid>

View File

@@ -1,12 +1,16 @@
using StructureHelper.Windows.ViewModels;
using StructureHelper.Windows.UserControls;
using StructureHelper.Windows.ViewModels;
using StructureHelperLogics.Models.BeamShears;
using System.ComponentModel;
using System.Windows.Media;
namespace StructureHelper.Windows.BeamShears
{
public class StirrupByDensityViewModel : OkCancelViewModelBase, IDataErrorInfo
{
private readonly IStirrupByDensity stirrupByDensity;
private PrimitiveVisualPropertyViewModel visual;
public double MinDensity { get; set; } = 0;
public string Name
@@ -50,6 +54,16 @@ namespace StructureHelper.Windows.BeamShears
}
}
public PrimitiveVisualPropertyViewModel VisualProperty
{
get => visual;
private set
{
visual = value;
OnPropertyChanged(nameof(VisualProperty));
}
}
public string Error => null;
public string this[string columnName]
@@ -71,6 +85,7 @@ namespace StructureHelper.Windows.BeamShears
public StirrupByDensityViewModel(IStirrupByDensity stirrupByDensity)
{
this.stirrupByDensity = stirrupByDensity;
VisualProperty = new(this.stirrupByDensity.VisualProperty);
}
}
}

View File

@@ -1,6 +1,8 @@
using StructureHelper.Windows.MainWindow.Materials;
using StructureHelper.Windows.UserControls;
using StructureHelper.Windows.ViewModels;
using StructureHelperLogics.Models.BeamShears;
using System.Windows.Media;
namespace StructureHelper.Windows.BeamShears
{
@@ -8,7 +10,7 @@ namespace StructureHelper.Windows.BeamShears
{
private const double minTransferLengthValue = 0.01;
private readonly IStirrupByInclinedRebar stirrupByInclinedRebar;
private PrimitiveVisualPropertyViewModel visual;
public string Name
{
@@ -73,6 +75,15 @@ namespace StructureHelper.Windows.BeamShears
}
public RebarSectionViewModel RebarSectionViewModel {get;}
public PrimitiveVisualPropertyViewModel VisualProperty
{
get => visual;
private set
{
visual = value;
OnPropertyChanged(nameof(VisualProperty));
}
}
public StirrupByInclinedRebarViewModel(IStirrupByInclinedRebar stirrupByInclinedRebar)
{
@@ -82,6 +93,7 @@ namespace StructureHelper.Windows.BeamShears
MinRebarDiameter = 0.003,
MaxRebarDiameter = 0.032
};
VisualProperty = new(this.stirrupByInclinedRebar.VisualProperty);
}
}
}

View File

@@ -53,6 +53,9 @@
<TabItem Header="Material" DataContext="{Binding RebarSectionViewModel}">
<ContentControl ContentTemplate="{StaticResource ReinforcementMaterial}" Content="{Binding Material}"/>
</TabItem>
<TabItem Header="Visual">
<uc:PrimitiveVisualProperty ObjectVisual="{Binding VisualProperty}"/>
</TabItem>
</TabControl>
<ContentControl Grid.Row="1" ContentTemplate="{StaticResource OkCancelButtons}" Content="{Binding}"/>

View File

@@ -4,6 +4,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:StructureHelper.Windows.BeamShears"
xmlns:uc="clr-namespace:StructureHelper.Windows.UserControls"
d:DataContext="{d:DesignInstance local:StirrupByRebarViewModel}"
mc:Ignorable="d"
Title="Stirrup by uniformly distributed rebars" Height="350" Width="300" ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
@@ -61,6 +62,9 @@
<TextBox Grid.Row="1" Grid.Column="1" Style="{StaticResource ValidatedError}" Text="{Binding EndCoordinate, Converter={StaticResource LengthConverter},ValidatesOnDataErrors=True}"/>
</Grid>
</TabItem>
<TabItem Header="Visual">
<uc:PrimitiveVisualProperty ObjectVisual="{Binding VisualProperty}"/>
</TabItem>
</TabControl>
<ContentControl Grid.Row="1" ContentTemplate="{StaticResource OkCancelButtons}" Content="{Binding}"/>
</Grid>

View File

@@ -1,6 +1,9 @@
using StructureHelper.Windows.ViewModels;
using StructureHelper.Windows.UserControls;
using StructureHelper.Windows.ViewModels;
using StructureHelper.Windows.ViewModels.Materials;
using StructureHelperCommon.Models.VisualProperties;
using StructureHelperLogics.Models.BeamShears;
using System;
using System.ComponentModel;
namespace StructureHelper.Windows.BeamShears
@@ -8,6 +11,8 @@ namespace StructureHelper.Windows.BeamShears
public class StirrupByRebarViewModel : OkCancelViewModelBase, IDataErrorInfo
{
private readonly IStirrupByRebar stirrupByRebar;
private PrimitiveVisualPropertyViewModel visual;
private PrimitiveVisualPropertyViewModel visual2;
public string Name
{
@@ -92,6 +97,17 @@ namespace StructureHelper.Windows.BeamShears
}
}
public PrimitiveVisualPropertyViewModel VisualProperty
{
get => visual;
private set
{
visual = value;
OnPropertyChanged(nameof(VisualProperty));
}
}
public ReinforcementViewModel Material { get; private set; }
public string Error => null;
@@ -151,6 +167,7 @@ namespace StructureHelper.Windows.BeamShears
{
this.stirrupByRebar = stirrupByRebar;
Material = new(this.stirrupByRebar.Material) { MaterialLogicVisibility = false};
VisualProperty = new(this.stirrupByRebar.VisualProperty);
}
}
}

View File

@@ -13,19 +13,19 @@ namespace StructureHelper.Windows.Graphs
{
public class FrameWorkElementServiseLogic : IFrameWorkElementServiseLogic
{
public void SaveImageToFile(FrameworkElement element)
public void SaveImageToFile(FrameworkElement element, double scaleFactor = 1)
{
var inputData = new ExportToFileInputData
{
Filter = "png |*.png",
Title = "Save in *.png File"
};
var logic = new ExportFrameWorkElementLogic(element);
var logic = new ExportFrameWorkElementLogic(element, scaleFactor);
var exportService = new ExportToFileService(inputData, logic);
exportService.Export();
}
public void CopyImageToClipboard(FrameworkElement element)
public void CopyImageToClipboard(FrameworkElement element, double scaleFactor = 1)
{
if (element == null) return;
@@ -35,8 +35,8 @@ namespace StructureHelper.Windows.Graphs
// Render the element to a RenderTargetBitmap
var renderTarget = new RenderTargetBitmap(
(int)element.ActualWidth,
(int)element.ActualHeight,
(int)(element.ActualWidth * scaleFactor),
(int)(element.ActualHeight * scaleFactor),
96, // DPI X
96, // DPI Y
PixelFormats.Pbgra32);

View File

@@ -4,7 +4,7 @@ namespace StructureHelper.Windows.Graphs
{
public interface IFrameWorkElementServiseLogic
{
void CopyImageToClipboard(FrameworkElement element);
void SaveImageToFile(FrameworkElement element);
void CopyImageToClipboard(FrameworkElement element, double scaleFactor = 1);
void SaveImageToFile(FrameworkElement element, double scaleFactor = 1);
}
}

View File

@@ -287,7 +287,6 @@
</i:EventTrigger>
</i:Interaction.Triggers>
<uc:WorkPlane ViewModel="{Binding}"/>
<!--<ContentControl ContentTemplate="{StaticResource WorkPlane}" Content="{Binding VisualProperty}"/>-->
</Border>
</Grid>
<StatusBar Grid.Row="1">

View File

@@ -0,0 +1,48 @@
<UserControl x:Class="StructureHelper.Windows.UserControls.PrimitiveVisualProperty"
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.Windows.UserControls"
mc:Ignorable="d"
d:DesignHeight="400" d:DesignWidth="400">
<Grid DataContext="{Binding ObjectVisual, RelativeSource={RelativeSource AncestorType=local:PrimitiveVisualProperty}}">
<Grid.RowDefinitions>
<RowDefinition Height="22"/>
<RowDefinition Height="22"/>
<RowDefinition Height="22"/>
<RowDefinition Height="30"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Text="Visible"/>
<TextBlock Grid.Row="1" Text="Color"/>
<TextBlock Grid.Row="2" Text="Z-index (integer)"/>
<TextBlock Grid.Row="3" Text="Opacity"/>
<CheckBox Grid.Column="1" IsChecked="{Binding IsVisible}" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="1,0,0,0"/>
<Grid Grid.Column="1" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<Rectangle Margin="1" Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{Binding Color}"/>
</Rectangle.Fill>
</Rectangle>
<Button Grid.Column="1" Margin="1" Content="..." Command="{Binding EditColorCommand}"/>
</Grid>
<TextBox Grid.Row="2" Grid.Column="1" Margin="1" Text="{Binding ZIndex}"/>
<Grid Grid.Row="3" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBox Text="{Binding Opacity, Converter={StaticResource PlainDouble}, ValidatesOnExceptions=True}" Margin="1,2,3,4"/>
<Slider Grid.Column="1" Value="{Binding Opacity}" Maximum="100" TickPlacement="BottomRight" TickFrequency="10" IsSnapToTickEnabled="True" Margin="2"/>
</Grid>
</Grid>
</UserControl>

View File

@@ -0,0 +1,32 @@
using System.Windows;
using System.Windows.Controls;
namespace StructureHelper.Windows.UserControls
{
/// <summary>
/// Логика взаимодействия для VisualProperty.xaml
/// </summary>
public partial class PrimitiveVisualProperty : UserControl
{
public PrimitiveVisualPropertyViewModel ObjectVisual
{
get { return (PrimitiveVisualPropertyViewModel)GetValue(ObjectVisualProperty); }
set { SetValue(ObjectVisualProperty, value); }
}
// Using a DependencyProperty as the backing store for ObjectVisualProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ObjectVisualProperty =
DependencyProperty.Register(
nameof(ObjectVisual),
typeof(PrimitiveVisualPropertyViewModel),
typeof(PrimitiveVisualProperty),
new PropertyMetadata(null)
);
public PrimitiveVisualProperty()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,69 @@
using StructureHelper.Infrastructure;
using StructureHelperCommon.Models.VisualProperties;
using StructureHelperCommon.Services.ColorServices;
using System.Windows.Input;
using System.Windows.Media;
namespace StructureHelper.Windows.UserControls
{
public class PrimitiveVisualPropertyViewModel : ViewModelBase
{
private IPrimitiveVisualProperty visualProperty;
private RelayCommand editColorCommand;
public bool IsVisible
{
get => visualProperty.IsVisible;
set
{
visualProperty.IsVisible = value;
OnPropertyChanged(nameof(IsVisible));
}
}
public int ZIndex
{
get => visualProperty.ZIndex;
set
{
visualProperty.ZIndex = value;
OnPropertyChanged(nameof(Color));
}
}
public double Opacity
{
get => visualProperty.Opacity * 100d;
set
{
if (value < 0d) { value = 0d; }
if (value > 100d) { value = 100d; }
visualProperty.Opacity = value / 100d;
OnPropertyChanged(nameof(Opacity));
}
}
public Color Color
{
get => visualProperty.Color;
set
{
visualProperty.Color = value;
OnPropertyChanged(nameof(Color));
}
}
public ICommand EditColorCommand => editColorCommand ??= new RelayCommand(o => EditColor());
private void EditColor()
{
Color color = Color;
ColorProcessor.EditColor(ref color);
Color = color;
}
public PrimitiveVisualPropertyViewModel(IPrimitiveVisualProperty visualProperty)
{
this.visualProperty = visualProperty;
}
}
}

View File

@@ -4,163 +4,194 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:StructureHelper.Windows.UserControls"
xmlns:uc="clr-namespace:StructureHelper.Windows.UserControls"
xmlns:enums="clr-namespace:StructureHelper.Infrastructure.Enums"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:infrastructure="clr-namespace:StructureHelper.Infrastructure"
xmlns:mouseEventTriggers="clr-namespace:StructureHelper.Infrastructure.UI.Triggers.MouseEventTriggers"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<DockPanel>
<ToolBarTray DockPanel.Dock="Top">
<ToolBar>
<Button Style="{DynamicResource ToolButton}" Command="{Binding CopyToClipboardCommand, RelativeSource={RelativeSource AncestorType=local:WorkPlane}}">
<Button.ToolTip>
<uc:ButtonToolTipEh HeaderText="Copy to clipboard"
IconContent="{StaticResource CopyToClipboard}"
DescriptionText="Copy chart to clipboard as image"/>
</Button.ToolTip>
<Viewbox>
<ContentControl ContentTemplate="{DynamicResource CopyToClipboard}"/>
</Viewbox>
</Button>
<Button Style="{DynamicResource ToolButton}" Command="{Binding SaveAsImageCommand, RelativeSource={RelativeSource AncestorType=local:WorkPlane}}">
<Button.ToolTip>
<uc:ButtonToolTipEh HeaderText="Export to *.png"
IconContent="{StaticResource PngImage}"
DescriptionText="Export chart to *.png file"/>
</Button.ToolTip>
<Viewbox>
<ContentControl ContentTemplate="{DynamicResource PngImage}"/>
</Viewbox>
</Button>
</ToolBar>
</ToolBarTray>
<ScrollViewer
Name="MainScrollViewer"
DataContext="{Binding VisualProperty}"
VerticalScrollBarVisibility="Visible"
HorizontalScrollBarVisibility="Visible">
<Canvas Name="WorkPlaneName"
HorizontalScrollBarVisibility="Visible"
Background="White">
<Grid x:Name="WorkPlaneGrid" Background="White">
<Canvas Name="WorkPlaneName"
ClipToBounds="True"
Width="{Binding Width}"
Height="{Binding Height}">
<Canvas.ContextMenu>
<ContextMenu>
<MenuItem Header="Add" DataContext="{Binding ParentViewModel.PrimitiveLogic}">
<MenuItem Header="Rectangle" Command="{Binding Add}" CommandParameter="{x:Static enums:PrimitiveType.Rectangle}">
<MenuItem.Icon>
<Image Style="{StaticResource ButtonImage16}" Source="/Windows/MainWindow/Rectangle32.png" />
</MenuItem.Icon>
Height="{Binding Height}"
>
<Canvas.ContextMenu>
<ContextMenu>
<MenuItem Header="Add" DataContext="{Binding ParentViewModel.PrimitiveLogic}">
<MenuItem Header="Rectangle" Command="{Binding Add}" CommandParameter="{x:Static enums:PrimitiveType.Rectangle}">
<MenuItem.Icon>
<Image Style="{StaticResource ButtonImage16}" Source="/Windows/MainWindow/Rectangle32.png" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Circle" Command="{Binding Add}" CommandParameter="{x:Static enums:PrimitiveType.Circle}">
<MenuItem.Icon>
<Image Style="{StaticResource ButtonImage16}" Source="/Windows/MainWindow/Circle32.png" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Rebar" Command="{Binding Add}" CommandParameter="{x:Static enums:PrimitiveType.Reinforcement}">
<MenuItem.Icon>
<Image Style="{StaticResource ButtonImage16}" Source="/Windows/MainWindow/Rebar32.png" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Point" Command="{Binding Add}" CommandParameter="{x:Static enums:PrimitiveType.Point}">
<MenuItem.Icon>
<Image Style="{StaticResource ButtonImage16}" Source="/Windows/MainWindow/Point32.png" />
</MenuItem.Icon>
</MenuItem>
</MenuItem>
<MenuItem Header="Circle" Command="{Binding Add}" CommandParameter="{x:Static enums:PrimitiveType.Circle}">
<MenuItem.Icon>
<Image Style="{StaticResource ButtonImage16}" Source="/Windows/MainWindow/Circle32.png" />
</MenuItem.Icon>
<MenuItem Header="Templates" DataContext="{Binding ParentViewModel}">
<MenuItem Header="Add Rectangle RC Column" Command="{Binding AddColumnCase}">
<MenuItem.Icon>
<Image Style="{StaticResource ButtonImage16}" Source="/Windows/MainWindow/RectangleColumn32.png" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Add Circle RC Column" Command="{Binding AddRCCircleCase}">
<MenuItem.Icon>
<Image Style="{StaticResource ButtonImage16}" Source="/Windows/MainWindow/CircleColumn32.png" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Add RC Beam" Command="{Binding AddBeamCase}">
<MenuItem.Icon>
<Image Style="{StaticResource ButtonImage16}" Source="/Windows/MainWindow/Beam32.png" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Add RC slab" Command="{Binding AddSlabCase}">
<MenuItem.Icon>
<Image Style="{StaticResource ButtonImage16}" Source="/Windows/MainWindow/Slab32.png" />
</MenuItem.Icon>
</MenuItem>
</MenuItem>
<MenuItem Header="Rebar" Command="{Binding Add}" CommandParameter="{x:Static enums:PrimitiveType.Reinforcement}">
<MenuItem.Icon>
<Image Style="{StaticResource ButtonImage16}" Source="/Windows/MainWindow/Rebar32.png" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Point" Command="{Binding Add}" CommandParameter="{x:Static enums:PrimitiveType.Point}">
<MenuItem.Icon>
<Image Style="{StaticResource ButtonImage16}" Source="/Windows/MainWindow/Point32.png" />
</MenuItem.Icon>
</MenuItem>
</MenuItem>
<MenuItem Header="Templates" DataContext="{Binding ParentViewModel}">
<MenuItem Header="Add Rectangle RC Column" Command="{Binding AddColumnCase}">
<MenuItem.Icon>
<Image Style="{StaticResource ButtonImage16}" Source="/Windows/MainWindow/RectangleColumn32.png" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Add Circle RC Column" Command="{Binding AddRCCircleCase}">
<MenuItem.Icon>
<Image Style="{StaticResource ButtonImage16}" Source="/Windows/MainWindow/CircleColumn32.png" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Add RC Beam" Command="{Binding AddBeamCase}">
<MenuItem.Icon>
<Image Style="{StaticResource ButtonImage16}" Source="/Windows/MainWindow/Beam32.png" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Add RC slab" Command="{Binding AddSlabCase}">
<MenuItem.Icon>
<Image Style="{StaticResource ButtonImage16}" Source="/Windows/MainWindow/Slab32.png" />
</MenuItem.Icon>
</MenuItem>
</MenuItem>
</ContextMenu>
</Canvas.ContextMenu>
<i:Interaction.Behaviors>
<infrastructure:MouseBehaviour MouseX="{Binding PanelX, Mode=OneWayToSource}" MouseY="{Binding PanelY, Mode=OneWayToSource}"/>
</i:Interaction.Behaviors>
<i:Interaction.Triggers>
<mouseEventTriggers:MouseWheelDownEventTrigger EventName="PreviewMouseWheel">
<i:InvokeCommandAction Command="{Binding ScaleCanvasDown}"/>
</mouseEventTriggers:MouseWheelDownEventTrigger>
<mouseEventTriggers:MouseWheelUpEventTrigger EventName="PreviewMouseWheel">
<i:InvokeCommandAction Command="{Binding ScaleCanvasUp}"/>
</mouseEventTriggers:MouseWheelUpEventTrigger>
</i:Interaction.Triggers>
<Canvas.LayoutTransform>
<TransformGroup>
<ScaleTransform ScaleX="{Binding ScaleValue}" ScaleY="{Binding ScaleValue}"
</ContextMenu>
</Canvas.ContextMenu>
<i:Interaction.Behaviors>
<infrastructure:MouseBehaviour MouseX="{Binding PanelX, Mode=OneWayToSource}" MouseY="{Binding PanelY, Mode=OneWayToSource}"/>
</i:Interaction.Behaviors>
<i:Interaction.Triggers>
<mouseEventTriggers:MouseWheelDownEventTrigger EventName="PreviewMouseWheel">
<i:InvokeCommandAction Command="{Binding ScaleCanvasDown}"/>
</mouseEventTriggers:MouseWheelDownEventTrigger>
<mouseEventTriggers:MouseWheelUpEventTrigger EventName="PreviewMouseWheel">
<i:InvokeCommandAction Command="{Binding ScaleCanvasUp}"/>
</mouseEventTriggers:MouseWheelUpEventTrigger>
</i:Interaction.Triggers>
<Canvas.LayoutTransform>
<TransformGroup>
<ScaleTransform ScaleX="{Binding ScaleValue}" ScaleY="{Binding ScaleValue}"
CenterX="{Binding ScrollPanelX}" CenterY="{Binding ScrollPanelY}"/>
</TransformGroup>
</Canvas.LayoutTransform>
<Canvas.Background>
<VisualBrush TileMode="Tile"
</TransformGroup>
</Canvas.LayoutTransform>
<Canvas.Background>
<VisualBrush TileMode="Tile"
Viewport="{Binding CanvasViewportSize}" ViewportUnits="Absolute"
Viewbox="{Binding CanvasViewportSize}" ViewboxUnits="Absolute">
<VisualBrush.Visual>
<Rectangle
<VisualBrush.Visual>
<Rectangle
Height="{Binding GridSize}"
Width="{Binding GridSize}"
Stroke="{Binding GridColorBrush}"
StrokeThickness="{Binding GridLineThickness}"/>
</VisualBrush.Visual>
</VisualBrush>
</Canvas.Background>
<!--Horizontal axis line-->
<TextBlock Canvas.Left="0" Canvas.Top="{Binding HalfOfHeight}"
StrokeThickness="{Binding GridLineThickness}"
Fill="White"/>
</VisualBrush.Visual>
</VisualBrush>
</Canvas.Background>
<!--Horizontal axis line-->
<TextBlock Canvas.Left="0" Canvas.Top="{Binding HalfOfHeight}"
Margin="0,0,0,0" Text="X" FontSize="{Binding MainTextFontSize}"
Background="AliceBlue"
Foreground="{Binding XAxisColorBrush}">
<TextBlock.RenderTransform>
<ScaleTransform ScaleX="{Binding TextScaleValue}" ScaleY="{Binding TextScaleValue}"/>
</TextBlock.RenderTransform>
</TextBlock>
<TextBlock Canvas.Left="{Binding Width}" Canvas.Top="{Binding HalfOfHeight}"
<TextBlock.RenderTransform>
<ScaleTransform ScaleX="{Binding TextScaleValue}" ScaleY="{Binding TextScaleValue}"/>
</TextBlock.RenderTransform>
</TextBlock>
<TextBlock Canvas.Left="{Binding Width}" Canvas.Top="{Binding HalfOfHeight}"
Margin="-0.02,0,0,0" Text="X" FontSize="{Binding MainTextFontSize}"
Background="AliceBlue"
Foreground="{Binding XAxisColorBrush}">
<TextBlock.RenderTransform>
<ScaleTransform ScaleX="{Binding TextScaleValue}" ScaleY="{Binding TextScaleValue}" />
</TextBlock.RenderTransform>
</TextBlock>
<Line
<TextBlock.RenderTransform>
<ScaleTransform ScaleX="{Binding TextScaleValue}" ScaleY="{Binding TextScaleValue}" />
</TextBlock.RenderTransform>
</TextBlock>
<Line
X1="0" X2="{Binding Width}"
Y1="{Binding HalfOfHeight}" Y2="{Binding HalfOfHeight}"
Stroke="{Binding XAxisColorBrush}"
StrokeThickness="{Binding AxisLineThickness}"/>
<!--Vertical axis line-->
<TextBlock Canvas.Left="{Binding HalfOfWidth}" Canvas.Top="0"
<!--Vertical axis line-->
<TextBlock Canvas.Left="{Binding HalfOfWidth}" Canvas.Top="0"
Margin="0.01,0,0,0" Text="Y" FontSize="{Binding MainTextFontSize}"
Background="AliceBlue"
Foreground="{Binding YAxisColorBrush}">
<TextBlock.RenderTransform>
<ScaleTransform ScaleX="{Binding TextScaleValue}" ScaleY="{Binding TextScaleValue}"/>
</TextBlock.RenderTransform>
</TextBlock>
<TextBlock Canvas.Left="{Binding HalfOfWidth}" Canvas.Top="{Binding Height}"
<TextBlock.RenderTransform>
<ScaleTransform ScaleX="{Binding TextScaleValue}" ScaleY="{Binding TextScaleValue}"/>
</TextBlock.RenderTransform>
</TextBlock>
<TextBlock Canvas.Left="{Binding HalfOfWidth}" Canvas.Top="{Binding Height}"
Margin="0.01,-0.05,0,0" Text="Y" FontSize="{Binding MainTextFontSize}"
Background="AliceBlue"
Foreground="{Binding YAxisColorBrush}">
<TextBlock.RenderTransform>
<ScaleTransform ScaleX="{Binding TextScaleValue}" ScaleY="{Binding TextScaleValue}" />
</TextBlock.RenderTransform>
</TextBlock>
<Line
<TextBlock.RenderTransform>
<ScaleTransform ScaleX="{Binding TextScaleValue}" ScaleY="{Binding TextScaleValue}" />
</TextBlock.RenderTransform>
</TextBlock>
<Line
X1="{Binding HalfOfWidth}" X2="{Binding HalfOfWidth}"
Y1="0" Y2="{Binding Height}"
Stroke="{Binding YAxisColorBrush}"
StrokeThickness="{Binding AxisLineThickness}"/>
<ItemsControl
<ItemsControl
DataContext="{Binding ParentViewModel.PrimitiveLogic}"
ItemsSource="{Binding Items}"
ContextMenu="{StaticResource PrimitiveCRUD}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.ZIndex" Value="{Binding ZIndex}"/>
<Setter Property="Canvas.Left" Value="{Binding PrimitiveLeft}"/>
<Setter Property="Canvas.Top" Value="{Binding PrimitiveTop}"/>
<Setter Property="Visibility" Value="{Binding IsVisible, Converter={StaticResource BooleanToVisibilityConverter}}"/>
<EventSetter Event="MouseDown" Handler="ContentPresenter_MouseLeftButtonDown"/>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</Canvas>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.ZIndex" Value="{Binding ZIndex}"/>
<Setter Property="Canvas.Left" Value="{Binding PrimitiveLeft}"/>
<Setter Property="Canvas.Top" Value="{Binding PrimitiveTop}"/>
<Setter Property="Visibility" Value="{Binding IsVisible, Converter={StaticResource BooleanToVisibilityConverter}}"/>
<EventSetter Event="MouseDown" Handler="ContentPresenter_MouseLeftButtonDown"/>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</Canvas>
</Grid>
</ScrollViewer>
</Grid>
</DockPanel>
</UserControl>

View File

@@ -1,4 +1,6 @@
using StructureHelper.Infrastructure.UI.DataContexts;
using StructureHelper.Infrastructure;
using StructureHelper.Infrastructure.UI.DataContexts;
using StructureHelper.Windows.Graphs;
using StructureHelper.Windows.MainWindow;
using StructureHelper.Windows.ViewModels.Materials;
using System;
@@ -23,7 +25,9 @@ namespace StructureHelper.Windows.UserControls
/// </summary>
public partial class WorkPlane : UserControl
{
private IFrameWorkElementServiseLogic frameWorkElementServiseLogic = new FrameWorkElementServiseLogic();
private RelayCommand saveImageCommand;
private RelayCommand copyToClipboardCommand;
public CrossSectionViewModel ViewModel
{
@@ -35,7 +39,15 @@ namespace StructureHelper.Windows.UserControls
public static readonly DependencyProperty ViewModelProperty =
DependencyProperty.Register(nameof(ViewModel), typeof(CrossSectionViewModel), typeof(WorkPlane), new PropertyMetadata(null));
public ICommand SaveAsImageCommand
{
get => saveImageCommand ??= new RelayCommand(o => frameWorkElementServiseLogic.SaveImageToFile(WorkPlaneGrid));
}
public ICommand CopyToClipboardCommand
{
get => copyToClipboardCommand ??= new RelayCommand(o => frameWorkElementServiseLogic.CopyImageToClipboard(WorkPlaneGrid));
}
public WorkPlane()
{

View File

@@ -0,0 +1,28 @@
<UserControl x:Class="StructureHelper.Windows.UserControls.WorkPlanes.AxisLayer"
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.Windows.UserControls.WorkPlanes"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance local:WorkPlaneRootViewModel}"
x:Name="AxisRoot"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Canvas x:Name="AxisCanvas" DataContext="{Binding WorkPlaneConfig}">
<!-- Horizontal Axis -->
<Line X1="0" X2="{Binding Width, ElementName=AxisRoot}" Y1="0" Y2="0"
Stroke="{Binding XAxisColorBrush, ElementName=AxisRoot}" StrokeThickness="{Binding AxisLineThickness}" />
<TextBlock Canvas.Left="0" Canvas.Top="{Binding HalfOfHeight, ElementName=AxisRoot}"
Text="X" FontSize="{Binding AxisFontSize}"
Foreground="{Binding XAxisColorBrush, ElementName=AxisRoot}" />
<!-- Vertical Axis -->
<Line X1="0" X2="0" Y1="0" Y2="{Binding Height, ElementName=AxisRoot}"
Stroke="{Binding YAxisColorBrush, ElementName=AxisRoot}" StrokeThickness="{Binding AxisLineThickness}" />
<TextBlock Canvas.Left="{Binding HalfOfWidth, ElementName=AxisRoot}" Canvas.Top="0"
Text="Y" FontSize="{Binding AxisFontSize}"
Foreground="{Binding YAxisColorBrush, ElementName=AxisRoot}" />
</Canvas>
</Grid>
</UserControl>

View File

@@ -0,0 +1,56 @@
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.Windows.UserControls.WorkPlanes
{
/// <summary>
/// Логика взаимодействия для AxisLayer.xaml
/// </summary>
public partial class AxisLayer : UserControl
{
public AxisLayer()
{
InitializeComponent();
}
public double HalfOfWidth => Width / 2;
public double HalfOfHeight => Height / 2;
public Brush XAxisColorBrush
{
get => (Brush)GetValue(XAxisColorBrushProperty);
set => SetValue(XAxisColorBrushProperty, value);
}
public static readonly DependencyProperty XAxisColorBrushProperty =
DependencyProperty.Register(nameof(XAxisColorBrush), typeof(Brush), typeof(AxisLayer), new PropertyMetadata(Brushes.Black));
public Brush YAxisColorBrush
{
get => (Brush)GetValue(YAxisColorBrushProperty);
set => SetValue(YAxisColorBrushProperty, value);
}
public static readonly DependencyProperty YAxisColorBrushProperty =
DependencyProperty.Register(nameof(YAxisColorBrush), typeof(Brush), typeof(AxisLayer), new PropertyMetadata(Brushes.Black));
public double AxisLineThickness
{
get => (double)GetValue(AxisLineThicknessProperty);
set => SetValue(AxisLineThicknessProperty, value);
}
public static readonly DependencyProperty AxisLineThicknessProperty =
DependencyProperty.Register(nameof(AxisLineThickness), typeof(double), typeof(AxisLayer), new PropertyMetadata(1.0));
}
}

View File

@@ -0,0 +1,30 @@
<UserControl x:Class="StructureHelper.Windows.UserControls.WorkPlanes.GridLayer"
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.Windows.UserControls.WorkPlanes"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance local:WorkPlaneRootViewModel}"
x:Name="GridRoot"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Canvas>
<Canvas.Background>
<VisualBrush TileMode="Tile"
Viewport="{Binding CanvasViewportSize, ElementName=GridRoot}"
ViewportUnits="Absolute"
Viewbox="{Binding CanvasViewportSize, ElementName=GridRoot}"
ViewboxUnits="Absolute">
<VisualBrush.Visual>
<Rectangle
Width="{Binding GridSize, ElementName=GridRoot}"
Height="{Binding GridSize, ElementName=GridRoot}"
Stroke="{Binding GridColorBrush, ElementName=GridRoot}"
StrokeThickness="{Binding GridLineThickness, ElementName=GridRoot}" />
</VisualBrush.Visual>
</VisualBrush>
</Canvas.Background>
</Canvas>
</Grid>
</UserControl>

View File

@@ -0,0 +1,65 @@
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.Windows.UserControls.WorkPlanes
{
/// <summary>
/// Логика взаимодействия для Gridlayer.xaml
/// </summary>
public partial class GridLayer : UserControl
{
public GridLayer()
{
InitializeComponent();
}
public static readonly DependencyProperty GridSizeProperty =
DependencyProperty.Register(nameof(GridSize), typeof(double), typeof(GridLayer), new PropertyMetadata(10.0));
public double GridSize
{
get => (double)GetValue(GridSizeProperty);
set => SetValue(GridSizeProperty, value);
}
public static readonly DependencyProperty GridColorBrushProperty =
DependencyProperty.Register(nameof(GridColorBrush), typeof(Brush), typeof(GridLayer), new PropertyMetadata(Brushes.LightGray));
public Brush GridColorBrush
{
get => (Brush)GetValue(GridColorBrushProperty);
set => SetValue(GridColorBrushProperty, value);
}
public static readonly DependencyProperty GridLineThicknessProperty =
DependencyProperty.Register(nameof(GridLineThickness), typeof(double), typeof(GridLayer), new PropertyMetadata(0.5));
public double GridLineThickness
{
get => (double)GetValue(GridLineThicknessProperty);
set => SetValue(GridLineThicknessProperty, value);
}
public static readonly DependencyProperty CanvasViewportSizeProperty =
DependencyProperty.Register(nameof(CanvasViewportSize), typeof(Rect), typeof(GridLayer), new PropertyMetadata(new Rect(0, 0, 20, 20)));
public Rect CanvasViewportSize
{
get => (Rect)GetValue(CanvasViewportSizeProperty);
set => SetValue(CanvasViewportSizeProperty, value);
}
}
}

View File

@@ -0,0 +1,17 @@
using StructureHelper.Infrastructure;
using StructureHelper.Infrastructure.UI.GraphicalPrimitives;
using StructureHelperLogics.Models.Primitives;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelper.Windows.UserControls.WorkPlanes
{
public class PrimitiveCollectionViewModel : ViewModelBase
{
public ObservableCollection<IGraphicalPrimitive> Primitives { get; } = new();
}
}

View File

@@ -0,0 +1,30 @@
using FieldVisualizer.Entities.Values.Primitives;
using StructureHelper.Infrastructure.UI.GraphicalPrimitives;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
namespace StructureHelper.Windows.UserControls.WorkPlanes
{
public class PrimitiveTemplateSelector : DataTemplateSelector
{
public DataTemplate BeamShearSectionTemplate { get; set; }
public DataTemplate InclinedSectionTemplate { get; set; }
public DataTemplate BeamShearStirrupByRebarTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
return item switch
{
BeamShearSectionPrimitive => BeamShearSectionTemplate,
InclinedSectionPrimitive => InclinedSectionTemplate,
_ => base.SelectTemplate(item, container)
};
}
}
}

View File

@@ -0,0 +1,124 @@
using StructureHelper.Infrastructure;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
namespace StructureHelper.Windows.UserControls.WorkPlanes
{
public class WorkPlaneConfigViewModel : ViewModelBase
{
private double zoomCenterX;
private double zoomCenterY;
private double scaleValue = 200;
private double canvasWidth = 3;
private double canvasHeight = 3;
private double axisFontSize = 14;
private double axisLineThickness = 2;
public double CanvasWidth
{
get => canvasWidth;
set
{
canvasWidth = value;
Refresh();
}
}
public double CanvasHeight
{
get => canvasHeight;
set
{
canvasHeight = value;
Refresh();
}
}
public double ScaleValue
{
get => scaleValue;
set
{
scaleValue = value;
Refresh();
}
}
public double NegativeScaleValue
{
get => scaleValue * (-1);
}
public double ZoomCenterX
{
get => zoomCenterX;
set
{
zoomCenterX = value;
Refresh();
}
}
public double ZoomCenterY
{
get => zoomCenterY;
set
{
zoomCenterY = value;
Refresh();
}
}
private void Refresh()
{
OnPropertyChanged(nameof(CanvasWidth));
OnPropertyChanged(nameof(CanvasHeight));
OnPropertyChanged(nameof(ScaleValue));
OnPropertyChanged(nameof(NegativeScaleValue));
OnPropertyChanged(nameof(ZoomCenterX));
OnPropertyChanged(nameof(ZoomCenterY));
OnPropertyChanged(nameof(AxisFontSize));
OnPropertyChanged(nameof(AxisLineThickness));
}
public double CenterOffsetX => 0;// CanvasWidth / 2;
public double CenterOffsetY => 0;// CanvasHeight / 2 * (-1);
public double GridSize { get; set; } = 0.05;
public Brush GridColorBrush { get; set; } = Brushes.LightGray;
public double GridLineThickness { get; set; } = 0.005;
public Size CanvasViewportSize => new(CanvasWidth, CanvasHeight);
public Brush XAxisColorBrush { get; set; } = Brushes.DarkRed;
public Brush YAxisColorBrush { get; set; } = Brushes.DarkGreen;
public double AxisLineThickness
{
get
{
return axisLineThickness / scaleValue;
}
}
public void ZoomAt(Point position, double zoomFactor)
{
// Optional: zoom to cursor
ZoomCenterX *= zoomFactor;// position.X / scaleValue ;// - CenterOffsetX;
ZoomCenterY *= zoomFactor;// position.Y / NegativeScaleValue;// - CenterOffsetY;
// Update scale
ScaleValue *= zoomFactor;
}
public double AxisFontSize
{
get
{
return axisFontSize / scaleValue;
}
}
}
}

View File

@@ -0,0 +1,92 @@
<UserControl x:Class="StructureHelper.Windows.UserControls.WorkPlanes.WorkPlaneRoot"
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.Windows.UserControls.WorkPlanes"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance local:WorkPlaneRootViewModel}"
d:DesignHeight="450" d:DesignWidth="800">
<DockPanel>
<ToolBarTray DockPanel.Dock="Top">
<ToolBar>
</ToolBar>
</ToolBarTray>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<ScrollViewer VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible" Background="White">
<Canvas x:Name="RootCanvas" Width="{Binding WorkPlaneConfig.CanvasWidth}" Height="{Binding WorkPlaneConfig.CanvasHeight}">
<Canvas.RenderTransform>
<TransformGroup>
<!-- Shift origin to canvas center -->
<TranslateTransform
X="{Binding WorkPlaneConfig.CenterOffsetX}"
Y="{Binding WorkPlaneConfig.CenterOffsetY}" />
<!-- Apply zoom scale -->
<ScaleTransform
ScaleX="{Binding WorkPlaneConfig.ScaleValue}"
ScaleY="{Binding WorkPlaneConfig.NegativeScaleValue}"
CenterX="{Binding WorkPlaneConfig.ZoomCenterX}"
CenterY="{Binding WorkPlaneConfig.ZoomCenterY}" />
</TransformGroup>
</Canvas.RenderTransform>
<!-- Grid layer -->
<local:GridLayer
GridSize="{Binding WorkPlaneConfig.GridSize}"
GridColorBrush="{Binding WorkPlaneConfig.GridColorBrush}"
GridLineThickness="{Binding WorkPlaneConfig.GridLineThickness}"
CanvasViewportSize="{Binding WorkPlaneConfig.CanvasViewportSize}" />
<!-- Axis layer -->
<local:AxisLayer
Width="{Binding WorkPlaneConfig.CanvasWidth}"
Height="{Binding WorkPlaneConfig.CanvasHeight}"
XAxisColorBrush="{Binding WorkPlaneConfig.XAxisColorBrush}"
YAxisColorBrush="{Binding WorkPlaneConfig.YAxisColorBrush}"
AxisLineThickness="{Binding WorkPlaneConfig.AxisLineThickness}" />
<!-- Primitives (ItemsControl) -->
<ItemsControl ItemsSource="{Binding PrimitiveCollection.Primitives}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplateSelector>
<local:PrimitiveTemplateSelector
BeamShearSectionTemplate="{StaticResource BeamShearSectionPrimitiveTemplate}"
InclinedSectionTemplate="{StaticResource InclinedSectionPrimitiveTemplate}"
/>
</ItemsControl.ItemTemplateSelector>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding CenterX}" />
<Setter Property="Canvas.Top" Value="{Binding CenterY}" />
<!--<Setter Property="Canvas.ZIndex" Value="{Binding WorkPlaneConfig.ZIndex}" />
<Setter Property="Visibility" Value="{Binding WorkPlaneConfig.IsVisible, Converter={StaticResource BooleanToVisibilityConverter}}" />-->
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</Canvas>
</ScrollViewer>
<StatusBar Grid.Row="1">
<StatusBarItem>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Scale = "/>
<TextBlock Width="50" Text="{Binding WorkPlaneConfig.ScaleValue}"/>
</StackPanel>
</StatusBarItem>
</StatusBar>
</Grid>
</DockPanel>
</UserControl>

View File

@@ -0,0 +1,79 @@
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.Windows.UserControls.WorkPlanes
{
/// <summary>
/// Логика взаимодействия для WorkPlaneRoot.xaml
/// </summary>
public partial class WorkPlaneRoot : UserControl
{
private Point? _lastPanPoint;
public WorkPlaneRoot()
{
InitializeComponent();
this.PreviewMouseWheel += WorkPlaneRoot_PreviewMouseWheel;
this.MouseDown += WorkPlaneRoot_MouseDown;
this.MouseMove += WorkPlaneRoot_MouseMove;
this.MouseUp += WorkPlaneRoot_MouseUp;
}
private void WorkPlaneRoot_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.MiddleButton == MouseButtonState.Pressed)
_lastPanPoint = e.GetPosition(this);
}
private void WorkPlaneRoot_MouseMove(object sender, MouseEventArgs e)
{
if (_lastPanPoint.HasValue && e.MiddleButton == MouseButtonState.Pressed)
{
var current = e.GetPosition(this);
var dx = current.X - _lastPanPoint.Value.X;
var dy = current.Y - _lastPanPoint.Value.Y;
if (DataContext is WorkPlaneRootViewModel dc)
{
dc.WorkPlaneConfig.ZoomCenterX -= dx / dc.WorkPlaneConfig.ScaleValue;
dc.WorkPlaneConfig.ZoomCenterY -= dy / dc.WorkPlaneConfig.NegativeScaleValue;
}
_lastPanPoint = current;
}
}
private void WorkPlaneRoot_MouseUp(object sender, MouseButtonEventArgs e)
{
_lastPanPoint = null;
}
private void WorkPlaneRoot_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
//if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
{
var pos = e.GetPosition(this);
if (DataContext is WorkPlaneRootViewModel dc)
{
double zoomFactor = e.Delta > 0 ? 1.1 : 0.9;
dc.WorkPlaneConfig.ZoomAt(pos, zoomFactor);
e.Handled = true;
}
}
}
}
}

View File

@@ -0,0 +1,15 @@
using StructureHelper.Infrastructure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelper.Windows.UserControls.WorkPlanes
{
public class WorkPlaneRootViewModel : ViewModelBase
{
public WorkPlaneConfigViewModel WorkPlaneConfig { get; } = new();
public PrimitiveCollectionViewModel PrimitiveCollection { get; } = new();
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperCommon.Infrastructures.Interfaces
{
public interface IObjectConvertStrategy<T, V>
{
T Convert(V source);
}
}

View File

@@ -7,7 +7,7 @@ namespace StructureHelperCommon.Models.VisualProperties
/// <inheritdoc/>
public class PrimitiveVisualProperty : IPrimitiveVisualProperty
{
private double opacity = 0;
private double opacity = 1;
/// <inheritdoc/>
public Guid Id { get; }
@@ -25,7 +25,7 @@ namespace StructureHelperCommon.Models.VisualProperties
{
if (value < 0)
{
opacity = 1;
opacity = 0;
return;
}
if (value > 1)

View File

@@ -1,6 +1,8 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models.Shapes;
using StructureHelperCommon.Models.VisualProperties;
using StructureHelperLogics.Models.Materials;
using System.Windows.Media;
namespace StructureHelperLogics.Models.BeamShears
{
@@ -17,6 +19,7 @@ namespace StructureHelperLogics.Models.BeamShears
public double CenterCover { get; set; } = 0.05;
public double ReinforcementArea { get; set; } = 0;
public IReinforcementLibMaterial ReinforcementMaterial { get; set; }
public IPrimitiveVisualProperty VisualProperty { get; set; }
public BeamShearSection(Guid id)
{
@@ -24,6 +27,10 @@ namespace StructureHelperLogics.Models.BeamShears
ConcreteMaterial = ConcreteLibMaterialFactory.GetConcreteLibMaterial(ConcreteLibTypes.Concrete25);
ReinforcementMaterial = HeadMaterialFactory.GetHeadMaterial(HeadmaterialType.Reinforcement500).HelperMaterial as IReinforcementLibMaterial;
ConcreteMaterial.TensionForULS = true;
VisualProperty = new PrimitiveVisualProperty(Guid.NewGuid())
{
Color = (Color)ColorConverter.ConvertFromString("DarkGray")
};
}
public object Clone()

View File

@@ -1,5 +1,6 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models.Shapes;
using StructureHelperCommon.Models.VisualProperties;
using StructureHelperLogics.Models.Materials;
namespace StructureHelperLogics.Models.BeamShears
@@ -7,7 +8,7 @@ namespace StructureHelperLogics.Models.BeamShears
/// <summary>
/// Properties of RC cross-section for shear strength of beam
/// </summary>
public interface IBeamShearSection : ISaveable, ICloneable
public interface IBeamShearSection : ISaveable, ICloneable, IHasVisualProperty
{
string? Name { get; set; }
/// <summary>

View File

@@ -36,6 +36,16 @@ namespace StructureHelperLogics.Models.BeamShears
Check();
TraceLogger?.AddMessage(LoggerStrings.LogicType(this), TraceLogStatuses.Service);
TraceLogger?.AddMessage("Calculation has been started", TraceLogStatuses.Debug);
if (stirrupByDensity.EndCoordinate < inclinedSection.StartCoord)
{
TraceLogger?.AddMessage($"Stirrup end coordinate Xend = {stirrupByDensity.EndCoordinate}(m) is less than incline section start coordinate Xstart = {inclinedSection.StartCoord}(m), stirrup {stirrupByDensity.Name} has been ignored");
return 0;
}
if (stirrupByDensity.StartCoordinate > inclinedSection.EndCoord)
{
TraceLogger?.AddMessage($"Stirrup start coordinate Xstart = {stirrupByDensity.StartCoordinate}(m) is bigger than incline section end coordinate Xend = {inclinedSection.EndCoord}(m), stirrup {stirrupByDensity.Name} has been ignored");
return 0;
}
double crackLength = inclinedSection.EndCoord - inclinedSection.StartCoord;
TraceLogger?.AddMessage($"Length of crack = {inclinedSection.EndCoord} - {inclinedSection.StartCoord} = {crackLength}(m)");
double crackEndCoord = Math.Min(stirrupByDensity.EndCoordinate, inclinedSection.EndCoord);

View File

@@ -52,6 +52,16 @@ namespace StructureHelperLogics.Models.BeamShears
public double GetShearStrength()
{
InitializeStrategies();
if (stirrupByRebar.EndCoordinate < inclinedSection.StartCoord)
{
TraceLogger?.AddMessage($"Stirrup end coordinate Xend = {stirrupByRebar.EndCoordinate}(m) is less than incline section start coordinate Xstart = {inclinedSection.StartCoord}(m), stirrup {stirrupByRebar.Name} has been ignored");
return 0;
}
if (stirrupByRebar.StartCoordinate > inclinedSection.EndCoord)
{
TraceLogger?.AddMessage($"Stirrup start coordinate Xstart = {stirrupByRebar.StartCoordinate}(m) is bigger than incline section end coordinate Xend = {inclinedSection.EndCoord}(m), stirrup {stirrupByRebar.Name} has been ignored");
return 0;
}
TraceLogger?.AddMessage($"Stirrup diameter d = {stirrupByRebar.Diameter}(m)");
TraceLogger?.AddMessage($"Stirrup leg number n = {stirrupByRebar.LegCount}");
TraceLogger?.AddMessage($"Stirrup spacing S = {stirrupByRebar.Spacing}(m)");

View File

@@ -21,7 +21,7 @@ namespace StructureHelperLogics.Models.BeamShears
Id = id;
VisualProperty = new PrimitiveVisualProperty(Guid.NewGuid())
{
Color = (Color)ColorConverter.ConvertFromString("Black")
Color = (Color)ColorConverter.ConvertFromString("Gray")
};
}

View File

@@ -73,7 +73,7 @@ namespace StructureHelperLogics.Models.BeamShears
Id = id;
VisualProperty = new PrimitiveVisualProperty(Guid.NewGuid())
{
Color = (Color)ColorConverter.ConvertFromString("Black")
Color = (Color)ColorConverter.ConvertFromString("Blue")
};
}

View File

@@ -74,7 +74,7 @@ namespace StructureHelperLogics.Models.BeamShears
Material = HeadMaterialFactory.GetHeadMaterial(HeadmaterialType.Reinforcement400).HelperMaterial as IReinforcementLibMaterial;
VisualProperty = new PrimitiveVisualProperty(Guid.NewGuid())
{
Color = (Color)ColorConverter.ConvertFromString("Black")
Color = (Color)ColorConverter.ConvertFromString("Brown")
};
}

View File

@@ -6,35 +6,40 @@ using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Xml.Linq;
namespace StructureHelperLogics.NdmCalculations.Analyses
{
public class ExportFrameWorkElementLogic : IExportResultLogic
{
private FrameworkElement visual;
private FrameworkElement element;
private double scaleFactor;
public string FileName { get; set; }
public void Export()
{
var encoder = new PngBitmapEncoder();
EncodeVisual(visual, FileName, encoder);
EncodeVisual(element, FileName, encoder);
}
public ExportFrameWorkElementLogic(FrameworkElement visual)
public ExportFrameWorkElementLogic(FrameworkElement visual, double scaleFactor = 1)
{
this.visual = visual;
this.element = visual;
this.scaleFactor = scaleFactor;
}
private static void EncodeVisual(FrameworkElement visual, string fileName, BitmapEncoder encoder)
private void EncodeVisual(FrameworkElement visual, string fileName, BitmapEncoder encoder)
{
// Measure and arrange the element to ensure it's fully rendered
visual.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
Rect previousBounds = VisualTreeHelper.GetDescendantBounds(visual);
visual.Arrange(new Rect(0, 0, visual.ActualWidth, visual.ActualHeight));
//visual.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
//Rect previousBounds = VisualTreeHelper.GetDescendantBounds(visual);
//visual.Arrange(new Rect(0, 0, visual.ActualWidth, visual.ActualHeight));
element.Measure(new Size(element.ActualWidth, element.ActualHeight));
element.Arrange(new Rect(new Size(element.ActualWidth, element.ActualHeight)));
var bitmap = new RenderTargetBitmap(
(int)visual.ActualWidth,
(int)visual.ActualHeight,
(int)(visual.ActualWidth * scaleFactor),
(int)(visual.ActualHeight * scaleFactor),
96,
96,
PixelFormats.Pbgra32);
@@ -43,7 +48,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses
var frame = BitmapFrame.Create(bitmap);
encoder.Frames.Add(frame);
using (var stream = File.Create(fileName)) encoder.Save(stream);
visual.Arrange(previousBounds);
//visual.Arrange(previousBounds);
}
}
}