Change field viewer

This commit is contained in:
Evgeny Redikultsev
2025-12-13 20:13:45 +05:00
parent 681ab17781
commit f937b9f373
31 changed files with 730 additions and 246 deletions

View File

@@ -4,26 +4,24 @@ using StructureHelperCommon.Models.Calculators;
using StructureHelperCommon.Models.Forces; using StructureHelperCommon.Models.Forces;
using StructureHelperLogics.Models.CrossSections; using StructureHelperLogics.Models.CrossSections;
using StructureHelperLogics.NdmCalculations.Primitives; using StructureHelperLogics.NdmCalculations.Primitives;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataAccess.DTOs namespace DataAccess.DTOs
{ {
public class CrossSectionRepositoryDTO : ICrossSectionRepository public class CrossSectionRepositoryDTO : ICrossSectionRepository
{ {
private IRepositoryOperationsLogic operations;
[JsonProperty("Id")] [JsonProperty("Id")]
public Guid Id { get; set; } public Guid Id { get; set; }
[JsonProperty("HeadMaterials")] [JsonProperty("HeadMaterials")]
public List<IHeadMaterial> HeadMaterials { get; } = new(); public List<IHeadMaterial> HeadMaterials { get; } = [];
[JsonProperty("ForceActions")] [JsonProperty("ForceActions")]
public List<IForceAction> ForceActions { get; } = new(); public List<IForceAction> ForceActions { get; } = [];
[JsonProperty("Primitives")] [JsonProperty("Primitives")]
public List<INdmPrimitive> Primitives { get; } = new(); public List<INdmPrimitive> Primitives { get; } = [];
[JsonProperty("Calculators")] [JsonProperty("Calculators")]
public List<ICalculator> Calculators { get; } = new(); public List<ICalculator> Calculators { get; } = [];
[JsonIgnore]
public IRepositoryOperationsLogic Operations => operations ??= new RepositoryOperationsLogic(this);
} }
} }

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace FieldVisualizer.Entities.Values
{
public interface IValueLabel
{
bool IsActive { get; set; }
string Value { get; set; }
double X { get; set; }
double Y { get; set; }
}
}

View File

@@ -0,0 +1,184 @@
using FieldVisualizer.Entities.ColorMaps;
using FieldVisualizer.InfraStructures.Exceptions;
using FieldVisualizer.InfraStructures.Strings;
using FieldVisualizer.Services.ColorServices;
using FieldVisualizer.Windows.UserControls;
using StructureHelperCommon.Services;
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
namespace FieldVisualizer.Entities.Values.Primitives
{
internal class AddPrimitivesToCanvasLogic
{
private const int zoomFactor = 1000;
private IMathRoundLogic roundLogic = new SmartRoundLogic() { DigitQuant = 3 };
public Canvas WorkPlaneCanvas { get; set; }
public IValueRange ValueRange { get; set; }
public IColorMap ColorMap { get; set; }
public IEnumerable<IValueColorRange> ValueColorRanges { get; set; }
public double DX { get; set; }
public double DY { get; set; }
public void ProcessPrimitives(IEnumerable<IValuePrimitive> valuePrimitives)
{
foreach (var primitive in valuePrimitives)
{
if (primitive is IRectanglePrimitive rectanglePrimitive)
{
Rectangle rectangle = ProcessRectanglePrimitive(rectanglePrimitive);
WorkPlaneCanvas.Children.Add(rectangle);
}
else if (primitive is ICirclePrimitive circlePrimitive)
{
Ellipse ellipse = ProcessCirclePrimitive(circlePrimitive);
WorkPlaneCanvas.Children.Add(ellipse);
}
else if (primitive is ITrianglePrimitive triangle)
{
Path path = ProcessTrianglePrimitive(triangle);
WorkPlaneCanvas.Children.Add(path);
}
else { throw new FieldVisulizerException(ErrorStrings.PrimitiveTypeIsUnknown); }
}
}
private Path ProcessTrianglePrimitive(ITrianglePrimitive triangle)
{
// Create the PathFigure using triangle vertices.
var figure = new PathFigure
{
StartPoint = new Point(triangle.Point1.X * zoomFactor, -triangle.Point1.Y * zoomFactor),
IsClosed = true,
IsFilled = true
};
// Add the remaining vertices as LineSegments
var segments = new PathSegmentCollection
{
new LineSegment(new Point(triangle.Point2.X * zoomFactor, - triangle.Point2.Y * zoomFactor), true),
new LineSegment(new Point(triangle.Point3.X * zoomFactor, - triangle.Point3.Y * zoomFactor), true)
// Closing is handled by IsClosed = true, so we don't need to add a segment back to Point1
};
figure.Segments = segments;
// Create geometry and path
var geometry = new PathGeometry();
geometry.Figures.Add(figure);
var path = new Path
{
Data = geometry,
};
ProcessShape(path, triangle, 0, 0, false);
path.MouseLeftButtonDown += OnPathClicked;
return path;
}
private Rectangle ProcessRectanglePrimitive(IRectanglePrimitive rectanglePrimitive)
{
Rectangle rectangle = new Rectangle
{
Height = rectanglePrimitive.Height * zoomFactor,
Width = rectanglePrimitive.Width * zoomFactor
};
double addX = rectanglePrimitive.Width / 2 * zoomFactor;
double addY = rectanglePrimitive.Height / 2 * zoomFactor;
ProcessShape(rectangle, rectanglePrimitive, addX, addY, true);
rectangle.MouseLeftButtonDown += OnRectangleClicked;
return rectangle;
}
private Ellipse ProcessCirclePrimitive(ICirclePrimitive circlePrimitive)
{
Ellipse ellipse = new Ellipse
{
Height = circlePrimitive.Diameter * zoomFactor,
Width = circlePrimitive.Diameter * zoomFactor
};
double addX = circlePrimitive.Diameter / 2 * zoomFactor;
double addY = circlePrimitive.Diameter / 2 * zoomFactor;
ProcessShape(ellipse, circlePrimitive, addX, addY, true);
ellipse.MouseLeftButtonDown += OnEllipseClicked;
return ellipse;
}
private void ProcessShape(Shape shape, IValuePrimitive valuePrimitive, double addX, double addY, bool addCenter)
{
SolidColorBrush brush = new SolidColorBrush();
brush.Color = ColorOperations.GetColorByValue(ValueRange, ColorMap, valuePrimitive.Value);
foreach (var valueRange in ValueColorRanges)
{
if (valuePrimitive.Value >= valueRange.ExactValues.BottomValue & valuePrimitive.Value <= valueRange.ExactValues.TopValue & (!valueRange.IsActive))
{
brush.Color = Colors.Gray;
}
}
shape.ToolTip = roundLogic.RoundValue(valuePrimitive.Value);
shape.Tag = valuePrimitive;
shape.Fill = brush;
shape.StrokeThickness = 0.0;
double addLeft = -addX - DX * zoomFactor;
double addTop = -addY + DY * zoomFactor;
if (addCenter == true)
{
addLeft += valuePrimitive.CenterX * zoomFactor;
addTop -= valuePrimitive.CenterY * zoomFactor;
}
Canvas.SetLeft(shape, addLeft);
Canvas.SetTop(shape, addTop);
}
private void OnRectangleClicked(object sender, MouseButtonEventArgs e)
{
if (sender is not Rectangle rectangle)
return;
if (rectangle.Tag is not IRectanglePrimitive primitive)
return;
AddLabel(primitive);
e.Handled = true;
}
private void OnEllipseClicked(object sender, MouseButtonEventArgs e)
{
if (sender is not Ellipse ellipse)
return;
if (ellipse.Tag is not ICirclePrimitive primitive)
return;
AddLabel(primitive);
e.Handled = true;
}
private void AddLabel(IValuePrimitive primitive)
{
var value = roundLogic.RoundValue(primitive.Value);
var label = new ValueLabelControl()
{
Value = Convert.ToString(value),
Scale = WorkPlaneCanvas.Height / 600,
X = (primitive.CenterX - DX) * zoomFactor,
Y = (- primitive.CenterY + DY) * zoomFactor,
};
WorkPlaneCanvas.Children.Add(label);
}
private void OnPathClicked(object sender, MouseButtonEventArgs e)
{
if (sender is not Path path)
return;
if (path.Tag is not ITrianglePrimitive primitive)
return;
AddLabel(primitive);
e.Handled = true;
}
}
}

View File

@@ -1,14 +1,11 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FieldVisualizer.Entities.Values.Primitives namespace FieldVisualizer.Entities.Values.Primitives
{ {
public interface IPrimitiveSet public interface IPrimitiveSet
{ {
string Name { get; } string Name { get; set; }
string SubTitle { get; set; }
IEnumerable<IValuePrimitive> ValuePrimitives { get; } IEnumerable<IValuePrimitive> ValuePrimitives { get; }
} }

View File

@@ -8,12 +8,13 @@ namespace FieldVisualizer.Entities.Values.Primitives
{ {
public class PrimitiveSet : IPrimitiveSet public class PrimitiveSet : IPrimitiveSet
{ {
public string Name { get; set; } public string Name { get; set; } = string.Empty;
public string SubTitle { get; set; } = string.Empty;
public IEnumerable<IValuePrimitive> ValuePrimitives { get; set;} public IEnumerable<IValuePrimitive> ValuePrimitives { get; set;}
public PrimitiveSet() public PrimitiveSet()
{ {
Name = "New set of primitives";
ValuePrimitives = new List<IValuePrimitive>(); ValuePrimitives = new List<IValuePrimitive>();
} }
} }

View File

@@ -14,8 +14,8 @@ namespace FieldVisualizer.Entities.Values.Primitives
// --- Computed properties --- // --- Computed properties ---
// Centroid (geometric center) // Centroid (geometric center)
public double CenterX => (Point1.X + Point2.X + Point3.X) / 3.0; public double CenterX => (Point1.X + Point2.X + Point3.X) / 3d;
public double CenterY => (Point1.Y + Point2.Y + Point3.Y) / 3.0; public double CenterY => (Point1.Y + Point2.Y + Point3.Y) / 3d;
// Triangle area using determinant formula // Triangle area using determinant formula
public double Area => public double Area =>

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace FieldVisualizer.Entities.Values
{
public class ValueLabel : IValueLabel
{
public bool IsActive { get; set; } = true;
public string Value { get; set; } = string.Empty;
public double X { get; set; }
public double Y { get; set; }
}
}

View File

@@ -1,4 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup /> <PropertyGroup />
<ItemGroup>
<Compile Update="Windows\UserControls\ValueLabelControl.xaml.cs">
<SubType>Code</SubType>
</Compile>
</ItemGroup>
</Project> </Project>

View File

@@ -3,20 +3,16 @@ using FieldVisualizer.Entities.ColorMaps.Factories;
using FieldVisualizer.Entities.Values; using FieldVisualizer.Entities.Values;
using FieldVisualizer.Entities.Values.Primitives; using FieldVisualizer.Entities.Values.Primitives;
using FieldVisualizer.Infrastructure.Commands; using FieldVisualizer.Infrastructure.Commands;
using FieldVisualizer.InfraStructures.Exceptions;
using FieldVisualizer.InfraStructures.Strings;
using FieldVisualizer.Services.ColorServices; using FieldVisualizer.Services.ColorServices;
using FieldVisualizer.Services.PrimitiveServices; using FieldVisualizer.Services.PrimitiveServices;
using FieldVisualizer.Services.ValueRanges; using FieldVisualizer.Services.ValueRanges;
using FieldVisualizer.Windows.UserControls; using FieldVisualizer.Windows.UserControls;
using StructureHelperCommon.Services;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Ink;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Shapes; using System.Windows.Shapes;
@@ -25,8 +21,26 @@ namespace FieldVisualizer.ViewModels.FieldViewerViewModels
{ {
public class FieldViewerViewModel : ViewModelBase, IDataErrorInfo public class FieldViewerViewModel : ViewModelBase, IDataErrorInfo
{ {
private IMathRoundLogic roundLogic = new SmartRoundLogic() { DigitQuant = 3 }; private ICommand setCrossLineCommand;
public ICommand RebuildCommand { get; } private IPrimitiveSet primitiveSet;
private double dX, dY;
private ColorMapsTypes _ColorMapType = ColorMapsTypes.LiraSpectrum;
private IColorMap _ColorMap;
private IValueRange valueRange;
private IEnumerable<IValueRange> valueRanges;
private IEnumerable<IValueColorRange> valueColorRanges;
private bool setMinValue;
private bool setMaxValue;
private double crossLineX;
private double crossLineY;
private double sumAboveLine;
private double sumUnderLine;
private Line previosLine;
const int RangeNumber = 16;
private const int zoomFactor = 1000;
private RelayCommand rebuildCommand;
public ICommand RebuildCommand => rebuildCommand ??= new RelayCommand(o => ProcessPrimitives(), o => PrimitiveValidation());
public ICommand ZoomInCommand { get; } public ICommand ZoomInCommand { get; }
public ICommand ZoomOutCommand { get; } public ICommand ZoomOutCommand { get; }
public ICommand ChangeColorMapCommand { get; } public ICommand ChangeColorMapCommand { get; }
@@ -148,6 +162,9 @@ namespace FieldVisualizer.ViewModels.FieldViewerViewModels
public double SumUnderLine { get => sumUnderLine; set => SetProperty(ref sumUnderLine, value); } public double SumUnderLine { get => sumUnderLine; set => SetProperty(ref sumUnderLine, value); }
public string Error { get; } public string Error { get; }
public string Title { get; set; }
public string SubTitle { get; set; }
public string this[string columnName] public string this[string columnName]
{ {
get get
@@ -157,27 +174,10 @@ namespace FieldVisualizer.ViewModels.FieldViewerViewModels
} }
} }
private ICommand setCrossLineCommand;
private IPrimitiveSet primitiveSet;
private double dX, dY;
private ColorMapsTypes _ColorMapType;
private IColorMap _ColorMap;
private IValueRange valueRange;
private IEnumerable<IValueRange> valueRanges;
private IEnumerable<IValueColorRange> valueColorRanges;
private bool setMinValue;
private bool setMaxValue;
private double crossLineX;
private double crossLineY;
private double sumAboveLine;
private double sumUnderLine;
private Line previosLine;
const int RangeNumber = 16;
public FieldViewerViewModel() public FieldViewerViewModel()
{ {
_ColorMapType = ColorMapsTypes.LiraSpectrum;
RebuildCommand = new RelayCommand(o => ProcessPrimitives(), o => PrimitiveValidation());
ZoomInCommand = new RelayCommand(o => Zoom(1.2), o => PrimitiveValidation()); ZoomInCommand = new RelayCommand(o => Zoom(1.2), o => PrimitiveValidation());
ZoomOutCommand = new RelayCommand(o => Zoom(0.8), o => PrimitiveValidation()); ZoomOutCommand = new RelayCommand(o => Zoom(0.8), o => PrimitiveValidation());
ChangeColorMapCommand = new RelayCommand(o => ChangeColorMap(), o => PrimitiveValidation()); ChangeColorMapCommand = new RelayCommand(o => ChangeColorMap(), o => PrimitiveValidation());
@@ -207,114 +207,29 @@ namespace FieldVisualizer.ViewModels.FieldViewerViewModels
private void ProcessPrimitives() private void ProcessPrimitives()
{ {
WorkPlaneCanvas.Children.Clear(); WorkPlaneCanvas.Children.Clear();
double sizeX = PrimitiveOperations.GetSizeX(PrimitiveSet.ValuePrimitives); Title = PrimitiveSet.Name;
double sizeY = PrimitiveOperations.GetSizeY(PrimitiveSet.ValuePrimitives); OnPropertyChanged(nameof(Title));
SubTitle = PrimitiveSet.SubTitle;
OnPropertyChanged(nameof(SubTitle));
double sizeX = PrimitiveOperations.GetSizeX(PrimitiveSet.ValuePrimitives) * zoomFactor;
double sizeY = PrimitiveOperations.GetSizeY(PrimitiveSet.ValuePrimitives) * zoomFactor;
dX = PrimitiveOperations.GetMinMaxX(PrimitiveSet.ValuePrimitives)[0]; dX = PrimitiveOperations.GetMinMaxX(PrimitiveSet.ValuePrimitives)[0];
dY = PrimitiveOperations.GetMinMaxY(PrimitiveSet.ValuePrimitives)[1]; dY = PrimitiveOperations.GetMinMaxY(PrimitiveSet.ValuePrimitives)[1];
WorkPlaneCanvas.Width = Math.Abs(sizeX); WorkPlaneCanvas.Width = Math.Abs(sizeX);
WorkPlaneCanvas.Height = Math.Abs(sizeY); WorkPlaneCanvas.Height = Math.Abs(sizeY);
WorkPlaneBox.Width = ScrolWidth - 50; WorkPlaneBox.Width = (ScrolWidth - 50);
WorkPlaneBox.Height = ScrolHeight - 50; WorkPlaneBox.Height = (ScrolHeight - 50);
foreach (var primitive in PrimitiveSet.ValuePrimitives) var logic = new AddPrimitivesToCanvasLogic()
{ {
if (primitive is IRectanglePrimitive rectanglePrimitive) WorkPlaneCanvas = WorkPlaneCanvas,
{ DX = dX,
Rectangle rectangle = ProcessRectanglePrimitive(rectanglePrimitive); DY = dY,
WorkPlaneCanvas.Children.Add(rectangle); ValueRange = valueRange,
} ColorMap = _ColorMap,
else if (primitive is ICirclePrimitive circlePrimitive) ValueColorRanges = valueColorRanges,
{
Ellipse ellipse = ProcessCirclePrimitive(circlePrimitive);
WorkPlaneCanvas.Children.Add(ellipse);
}
else if (primitive is ITrianglePrimitive triangle)
{
Path path = ProcessTrianglePrimitive(triangle);
WorkPlaneCanvas.Children.Add(path);
}
else { throw new FieldVisulizerException(ErrorStrings.PrimitiveTypeIsUnknown); }
}
}
private Path ProcessTrianglePrimitive(ITrianglePrimitive triangle)
{
// Create the PathFigure using triangle vertices.
var figure = new PathFigure
{
StartPoint = new Point(triangle.Point1.X, - triangle.Point1.Y),
IsClosed = true,
IsFilled = true
}; };
logic.ProcessPrimitives(PrimitiveSet.ValuePrimitives);
// Add the remaining vertices as LineSegments
var segments = new PathSegmentCollection
{
new LineSegment(new Point(triangle.Point2.X, - triangle.Point2.Y), true),
new LineSegment(new Point(triangle.Point3.X, - triangle.Point3.Y), true)
// Closing is handled by IsClosed = true, so we don't need to add a segment back to Point1
};
figure.Segments = segments;
// Create geometry and path
var geometry = new PathGeometry();
geometry.Figures.Add(figure);
var path = new Path
{
Data = geometry,
};
ProcessShape(path, triangle, 0, 0, false);
return path;
}
private Rectangle ProcessRectanglePrimitive(IRectanglePrimitive rectanglePrimitive)
{
Rectangle rectangle = new Rectangle
{
Height = rectanglePrimitive.Height,
Width = rectanglePrimitive.Width
};
double addX = rectanglePrimitive.Width / 2;
double addY = rectanglePrimitive.Height / 2;
ProcessShape(rectangle, rectanglePrimitive, addX, addY, true);
return rectangle;
}
private Ellipse ProcessCirclePrimitive(ICirclePrimitive circlePrimitive)
{
Ellipse ellipse = new Ellipse
{
Height = circlePrimitive.Diameter,
Width = circlePrimitive.Diameter
};
double addX = circlePrimitive.Diameter / 2;
double addY = circlePrimitive.Diameter / 2;
ProcessShape(ellipse, circlePrimitive, addX, addY, true);
return ellipse;
}
private void ProcessShape(Shape shape, IValuePrimitive valuePrimitive, double addX, double addY, bool addCenter)
{
SolidColorBrush brush = new SolidColorBrush();
brush.Color = ColorOperations.GetColorByValue(valueRange, _ColorMap, valuePrimitive.Value);
foreach (var valueRange in valueColorRanges)
{
if (valuePrimitive.Value >= valueRange.ExactValues.BottomValue & valuePrimitive.Value <= valueRange.ExactValues.TopValue & (!valueRange.IsActive))
{
brush.Color = Colors.Gray;
}
}
shape.ToolTip = roundLogic.RoundValue(valuePrimitive.Value);
shape.Tag = valuePrimitive;
shape.Fill = brush;
double addLeft = - addX - dX;
double addTop = - addY + dY;
if (addCenter == true)
{
addLeft += valuePrimitive.CenterX;
addTop -= valuePrimitive.CenterY;
}
Canvas.SetLeft(shape, addLeft);
Canvas.SetTop(shape, addTop);
} }
private void Zoom(double coefficient) private void Zoom(double coefficient)
{ {

View File

@@ -24,7 +24,12 @@
<Button x:Name="ZoomOutButton" Content="ZoomOut" Command="{Binding ZoomOutCommand}"/> <Button x:Name="ZoomOutButton" Content="ZoomOut" Command="{Binding ZoomOutCommand}"/>
<Button x:Name="ChangeColorMapButton" Content="ColorMap" Command="{Binding ChangeColorMapCommand}"/> <Button x:Name="ChangeColorMapButton" Content="ColorMap" Command="{Binding ChangeColorMapCommand}"/>
</StackPanel> </StackPanel>
<ScrollViewer Name="WorkPlaneViewer" Grid.Row="1" HorizontalScrollBarVisibility="Visible" SizeChanged="WorkPlaneViewer_SizeChanged"> <Grid Grid.Row="1">
<StackPanel Panel.ZIndex="1">
<TextBlock Text="{Binding Title}" FontWeight="Bold"/>
<TextBlock Text="{Binding SubTitle}"/>
</StackPanel>
<ScrollViewer Name="WorkPlaneViewer" HorizontalScrollBarVisibility="Visible" SizeChanged="WorkPlaneViewer_SizeChanged">
<ScrollViewer.Background> <ScrollViewer.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black"/> <GradientStop Color="Black"/>
@@ -33,11 +38,16 @@
</LinearGradientBrush> </LinearGradientBrush>
</ScrollViewer.Background> </ScrollViewer.Background>
<Viewbox Name="WorkPlaneBox" Margin="10"> <Viewbox Name="WorkPlaneBox" Margin="10">
<Canvas Name="WorkPlaneCanvas"> <Grid>
<Canvas x:Name="LabelCanvas"/>
<Canvas x:Name="WorkPlaneCanvas">
</Canvas> </Canvas>
</Grid>
</Viewbox> </Viewbox>
</ScrollViewer> </ScrollViewer>
</Grid> </Grid>
</Grid>
<ScrollViewer Grid.Column="2"> <ScrollViewer Grid.Column="2">
<StackPanel> <StackPanel>
<Expander Header="Color legend" IsExpanded="True"> <Expander Header="Color legend" IsExpanded="True">

View File

@@ -0,0 +1,27 @@
<UserControl x:Class="FieldVisualizer.Windows.UserControls.ValueLabelControl"
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:FieldVisualizer.Windows.UserControls"
mc:Ignorable="d"
d:DesignHeight="100" d:DesignWidth="100"
Name="ThisControl">
<Grid DataContext="{Binding ElementName=ThisControl}">
<Canvas>
<Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="{Binding Scale}" ScaleY="{Binding Scale}"/>
<TranslateTransform X="{Binding X}" Y="{Binding Y}"/>
</TransformGroup>
</Canvas.RenderTransform>
<Path Data="M 0 0 l 20 -25 v 16 z" Fill="AntiqueWhite"/>
<Canvas>
<Canvas.RenderTransform>
<TranslateTransform X="20" Y="-25"/>
</Canvas.RenderTransform>
<TextBlock MinWidth="25" Text="{Binding Value}" Background="AntiqueWhite"/>
</Canvas>
</Canvas>
</Grid>
</UserControl>

View File

@@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.Text;
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 FieldVisualizer.Windows.UserControls
{
/// <summary>
/// Interaction logic for ValueLabelControl.xaml
/// </summary>
public partial class ValueLabelControl : UserControl
{
public string Value
{
get { return (string)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
// Using a DependencyProperty as the backing store for Value. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register(nameof(Value), typeof(string), typeof(ValueLabelControl), new PropertyMetadata("Label value"));
public double X
{
get { return (double)GetValue(XProperty); }
set { SetValue(XProperty, value); }
}
// Using a DependencyProperty as the backing store for X. This enables animation, styling, binding, etc...
public static readonly DependencyProperty XProperty =
DependencyProperty.Register(nameof(X), typeof(double), typeof(ValueLabelControl), new PropertyMetadata(0.0));
public double Y
{
get { return (double)GetValue(YProperty); }
set { SetValue(YProperty, value); }
}
// Using a DependencyProperty as the backing store for Y. This enables animation, styling, binding, etc...
public static readonly DependencyProperty YProperty =
DependencyProperty.Register(nameof(Y), typeof(double), typeof(ValueLabelControl), new PropertyMetadata(0.0));
public double Scale
{
get { return (double)GetValue(ScaleProperty); }
set { SetValue(ScaleProperty, value); }
}
// Using a DependencyProperty as the backing store for Scale. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ScaleProperty =
DependencyProperty.Register(nameof(Scale), typeof(double), typeof(ValueLabelControl), new PropertyMetadata(0.0));
public ValueLabelControl()
{
InitializeComponent();
}
}
}

View File

@@ -30,7 +30,7 @@ namespace StructureHelper.Infrastructure
OnPropertyChanged(nameof(Camera)); OnPropertyChanged(nameof(Camera));
} }
} }
public System.Windows.Media.Color AmbientLightColor public Color AmbientLightColor
{ {
get => ambientLightColor; get => ambientLightColor;
set set
@@ -39,7 +39,7 @@ namespace StructureHelper.Infrastructure
OnPropertyChanged(nameof(AmbientLightColor)); OnPropertyChanged(nameof(AmbientLightColor));
} }
} }
public System.Windows.Media.Color DirectionalLightColor { get; set; } public Color DirectionalLightColor { get; set; }
public Vector3D DirectionalLightDirection public Vector3D DirectionalLightDirection
{ {
get => directionalLightDirection; get => directionalLightDirection;
@@ -87,6 +87,7 @@ namespace StructureHelper.Infrastructure
OnPropertyChanged(nameof(Title)); OnPropertyChanged(nameof(Title));
} }
} }
public string SubTitle public string SubTitle
{ {
get => subTitle; get => subTitle;

View File

@@ -17,6 +17,7 @@ namespace StructureHelper.Services.ResultViewers
static IUnit unitStress = UnitLogic.GetUnit(UnitTypes.Stress); static IUnit unitStress = UnitLogic.GetUnit(UnitTypes.Stress);
static IUnit unitLength = UnitLogic.GetUnit(UnitTypes.Length, "mm"); static IUnit unitLength = UnitLogic.GetUnit(UnitTypes.Length, "mm");
static IUnit unitStrain = UnitLogic.GetUnit(UnitTypes.Strain);
public static List<CrackResultFunc> GetResultFuncs() public static List<CrackResultFunc> GetResultFuncs()
{ {
@@ -69,28 +70,28 @@ namespace StructureHelper.Services.ResultViewers
Name = "Long rebar strain", Name = "Long rebar strain",
ResultFunction = (IRebarCrackResult rebar) => rebar.LongTermResult.RebarStressResult.RebarStrain, ResultFunction = (IRebarCrackResult rebar) => rebar.LongTermResult.RebarStressResult.RebarStrain,
UnitFactor = 1d, UnitFactor = 1d,
UnitName = string.Empty UnitName = unitStrain.Name
}, },
new() new()
{ {
Name = "Short rebar strain", Name = "Short rebar strain",
ResultFunction = (IRebarCrackResult rebar) => rebar.ShortTermResult.RebarStressResult.RebarStrain, ResultFunction = (IRebarCrackResult rebar) => rebar.ShortTermResult.RebarStressResult.RebarStrain,
UnitFactor = 1d, UnitFactor = 1d,
UnitName = string.Empty UnitName = unitStrain.Name
}, },
new() new()
{ {
Name = "Long concrete strain", Name = "Long concrete strain",
ResultFunction = (IRebarCrackResult rebar) => rebar.LongTermResult.RebarStressResult.ConcreteStrain, ResultFunction = (IRebarCrackResult rebar) => rebar.LongTermResult.RebarStressResult.ConcreteStrain,
UnitFactor = 1d, UnitFactor = 1d,
UnitName = string.Empty UnitName = unitStrain.Name
}, },
new() new()
{ {
Name = "Short concrete strain", Name = "Short concrete strain",
ResultFunction = (IRebarCrackResult rebar) => rebar.ShortTermResult.RebarStressResult.ConcreteStrain, ResultFunction = (IRebarCrackResult rebar) => rebar.ShortTermResult.RebarStressResult.ConcreteStrain,
UnitFactor = 1d, UnitFactor = 1d,
UnitName = string.Empty UnitName = unitStrain.Name
} }
}; };
return results; return results;

View File

@@ -1,13 +1,8 @@
using LoaderCalculator.Logics; using LoaderCalculator.Logics;
using StructureHelper.Infrastructure.UI.Converters.Units;
using StructureHelperCommon.Infrastructures.Enums; using StructureHelperCommon.Infrastructures.Enums;
using StructureHelperCommon.Infrastructures.Exceptions; using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Services.Units; using StructureHelperCommon.Services.Units;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelper.Services.ResultViewers namespace StructureHelper.Services.ResultViewers
{ {
@@ -25,6 +20,7 @@ namespace StructureHelper.Services.ResultViewers
static IUnit unitStress = unitLogic.GetUnit(UnitTypes.Stress); static IUnit unitStress = unitLogic.GetUnit(UnitTypes.Stress);
static IUnit unitMoment = unitLogic.GetUnit(UnitTypes.Moment); static IUnit unitMoment = unitLogic.GetUnit(UnitTypes.Moment);
static IUnit unitCurvature = unitLogic.GetUnit(UnitTypes.Curvature); static IUnit unitCurvature = unitLogic.GetUnit(UnitTypes.Curvature);
static IUnit unitStrain = unitLogic.GetUnit(UnitTypes.Strain);
static readonly IStressLogic stressLogic = new StressLogic(); static readonly IStressLogic stressLogic = new StressLogic();
public static List<ForceResultFunc> GetResultFuncs(FuncsTypes funcsType = FuncsTypes.Full) public static List<ForceResultFunc> GetResultFuncs(FuncsTypes funcsType = FuncsTypes.Full)
@@ -57,12 +53,12 @@ namespace StructureHelper.Services.ResultViewers
private static List<ForceResultFunc> GetStrainResultFuncs() private static List<ForceResultFunc> GetStrainResultFuncs()
{ {
List<ForceResultFunc> resultFuncs = []; List<ForceResultFunc> resultFuncs = [];
resultFuncs.Add(new ForceResultFunc() { Name = "Section Strain", ResultFunction = stressLogic.GetSectionStrain }); resultFuncs.Add(new ForceResultFunc() { Name = "Section Strain", UnitName = unitStrain.Name, ResultFunction = stressLogic.GetSectionStrain });
resultFuncs.Add(new ForceResultFunc() { Name = "Total Strain", ResultFunction = stressLogic.GetTotalStrain }); resultFuncs.Add(new ForceResultFunc() { Name = "Total Strain", UnitName = unitStrain.Name, ResultFunction = stressLogic.GetTotalStrain });
resultFuncs.Add(new ForceResultFunc() { Name = "Prestrain", ResultFunction = stressLogic.GetPrestrain }); resultFuncs.Add(new ForceResultFunc() { Name = "Prestrain", UnitName = unitStrain.Name, ResultFunction = stressLogic.GetPrestrain });
resultFuncs.Add(new ForceResultFunc() { Name = "Elastic Strain", ResultFunction = stressLogic.GetElasticStrain }); resultFuncs.Add(new ForceResultFunc() { Name = "Elastic Strain", UnitName = unitStrain.Name, ResultFunction = stressLogic.GetElasticStrain });
resultFuncs.Add(new ForceResultFunc() { Name = "Plastic Strain", ResultFunction = stressLogic.GetPlasticStrain }); resultFuncs.Add(new ForceResultFunc() { Name = "Plastic Strain", UnitName = unitStrain.Name, ResultFunction = stressLogic.GetPlasticStrain });
resultFuncs.Add(new ForceResultFunc() { Name = "Limit Strain Ratio", ResultFunction = stressLogic.GetLimitStrainRatio }); resultFuncs.Add(new ForceResultFunc() { Name = "Limit Strain Ratio", UnitName = unitStrain.Name, ResultFunction = stressLogic.GetLimitStrainRatio });
return resultFuncs; return resultFuncs;
} }
private static List<ForceResultFunc> GetStressResultFuncs() private static List<ForceResultFunc> GetStressResultFuncs()

View File

@@ -18,7 +18,6 @@ namespace StructureHelper.Services.ResultViewers
primitiveSet = GetBaseDevelopmentLength(strainMatrix, limitState, calcTerm, ndmPrimitives); primitiveSet = GetBaseDevelopmentLength(strainMatrix, limitState, calcTerm, ndmPrimitives);
primitiveSets.Add(primitiveSet); primitiveSets.Add(primitiveSet);
primitiveSet = GetDevelopmentLength(strainMatrix, limitState, calcTerm, ndmPrimitives, true); primitiveSet = GetDevelopmentLength(strainMatrix, limitState, calcTerm, ndmPrimitives, true);
primitiveSet.Name = "Development length full strength";
primitiveSets.Add(primitiveSet); primitiveSets.Add(primitiveSet);
primitiveSet = GetDevelopmentLength(strainMatrix, limitState, calcTerm, ndmPrimitives,false); primitiveSet = GetDevelopmentLength(strainMatrix, limitState, calcTerm, ndmPrimitives,false);
primitiveSet.Name = "Development length actual stress"; primitiveSet.Name = "Development length actual stress";
@@ -69,7 +68,11 @@ namespace StructureHelper.Services.ResultViewers
private static PrimitiveSet GetBaseDevelopmentLength(IStrainMatrix strainMatrix, LimitStates limitState, CalcTerms calcTerm, IEnumerable<INdmPrimitive> ndmPrimitives) private static PrimitiveSet GetBaseDevelopmentLength(IStrainMatrix strainMatrix, LimitStates limitState, CalcTerms calcTerm, IEnumerable<INdmPrimitive> ndmPrimitives)
{ {
PrimitiveSet primitiveSet = new PrimitiveSet() { Name = "Base Development Length"}; PrimitiveSet primitiveSet = new PrimitiveSet()
{
Name = "Base Development Length",
SubTitle = "mm"
};
List<IValuePrimitive> primitives = new List<IValuePrimitive>(); List<IValuePrimitive> primitives = new List<IValuePrimitive>();
foreach (var item in ndmPrimitives) foreach (var item in ndmPrimitives)
{ {
@@ -88,7 +91,11 @@ namespace StructureHelper.Services.ResultViewers
} }
private static PrimitiveSet GetDevelopmentLength(IStrainMatrix strainMatrix, LimitStates limitState, CalcTerms calcTerm, IEnumerable<INdmPrimitive> ndmPrimitives, bool fullStrength) private static PrimitiveSet GetDevelopmentLength(IStrainMatrix strainMatrix, LimitStates limitState, CalcTerms calcTerm, IEnumerable<INdmPrimitive> ndmPrimitives, bool fullStrength)
{ {
PrimitiveSet primitiveSet = new PrimitiveSet(); PrimitiveSet primitiveSet = new PrimitiveSet()
{
Name = "Development length full strength",
SubTitle = "mm"
};
List<IValuePrimitive> primitives = new List<IValuePrimitive>(); List<IValuePrimitive> primitives = new List<IValuePrimitive>();
foreach (var item in ndmPrimitives) foreach (var item in ndmPrimitives)
{ {

View File

@@ -28,7 +28,11 @@ namespace StructureHelper.Services.ResultViewers
List<IPrimitiveSet> primitiveSets = new List<IPrimitiveSet>(); List<IPrimitiveSet> primitiveSets = new List<IPrimitiveSet>();
foreach (var valDelegate in resultFuncs) foreach (var valDelegate in resultFuncs)
{ {
PrimitiveSet primitiveSet = new PrimitiveSet() { Name = valDelegate.Name }; PrimitiveSet primitiveSet = new PrimitiveSet()
{
Name = valDelegate.Name,
SubTitle = valDelegate.UnitName
};
List<IValuePrimitive> primitives = new List<IValuePrimitive>(); List<IValuePrimitive> primitives = new List<IValuePrimitive>();
foreach (INdm ndm in ndms) foreach (INdm ndm in ndms)
{ {
@@ -45,7 +49,11 @@ namespace StructureHelper.Services.ResultViewers
List<IPrimitiveSet> primitiveSets = new List<IPrimitiveSet>(); List<IPrimitiveSet> primitiveSets = new List<IPrimitiveSet>();
foreach (var valDelegate in resultFuncs) foreach (var valDelegate in resultFuncs)
{ {
PrimitiveSet primitiveSet = new PrimitiveSet() { Name = valDelegate.Name }; PrimitiveSet primitiveSet = new PrimitiveSet()
{
Name = valDelegate.Name,
SubTitle = valDelegate.UnitName
};
List<IValuePrimitive> primitives = new List<IValuePrimitive>(); List<IValuePrimitive> primitives = new List<IValuePrimitive>();
foreach (var rebarResult in rebarResults) foreach (var rebarResult in rebarResults)
{ {

View File

@@ -5,9 +5,6 @@ using StructureHelper.Windows.ViewModels.Errors;
using StructureHelperLogics.NdmCalculations.Cracking; using StructureHelperLogics.NdmCalculations.Cracking;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews
{ {

View File

@@ -53,6 +53,7 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu
{ {
selectedPrimitiveSet = value; selectedPrimitiveSet = value;
ViewportViewModel.Title = selectedPrimitiveSet.Name; ViewportViewModel.Title = selectedPrimitiveSet.Name;
ViewportViewModel.SubTitle = selectedPrimitiveSet.SubTitle;
OnPropertyChanged(nameof(SelectedPrimitiveSet)); OnPropertyChanged(nameof(SelectedPrimitiveSet));
RebuildPrimitives(); RebuildPrimitives();
} }

View File

@@ -3,11 +3,11 @@ using StructureHelper.Infrastructure.Enums;
using StructureHelper.Infrastructure.UI.DataContexts; using StructureHelper.Infrastructure.UI.DataContexts;
using StructureHelper.Windows.PrimitivePropertiesWindow; using StructureHelper.Windows.PrimitivePropertiesWindow;
using StructureHelper.Windows.Services; using StructureHelper.Windows.Services;
using StructureHelper.Windows.ViewModels.Errors;
using StructureHelperCommon.Infrastructures.Exceptions; using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Models.Calculators; using StructureHelperCommon.Models.Calculators;
using StructureHelperCommon.Models.Shapes; using StructureHelperCommon.Models.Shapes;
using StructureHelperLogics.Models.CrossSections; using StructureHelperLogics.Models.CrossSections;
using StructureHelperLogics.Models.Primitives;
using StructureHelperLogics.NdmCalculations.Analyses.ByForces; using StructureHelperLogics.NdmCalculations.Analyses.ByForces;
using StructureHelperLogics.NdmCalculations.Analyses.Curvatures; using StructureHelperLogics.NdmCalculations.Analyses.Curvatures;
using StructureHelperLogics.NdmCalculations.Analyses.ValueDiagrams; using StructureHelperLogics.NdmCalculations.Analyses.ValueDiagrams;
@@ -77,7 +77,7 @@ namespace StructureHelper.Windows.ViewModels.NdmCrossSections
var dialogResult = MessageBox.Show("Delete all primitives?", "Please, confirm deleting", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); var dialogResult = MessageBox.Show("Delete all primitives?", "Please, confirm deleting", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
if (dialogResult == DialogResult.Yes) if (dialogResult == DialogResult.Yes)
{ {
ClearRepository(); SafetyProcessor.RunSafeProcess(ClearRepository, "Error of deleting primitives");
Refresh(); Refresh();
OnPropertyChanged(nameof(Items)); OnPropertyChanged(nameof(Items));
OnPropertyChanged(nameof(PrimitivesCount)); OnPropertyChanged(nameof(PrimitivesCount));
@@ -86,30 +86,7 @@ namespace StructureHelper.Windows.ViewModels.NdmCrossSections
private void ClearRepository() private void ClearRepository()
{ {
repository.Primitives.Clear(); repository.Operations.Primitives.RemoveAll();
foreach (var calculator in repository.Calculators)
{
if (calculator is IForceCalculator forceCalculator)
{
forceCalculator.InputData.Primitives.Clear();
}
else if (calculator is ICrackCalculator crackCalculator)
{
crackCalculator.InputData.Primitives.Clear();
}
else if (calculator is IValueDiagramCalculator valueDiagramCalculator)
{
valueDiagramCalculator.InputData.Primitives.Clear();
}
else if (calculator is ICurvatureCalculator curvatureCalculator)
{
curvatureCalculator.InputData.Primitives.Clear();
}
else
{
// skip
}
}
Items.Clear(); Items.Clear();
} }
@@ -139,29 +116,6 @@ namespace StructureHelper.Windows.ViewModels.NdmCrossSections
private void RemoveFromRepository(PrimitiveBase item) private void RemoveFromRepository(PrimitiveBase item)
{ {
repository.Primitives.Remove(item.NdmPrimitive); repository.Primitives.Remove(item.NdmPrimitive);
foreach (var calculator in repository.Calculators)
{
if (calculator is IForceCalculator forceCalculator)
{
forceCalculator.InputData.Primitives.Remove(item.NdmPrimitive);
}
else if (calculator is ICrackCalculator crackCalculator)
{
crackCalculator.InputData.Primitives.Remove(item.NdmPrimitive);
}
else if (calculator is IValueDiagramCalculator valueDiagramCalculator)
{
valueDiagramCalculator.InputData.Primitives.Remove(item.NdmPrimitive);
}
else if (calculator is ICurvatureCalculator curvatureCalculator)
{
curvatureCalculator.InputData.Primitives.Remove(item.NdmPrimitive);
}
else
{
// skip
}
}
Items.Remove(item); Items.Remove(item);
} }

View File

@@ -8,6 +8,7 @@
Force, Force,
Moment, Moment,
Curvature, Curvature,
DistributedLoad DistributedLoad,
Strain
} }
} }

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace StructureHelperCommon.Infrastructures.Interfaces
{
public interface IRepositoryOperation<T, V>
{
void RemoveAll();
void Remove(V entity);
void Remove(IEnumerable<V> entities);
}
}

View File

@@ -25,6 +25,7 @@ namespace StructureHelperCommon.Services.Units
{ UnitTypes.Stress, "MPa"}, { UnitTypes.Stress, "MPa"},
{ UnitTypes.Curvature, "1/m"}, { UnitTypes.Curvature, "1/m"},
{ UnitTypes.DistributedLoad, "kN/m" }, { UnitTypes.DistributedLoad, "kN/m" },
{ UnitTypes.Strain, "Dimensionless" },
}; };
} }

View File

@@ -42,6 +42,8 @@ namespace StructureHelperCommon.Services.Units
units.Add(new Unit() { UnitType = type, Name = "N/m", Multiplyer = 1d }); units.Add(new Unit() { UnitType = type, Name = "N/m", Multiplyer = 1d });
units.Add(new Unit() { UnitType = type, Name = "kN/m", Multiplyer = 1e-3d }); units.Add(new Unit() { UnitType = type, Name = "kN/m", Multiplyer = 1e-3d });
units.Add(new Unit() { UnitType = type, Name = "MN/m", Multiplyer = 1e-6d }); units.Add(new Unit() { UnitType = type, Name = "MN/m", Multiplyer = 1e-6d });
type = UnitTypes.Strain;
units.Add(new Unit() { UnitType = type, Name = "Dimensionless", Multiplyer = 1d });
return units; return units;
} }
} }

View File

@@ -7,12 +7,16 @@ namespace StructureHelperLogics.Models.CrossSections
{ {
public class CrossSectionRepository : ICrossSectionRepository public class CrossSectionRepository : ICrossSectionRepository
{ {
private RepositoryOperationsLogic operations;
public Guid Id { get; } public Guid Id { get; }
public List<IForceAction> ForceActions { get; private set; } = new(); public List<IForceAction> ForceActions { get; private set; } = new();
public List<IHeadMaterial> HeadMaterials { get; private set; } = new(); public List<IHeadMaterial> HeadMaterials { get; private set; } = new();
public List<INdmPrimitive> Primitives { get; } = new(); public List<INdmPrimitive> Primitives { get; } = new();
public List<ICalculator> Calculators { get; private set; } = new(); public List<ICalculator> Calculators { get; private set; } = new();
public IRepositoryOperationsLogic Operations => operations ??= new RepositoryOperationsLogic(this);
public CrossSectionRepository(Guid id) public CrossSectionRepository(Guid id)
{ {
Id = id; Id = id;

View File

@@ -1,13 +1,15 @@
using StructureHelperCommon.Infrastructures.Interfaces; using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models.Calculators; using StructureHelperCommon.Models.Calculators;
using StructureHelperCommon.Models.Forces;
using StructureHelperLogics.Models.Materials; using StructureHelperLogics.Models.Materials;
using StructureHelperLogics.NdmCalculations.Primitives; using StructureHelperLogics.NdmCalculations.Primitives;
namespace StructureHelperLogics.Models.CrossSections namespace StructureHelperLogics.Models.CrossSections
{ {
/// <summary>
/// Repository of members of cross-section
/// </summary>
public interface ICrossSectionRepository : ISaveable, IHasHeadMaterials, IHasForcesAndPrimitives, IHasCalculators public interface ICrossSectionRepository : ISaveable, IHasHeadMaterials, IHasForcesAndPrimitives, IHasCalculators
{ {
IRepositoryOperationsLogic Operations { get; }
} }
} }

View File

@@ -0,0 +1,13 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperLogics.NdmCalculations.Primitives;
using System;
using System.Collections.Generic;
using System.Text;
namespace StructureHelperLogics.Models.CrossSections
{
public interface IRepositoryOperationsLogic
{
IRepositoryOperation<ICrossSectionRepository, INdmPrimitive> Primitives { get; }
}
}

View File

@@ -0,0 +1,18 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperLogics.NdmCalculations.Primitives;
namespace StructureHelperLogics.Models.CrossSections
{
public class RepositoryOperationsLogic : IRepositoryOperationsLogic
{
private ICrossSectionRepository repository;
private RepositoryPrimitiveOperation primitiveLogic;
public RepositoryOperationsLogic(ICrossSectionRepository repository)
{
this.repository = repository;
}
public IRepositoryOperation<ICrossSectionRepository, INdmPrimitive> Primitives => primitiveLogic ??= new RepositoryPrimitiveOperation(repository);
}
}

View File

@@ -1,18 +1,13 @@
using LoaderCalculator.Data.Matrix; using LoaderCalculator;
using LoaderCalculator; using LoaderCalculator.Data.Matrix;
using LoaderCalculator.Data.Ndms;
using LoaderCalculator.Data.ResultData; using LoaderCalculator.Data.ResultData;
using LoaderCalculator.Data.SourceData; using LoaderCalculator.Data.SourceData;
using LoaderCalculator.Logics;
using StructureHelperCommon.Models; using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Calculators; using StructureHelperCommon.Models.Calculators;
using StructureHelperCommon.Models.Loggers; using StructureHelperCommon.Models.Loggers;
using StructureHelperLogics.Services; using StructureHelperLogics.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LoaderCalculator.Logics;
using LoaderCalculator.Data.Ndms;
namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
{ {

View File

@@ -0,0 +1,92 @@
using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperLogics.Models.CrossSections;
using StructureHelperLogics.NdmCalculations.Analyses.ByForces;
using StructureHelperLogics.NdmCalculations.Analyses.Curvatures;
using StructureHelperLogics.NdmCalculations.Analyses.ValueDiagrams;
using StructureHelperLogics.NdmCalculations.Cracking;
namespace StructureHelperLogics.NdmCalculations.Primitives
{
public class RepositoryPrimitiveOperation : IRepositoryOperation<ICrossSectionRepository, INdmPrimitive>
{
private ICrossSectionRepository repository;
public RepositoryPrimitiveOperation(ICrossSectionRepository repository)
{
this.repository = repository;
}
public void RemoveAll()
{
foreach (var calculator in repository.Calculators)
{
if (calculator is IForceCalculator forceCalculator)
{
forceCalculator.InputData.Primitives.Clear();
}
else if (calculator is ICrackCalculator crackCalculator)
{
crackCalculator.InputData.Primitives.Clear();
}
else if (calculator is IValueDiagramCalculator valueDiagramCalculator)
{
valueDiagramCalculator.InputData.Primitives.Clear();
}
else if (calculator is ICurvatureCalculator curvatureCalculator)
{
curvatureCalculator.InputData.Primitives.Clear();
}
else if (calculator is ILimitCurvesCalculator limitCurve)
{
// skip
}
else
{
throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(calculator) + $": Unsupported calculator type: { calculator.GetType().FullName }");
}
}
repository.Primitives.Clear();
}
public void Remove(IEnumerable<INdmPrimitive> entities)
{
foreach (var item in entities)
{
Remove(item);
}
}
public void Remove(INdmPrimitive entity)
{
foreach (var calculator in repository.Calculators)
{
if (calculator is IForceCalculator forceCalculator)
{
forceCalculator.InputData.Primitives.Remove(entity);
}
else if (calculator is ICrackCalculator crackCalculator)
{
crackCalculator.InputData.Primitives.Remove(entity);
}
else if (calculator is IValueDiagramCalculator valueDiagramCalculator)
{
valueDiagramCalculator.InputData.Primitives.Remove(entity);
}
else if (calculator is ICurvatureCalculator curvatureCalculator)
{
curvatureCalculator.InputData.Primitives.Remove(entity);
}
else if (calculator is ILimitCurvesCalculator limitCurve)
{
// skip, nothing to do
}
else
{
throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(calculator) + $": Unsupported calculator type: {calculator.GetType().FullName}");
}
}
repository.Primitives.Remove(entity);
}
}
}

View File

@@ -0,0 +1,137 @@
using Moq;
using NUnit.Framework;
using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Models.Calculators;
using StructureHelperLogics.Models.CrossSections;
using StructureHelperLogics.NdmCalculations.Analyses.ByForces;
using StructureHelperLogics.NdmCalculations.Analyses.Curvatures;
using StructureHelperLogics.NdmCalculations.Analyses.ValueDiagrams;
using StructureHelperLogics.NdmCalculations.Cracking;
using StructureHelperLogics.NdmCalculations.Primitives;
using System;
using System.Collections.Generic;
namespace StructureHelperTests.UnitTests.CrossSections
{
[TestFixture]
public class RepositoryPrimitiveOperationTests
{
private Mock<ICrossSectionRepository> repositoryMock;
private List<INdmPrimitive> repositoryPrimitives;
private Mock<IForceCalculator> forceCalculatorMock;
private Mock<ICrackCalculator> crackCalculatorMock;
private Mock<IValueDiagramCalculator> valueDiagramCalculatorMock;
private Mock<ICurvatureCalculator> curvatureCalculatorMock;
private Mock<ILimitCurvesCalculator> limitCurvesCalculatorMock;
private List<INdmPrimitive> forcePrimitives;
private List<INdmPrimitive> crackPrimitives;
private List<INdmPrimitive> valueDiagramPrimitives;
private List<INdmPrimitive> curvaturePrimitives;
private RepositoryPrimitiveOperation operation;
[SetUp]
public void SetUp()
{
repositoryPrimitives = new List<INdmPrimitive>
{
Mock.Of<INdmPrimitive>(),
Mock.Of<INdmPrimitive>()
};
forcePrimitives = new List<INdmPrimitive>(repositoryPrimitives);
crackPrimitives = new List<INdmPrimitive>(repositoryPrimitives);
valueDiagramPrimitives = new List<INdmPrimitive>(repositoryPrimitives);
curvaturePrimitives = new List<INdmPrimitive>(repositoryPrimitives);
forceCalculatorMock = new Mock<IForceCalculator>();
crackCalculatorMock = new Mock<ICrackCalculator>();
valueDiagramCalculatorMock = new Mock<IValueDiagramCalculator>();
curvatureCalculatorMock = new Mock<ICurvatureCalculator>();
limitCurvesCalculatorMock = new Mock<ILimitCurvesCalculator>();
repositoryMock = new Mock<ICrossSectionRepository>();
repositoryMock.Setup(r => r.Primitives).Returns(repositoryPrimitives);
repositoryMock.Setup(r => r.Calculators).Returns(new List<ICalculator>
{
forceCalculatorMock.Object,
crackCalculatorMock.Object,
valueDiagramCalculatorMock.Object,
curvatureCalculatorMock.Object,
limitCurvesCalculatorMock.Object
});
forceCalculatorMock.Setup(x => x.InputData.Primitives).Returns(forcePrimitives);
crackCalculatorMock.Setup(x => x.InputData.Primitives).Returns(crackPrimitives);
valueDiagramCalculatorMock.Setup(x => x.InputData.Primitives).Returns(valueDiagramPrimitives);
curvatureCalculatorMock.Setup(x => x.InputData.Primitives).Returns(curvaturePrimitives);
operation = new RepositoryPrimitiveOperation(repositoryMock.Object);
}
[Test]
public void RemoveAll_ClearsPrimitivesInAllSupportedCalculators_AndRepository()
{
// Act
operation.RemoveAll();
// Assert
Assert.That(forcePrimitives, Is.Empty);
Assert.That(crackPrimitives, Is.Empty);
Assert.That(valueDiagramPrimitives, Is.Empty);
Assert.That(curvaturePrimitives, Is.Empty);
Assert.That(repositoryPrimitives, Is.Empty);
}
[Test]
public void Remove_RemovesPrimitiveFromAllCalculators_AndRepository()
{
// Arrange
var primitive = repositoryPrimitives[0];
// Act
operation.Remove(primitive);
// Assert
Assert.That(forcePrimitives, Does.Not.Contain(primitive));
Assert.That(crackPrimitives, Does.Not.Contain(primitive));
Assert.That(valueDiagramPrimitives, Does.Not.Contain(primitive));
Assert.That(curvaturePrimitives, Does.Not.Contain(primitive));
Assert.That(repositoryPrimitives, Does.Not.Contain(primitive));
}
[Test]
public void Remove_MultipleEntities_RemovesAll()
{
// Arrange
var toRemove = new List<INdmPrimitive>(repositoryPrimitives);
// Act
operation.Remove(toRemove);
// Assert
Assert.That(forcePrimitives, Is.Empty);
Assert.That(crackPrimitives, Is.Empty);
Assert.That(valueDiagramPrimitives, Is.Empty);
Assert.That(curvaturePrimitives, Is.Empty);
Assert.That(repositoryPrimitives, Is.Empty);
}
[Test]
public void RemoveAll_UnsupportedCalculatorType_ThrowsStructureHelperException()
{
// Arrange
Mock<ICalculator> calculator = new Mock<ICalculator>();
repositoryMock.Setup(r => r.Calculators)
.Returns(new List<ICalculator>() { calculator.Object});
// Act + Assert
Assert.Throws<StructureHelperException>(() => operation.RemoveAll());
}
}
}