diff --git a/DataAccess/DTOs/DTOEntities/CompressedMemberDTO.cs b/DataAccess/DTOs/DTOEntities/CompressedMemberDTO.cs index 922da97..fe3962a 100644 --- a/DataAccess/DTOs/DTOEntities/CompressedMemberDTO.cs +++ b/DataAccess/DTOs/DTOEntities/CompressedMemberDTO.cs @@ -11,7 +11,7 @@ namespace DataAccess.DTOs public class CompressedMemberDTO : ICompressedMember { [JsonProperty("Id")] - public Guid Id { get; set; } + public Guid Id { get; set; } = Guid.NewGuid(); [JsonProperty("Bucling")] public bool Buckling { get; set; } [JsonProperty("GeometryLength")] diff --git a/DataAccess/DTOs/DTOEntities/CrossSectionNdmAnalysisDTO.cs b/DataAccess/DTOs/DTOEntities/CrossSectionNdmAnalysisDTO.cs index 7656bb2..0d76d9a 100644 --- a/DataAccess/DTOs/DTOEntities/CrossSectionNdmAnalysisDTO.cs +++ b/DataAccess/DTOs/DTOEntities/CrossSectionNdmAnalysisDTO.cs @@ -8,6 +8,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Windows.Media; namespace DataAccess.DTOs { @@ -21,6 +22,10 @@ namespace DataAccess.DTOs public string Tags { get; set; } [JsonProperty("VersionProcessor")] public IVersionProcessor VersionProcessor { get; set; } = new VersionProcessorDTO(); + [JsonProperty("Comment")] + public string Comment { get; set; } = string.Empty; + [JsonProperty("Color")] + public Color Color { get; set; } = new(); public object Clone() { diff --git a/DataAccess/DTOs/DTOEntities/ForceCalculatorInputDataDTO.cs b/DataAccess/DTOs/DTOEntities/ForceCalculatorInputDataDTO.cs index 5535a5e..91884f7 100644 --- a/DataAccess/DTOs/DTOEntities/ForceCalculatorInputDataDTO.cs +++ b/DataAccess/DTOs/DTOEntities/ForceCalculatorInputDataDTO.cs @@ -17,7 +17,7 @@ namespace DataAccess.DTOs public class ForceCalculatorInputDataDTO : IForceCalculatorInputData { [JsonProperty("Id")] - public Guid Id { get; set; } + public Guid Id { get; set; } = Guid.NewGuid(); [JsonProperty("ForceActions")] public List ForceActions { get; set; } = new(); [JsonProperty("Primitives")] diff --git a/StructureHelper/Documentation/Manuals/Руководство пользователя.docx b/StructureHelper/Documentation/Manuals/Руководство пользователя.docx index a737148..7d9ef22 100644 Binary files a/StructureHelper/Documentation/Manuals/Руководство пользователя.docx and b/StructureHelper/Documentation/Manuals/Руководство пользователя.docx differ diff --git a/StructureHelper/Infrastructure/UI/Resources/ButtonStyles.xaml b/StructureHelper/Infrastructure/UI/Resources/ButtonStyles.xaml index c10ad2b..6cfab81 100644 --- a/StructureHelper/Infrastructure/UI/Resources/ButtonStyles.xaml +++ b/StructureHelper/Infrastructure/UI/Resources/ButtonStyles.xaml @@ -408,7 +408,26 @@ - + + + + + + + + + + + + + + + + + + + + @@ -416,7 +435,7 @@ - + @@ -424,7 +443,7 @@ - + diff --git a/StructureHelper/Infrastructure/ViewModelBase.cs b/StructureHelper/Infrastructure/ViewModelBase.cs index 0e9d025..3d29d79 100644 --- a/StructureHelper/Infrastructure/ViewModelBase.cs +++ b/StructureHelper/Infrastructure/ViewModelBase.cs @@ -1,11 +1,13 @@ using System.ComponentModel; using System.Runtime.CompilerServices; +using System.Windows; using StructureHelper.Properties; namespace StructureHelper.Infrastructure { public class ViewModelBase : INotifyPropertyChanged { + public Window OwnerWindow { get; set; } public event PropertyChangedEventHandler PropertyChanged; [NotifyPropertyChangedInvocator] protected virtual void OnPropertyChanged(T value, T prop, [CallerMemberName] string propertyName = null) diff --git a/StructureHelper/StructureHelper.csproj.user b/StructureHelper/StructureHelper.csproj.user index 1a3452d..7acfc94 100644 --- a/StructureHelper/StructureHelper.csproj.user +++ b/StructureHelper/StructureHelper.csproj.user @@ -66,6 +66,9 @@ Code + + Code + Code @@ -167,6 +170,9 @@ Designer + + Designer + Designer diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/InteractionDiagramLogic.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/InteractionDiagramLogic.cs index 625265f..57d6976 100644 --- a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/InteractionDiagramLogic.cs +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/InteractionDiagramLogic.cs @@ -34,14 +34,14 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu private int stepCount; private static GeometryNames GeometryNames => ProgramSetting.GeometryNames; - public LimitCurveInputData InputData { get; set; } + public LimitCurvesCalculatorInputData InputData { get; set; } public int StepCount { get => stepCount; set => stepCount = value; } public Action SetProgress { get; set; } public bool Result { get; set; } public IShiftTraceLogger? TraceLogger { get; set; } - public InteractionDiagramLogic(LimitCurveInputData inputData) + public InteractionDiagramLogic(LimitCurvesCalculatorInputData inputData) { InputData = inputData; stepCount = InputData.PointCount; diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/LimitCurveDataViewModel.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/LimitCurveDataViewModel.cs index f994abb..2d9f1a0 100644 --- a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/LimitCurveDataViewModel.cs +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/LimitCurveDataViewModel.cs @@ -24,11 +24,11 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu { public class LimitCurveDataViewModel : OkCancelViewModelBase, IDataErrorInfo { - private LimitCurveInputData inputData; + private LimitCurvesCalculatorInputData inputData; //public SurroundDataViewModel SurroundDataViewModel { get; private set; } - public SurroundData SurroundData { get => inputData.SurroundData; } + public ISurroundData SurroundData { get => inputData.SurroundData; } public SelectPrimitivesSourceTarget PrimitiveSeries { get; private set; } public SelectItemsVM PredicateItems { get; private set; } public SelectItemsVM LimitStateItems { get; private set; } @@ -52,7 +52,7 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu public IEnumerable AllowedPrimitives { get; set; } - public LimitCurveDataViewModel(LimitCurveInputData inputData, IEnumerable allowedPrimitives) + public LimitCurveDataViewModel(LimitCurvesCalculatorInputData inputData, IEnumerable allowedPrimitives) { this.inputData = inputData; AllowedPrimitives = allowedPrimitives; diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForcesResultsView.xaml b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForcesResultsView.xaml index 567bd2d..16895d2 100644 --- a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForcesResultsView.xaml +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForcesResultsView.xaml @@ -140,13 +140,13 @@ - + - + diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForcesResultsViewModel.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForcesResultsViewModel.cs index 81883fe..cbb5c24 100644 --- a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForcesResultsViewModel.cs +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForcesResultsViewModel.cs @@ -89,7 +89,7 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu private void ShowInteractionDiagram() { - var inputData = new LimitCurveInputData(ndmPrimitives); + var inputData = new LimitCurvesCalculatorInputData(ndmPrimitives); var vm = new LimitCurveDataViewModel(inputData, ndmPrimitives); //vm.LimitStateItems.SetIsSelected(); //vm.CalcTermITems.SetIsSelected(); @@ -106,7 +106,7 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu ShowInteractionDiagramByInputData(inputData); } - private void ShowInteractionDiagramByInputData(LimitCurveInputData inputData) + private void ShowInteractionDiagramByInputData(LimitCurvesCalculatorInputData inputData) { interactionDiagramLogic = new(inputData); showProgressLogic = new(interactionDiagramLogic) diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/UserControls/SurroundDataViewModel.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/UserControls/SurroundDataViewModel.cs index 15fbb13..9d3f718 100644 --- a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/UserControls/SurroundDataViewModel.cs +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/UserControls/SurroundDataViewModel.cs @@ -23,7 +23,7 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu const string MomentUnitString = "kNm"; static IConvertUnitLogic operationLogic = new ConvertUnitLogic(); static IGetUnitLogic unitLogic = new GetUnitLogic(); - public SurroundData SurroundData + public ISurroundData SurroundData { get => surroundData; set { @@ -50,7 +50,7 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu private static IUnit unitForce = unitLogic.GetUnit(UnitTypes.Force, ForceUnitString); private static IUnit unitMoment = unitLogic.GetUnit(UnitTypes.Moment, MomentUnitString); - private SurroundData surroundData; + private ISurroundData surroundData; public IValueConverter ForceConverter { get => new Force(); } public IValueConverter MomentConverter { get => new Moment();} @@ -183,7 +183,7 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu } } - public SurroundDataViewModel(SurroundData surroundData) + public SurroundDataViewModel(ISurroundData surroundData) { this.SurroundData = surroundData; Logics = new(); diff --git a/StructureHelper/Windows/MainWindow/Analyses/AnalysesLogic.cs b/StructureHelper/Windows/MainWindow/Analyses/AnalysesLogic.cs index c7ab311..1c32ff5 100644 --- a/StructureHelper/Windows/MainWindow/Analyses/AnalysesLogic.cs +++ b/StructureHelper/Windows/MainWindow/Analyses/AnalysesLogic.cs @@ -22,6 +22,8 @@ namespace StructureHelper.Windows.MainWindow private RelayCommand? runCommand; private RelayCommand? editCommand; private RelayCommand? deleteCommand; + private RelayCommand? copyCommand; + private RelayCommand versionsCommand; public IVisualAnalysis? SelectedAnalysis { get; set; } @@ -74,6 +76,56 @@ namespace StructureHelper.Windows.MainWindow } } + public RelayCommand CopyCommand + { + get + { + return copyCommand ??= new RelayCommand(obj => + { + CopyCurrentAnalysis(); + }, + b => SelectedAnalysis is not null); + } + } + + public RelayCommand VersionsCommand + { + get + { + return versionsCommand ??= new RelayCommand(obj => + { + ShowVersions(); + }, + b => SelectedAnalysis is not null); + } + } + + private void ShowVersions() + { + if (SelectedAnalysis is null) { return; } + try + { + VersionsViewModel viewModel = new(SelectedAnalysis.Analysis.VersionProcessor); + var wnd = new VersionsView(viewModel); + wnd.ShowDialog(); + } + catch (Exception ex) + { + // to do + } + } + + private void CopyCurrentAnalysis() + { + if (SelectedAnalysis is not null) + { + var newAnalysis = SelectedAnalysis.Clone() as IVisualAnalysis; + newAnalysis.Analysis.Name += " - copy"; + ProgramSetting.CurrentProject.VisualAnalyses.Add(newAnalysis); + Refresh(); + SelectedAnalysis = newAnalysis; + } + } public AnalysesLogic() { diff --git a/StructureHelper/Windows/MainWindow/Analyses/VersionsView.xaml b/StructureHelper/Windows/MainWindow/Analyses/VersionsView.xaml new file mode 100644 index 0000000..545e271 --- /dev/null +++ b/StructureHelper/Windows/MainWindow/Analyses/VersionsView.xaml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/StructureHelper/Windows/MainWindow/Analyses/VersionsView.xaml.cs b/StructureHelper/Windows/MainWindow/Analyses/VersionsView.xaml.cs new file mode 100644 index 0000000..2b1f227 --- /dev/null +++ b/StructureHelper/Windows/MainWindow/Analyses/VersionsView.xaml.cs @@ -0,0 +1,40 @@ +using StructureHelperCommon.Models.Analyses; +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.MainWindow.Analyses +{ + /// + /// Interaction logic for VersionsView.xaml + /// + public partial class VersionsView : Window + { + VersionsViewModel viewModel; + public VersionsView(VersionsViewModel viewModel) + { + InitializeComponent(); + this.viewModel = viewModel; + DataContext = this.viewModel; + if (this.viewModel.OwnerWindow is not null) + { + Owner = this.viewModel.OwnerWindow; + } + } + + public VersionsView(IVersionProcessor versionProcessor) : this (new VersionsViewModel(versionProcessor)) + { + + } + } +} diff --git a/StructureHelper/Windows/MainWindow/Analyses/VersionsViewModel.cs b/StructureHelper/Windows/MainWindow/Analyses/VersionsViewModel.cs new file mode 100644 index 0000000..19c7a22 --- /dev/null +++ b/StructureHelper/Windows/MainWindow/Analyses/VersionsViewModel.cs @@ -0,0 +1,103 @@ +using StructureHelper.Infrastructure; +using StructureHelper.Windows.ViewModels; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models.Analyses; +using StructureHelperCommon.Models.Calculators; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window; +using System.Windows; +using StructureHelper.Windows.ViewModels.Errors; + +namespace StructureHelper.Windows.MainWindow.Analyses +{ + public class VersionsViewModel : ViewModelBase + { + private IVersionProcessor versionProcessor; + private RelayCommand addNewVersionCommand; + private RelayCommand returnToVersionCommand; + + public VersionsViewModel(IVersionProcessor versionProcessor) + { + this.versionProcessor = versionProcessor; + Refresh(); + } + + public IDateVersion SelectedVersion { get; set; } + public ObservableCollection DateVersions { get; set; } = new(); + + public RelayCommand AddNewVersionCommand + { + get + { + return addNewVersionCommand ??= new RelayCommand(obj => + { + AddNewVersion(); + }, + b => SelectedVersion is not null); + } + } + + public RelayCommand ReturnToVersionCommand + { + get + { + return returnToVersionCommand ??= new RelayCommand(obj => + { + ReturnToVersion(); + }, + b => SelectedVersion is not null); + } + } + + private void ReturnToVersion() + { + if (SelectedVersion is null) return; + if (versionProcessor.Versions.Count <= 1) + { + MessageBox.Show("It is not possible to delete last version", "There is only 1 version", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK); + return; + } + MessageBoxResult result = MessageBox.Show("Please, confirm deleting", "Delete version(s)?", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); + if (result != MessageBoxResult.OK) { return; } + SafetyProcessor.RunSafeProcess(RemovingOfVersion, "Error of deleting of version"); + } + + private void RemovingOfVersion() + { + while (SelectedVersion != versionProcessor.GetCurrentVersion()) + { + versionProcessor + .Versions + .Remove(versionProcessor.GetCurrentVersion()); + } + Refresh(); + } + + private void AddNewVersion() + { + if (SelectedVersion is null) { return; } + SafetyProcessor.RunSafeProcess(AddVersion, "Error of adding of new version"); + } + + private void AddVersion() + { + var selectedItem = SelectedVersion.AnalysisVersion as ICloneable; + versionProcessor.AddVersion(selectedItem.Clone() as ISaveable); + Refresh(); + } + + private void Refresh() + { + DateVersions.Clear(); + versionProcessor.Versions.ForEach(x => DateVersions.Add(x)); + SelectedVersion = DateVersions[^1]; + } + + } +} diff --git a/StructureHelper/Windows/MainWindow/AnalysesManagerView.xaml b/StructureHelper/Windows/MainWindow/AnalysesManagerView.xaml index c5a0fcb..b99eb5b 100644 --- a/StructureHelper/Windows/MainWindow/AnalysesManagerView.xaml +++ b/StructureHelper/Windows/MainWindow/AnalysesManagerView.xaml @@ -21,13 +21,23 @@ + + + + + diff --git a/StructureHelper/Windows/ViewModels/Errors/SafetyProcessor.cs b/StructureHelper/Windows/ViewModels/Errors/SafetyProcessor.cs index 2ca2e56..50d55e0 100644 --- a/StructureHelper/Windows/ViewModels/Errors/SafetyProcessor.cs +++ b/StructureHelper/Windows/ViewModels/Errors/SafetyProcessor.cs @@ -8,8 +8,16 @@ using System.Threading.Tasks; namespace StructureHelper.Windows.ViewModels.Errors { + /// + /// Provides safety runing of some action + /// internal static class SafetyProcessor { + /// + /// Invokes action and wrap it in safety try-catch block + /// + /// Action wich will be invoked + /// Short text of error public static void RunSafeProcess(Action action, string shortText = "") { try diff --git a/StructureHelper/Windows/ViewModels/NdmCrossSections/AnalysisViewModelLogic.cs b/StructureHelper/Windows/ViewModels/NdmCrossSections/AnalysisViewModelLogic.cs index 5bffae7..36a059b 100644 --- a/StructureHelper/Windows/ViewModels/NdmCrossSections/AnalysisViewModelLogic.cs +++ b/StructureHelper/Windows/ViewModels/NdmCrossSections/AnalysisViewModelLogic.cs @@ -71,7 +71,7 @@ namespace StructureHelper.Windows.ViewModels.NdmCrossSections private void AddLimitCurveCalculator() { - var inputData = new LimitCurveInputData(repository.Primitives); + var inputData = new LimitCurvesCalculatorInputData(repository.Primitives); NewItem = new LimitCurvesCalculator() { Name = "New interaction diagram calculator", diff --git a/StructureHelperCommon/Infrastructures/Interfaces/DeepCloningStrategy.cs b/StructureHelperCommon/Infrastructures/Interfaces/DeepCloningStrategy.cs new file mode 100644 index 0000000..e416f0e --- /dev/null +++ b/StructureHelperCommon/Infrastructures/Interfaces/DeepCloningStrategy.cs @@ -0,0 +1,60 @@ +using StructureHelperCommon.Infrastructures.Exceptions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Infrastructures.Interfaces +{ + public class DeepCloningStrategy : ICloningStrategy + { + private readonly Dictionary _clonedObjects = new Dictionary(); + + public T Clone(T original, ICloneStrategy? cloneStrategy = null) where T : class + { + if (original == null) return null; + + // Check if the object is already cloned + if (_clonedObjects.TryGetValue(original, out var existingClone)) + return (T)existingClone; + + // Perform custom cloning logic based on the object's type + T clone; + if (cloneStrategy is not null) + { + clone = cloneStrategy.GetClone(original); + } + // Check if the object implements ICloneable (or IClone) and use that method + else if (original is ICloneable cloneable) + { + clone = cloneable.Clone() as T; // Use the ICloneable interface's Clone method + } + else + { + throw new StructureHelperException(ErrorStrings.DataIsInCorrect + ": object is not IClonable and cloning strategy is null"); + + } + _clonedObjects[original] = clone; + + return clone; + } + + //private T CreateClone(T original) where T : class + //{ + // // Example logic for creating a clone (modify as needed for your use case) + // var type = original.GetType(); + // var clone = Activator.CreateInstance(type); + + // foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) + // { + // var value = field.GetValue(original); + // field.SetValue(clone, Clone(value)); + // } + + // return (T)clone; + //} + } + +} diff --git a/StructureHelperCommon/Infrastructures/Interfaces/ICloneStrategy.cs b/StructureHelperCommon/Infrastructures/Interfaces/ICloneStrategy.cs new file mode 100644 index 0000000..acb4a5c --- /dev/null +++ b/StructureHelperCommon/Infrastructures/Interfaces/ICloneStrategy.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Infrastructures.Interfaces +{ + /// + /// Creates deep clone of object + /// + /// + public interface ICloneStrategy + { + /// + /// Returns deep clone of object + /// + /// + /// + T GetClone(T sourceObject); + } +} diff --git a/StructureHelperCommon/Infrastructures/Interfaces/ICloningStrategy.cs b/StructureHelperCommon/Infrastructures/Interfaces/ICloningStrategy.cs new file mode 100644 index 0000000..a1f9dd0 --- /dev/null +++ b/StructureHelperCommon/Infrastructures/Interfaces/ICloningStrategy.cs @@ -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 ICloningStrategy + { + T Clone(T original, ICloneStrategy? cloneStrategy = null) where T : class; + } +} diff --git a/StructureHelperCommon/Models/Analyses/AnalysisUpdateStrategy.cs b/StructureHelperCommon/Models/Analyses/AnalysisUpdateStrategy.cs index dd7ee82..bfca454 100644 --- a/StructureHelperCommon/Models/Analyses/AnalysisUpdateStrategy.cs +++ b/StructureHelperCommon/Models/Analyses/AnalysisUpdateStrategy.cs @@ -16,6 +16,9 @@ namespace StructureHelperCommon.Models.Analyses if (ReferenceEquals(targetObject, sourceObject)) { return; } targetObject.Name = sourceObject.Name; targetObject.Tags = sourceObject.Tags; + targetObject.Comment = sourceObject.Comment; + targetObject.Color = sourceObject.Color; + } } } diff --git a/StructureHelperCommon/Models/Analyses/IAnalysis.cs b/StructureHelperCommon/Models/Analyses/IAnalysis.cs index eee4d36..fbbdc55 100644 --- a/StructureHelperCommon/Models/Analyses/IAnalysis.cs +++ b/StructureHelperCommon/Models/Analyses/IAnalysis.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Windows.Media; namespace StructureHelperCommon.Models.Analyses { @@ -11,6 +12,8 @@ namespace StructureHelperCommon.Models.Analyses { string Name { get; set; } string Tags { get; set; } + string Comment { get; set; } + Color Color { get; set; } IVersionProcessor VersionProcessor { get; set; } } } diff --git a/StructureHelperLogics/Models/Analyses/CrossSectionNdmAnalysis.cs b/StructureHelperLogics/Models/Analyses/CrossSectionNdmAnalysis.cs index 7d65ed4..62ac0bc 100644 --- a/StructureHelperLogics/Models/Analyses/CrossSectionNdmAnalysis.cs +++ b/StructureHelperLogics/Models/Analyses/CrossSectionNdmAnalysis.cs @@ -1,6 +1,8 @@ -using StructureHelperCommon.Models.Analyses; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models.Analyses; using StructureHelperLogics.Models.Analyses; using StructureHelperLogics.Models.CrossSections; +using System.Windows.Media; namespace StructureHelperLogic.Models.Analyses { @@ -11,6 +13,8 @@ namespace StructureHelperLogic.Models.Analyses public string Name { get; set; } public string Tags { get; set; } public IVersionProcessor VersionProcessor { get; set; } + public string Comment { get; set; } = string.Empty; + public Color Color { get; set; } = Color.FromRgb(128, 0, 0); public CrossSectionNdmAnalysis(Guid id, IVersionProcessor versionProcessor) { @@ -33,6 +37,10 @@ namespace StructureHelperLogic.Models.Analyses { CrossSectionNdmAnalysis newAnalysis = new(); updateStrategy.Update(newAnalysis, this); + var currentVersion = VersionProcessor.GetCurrentVersion().AnalysisVersion as ICloneable; + ISaveable newCrossSection = currentVersion.Clone() as ISaveable; + newAnalysis.VersionProcessor.Versions.Clear(); + newAnalysis.VersionProcessor.AddVersion(newCrossSection); return newAnalysis; } } diff --git a/StructureHelperLogics/Models/CrossSections/CrossSection.cs b/StructureHelperLogics/Models/CrossSections/CrossSection.cs index e32ed17..a963b58 100644 --- a/StructureHelperLogics/Models/CrossSections/CrossSection.cs +++ b/StructureHelperLogics/Models/CrossSections/CrossSection.cs @@ -1,4 +1,5 @@ -using System; +using StructureHelperCommon.Infrastructures.Interfaces; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -8,6 +9,7 @@ namespace StructureHelperLogics.Models.CrossSections { public class CrossSection : ICrossSection { + private ICloneStrategy cloneStrategy = new CrossSectionCloneStrategy(); public ICrossSectionRepository SectionRepository { get; set; } = new CrossSectionRepository(); public Guid Id { get; private set; } @@ -24,7 +26,7 @@ namespace StructureHelperLogics.Models.CrossSections public object Clone() { - throw new NotImplementedException(); + return cloneStrategy.GetClone(this); } } } diff --git a/StructureHelperLogics/Models/CrossSections/CrossSectionCloneStrategy.cs b/StructureHelperLogics/Models/CrossSections/CrossSectionCloneStrategy.cs new file mode 100644 index 0000000..b91ddbd --- /dev/null +++ b/StructureHelperLogics/Models/CrossSections/CrossSectionCloneStrategy.cs @@ -0,0 +1,30 @@ +using StructureHelperCommon.Infrastructures.Interfaces; + +namespace StructureHelperLogics.Models.CrossSections +{ + public class CrossSectionCloneStrategy : ICloneStrategy + { + private ICloneStrategy repositoryCloneStrategy; + private CrossSection targetObject; + + public CrossSectionCloneStrategy(ICloneStrategy repositoryCloneStrategy) + { + this.repositoryCloneStrategy = repositoryCloneStrategy; + } + + public CrossSectionCloneStrategy() : this (new CrossSectionRepositoryCloneStrategy()) + { + + } + + public ICrossSection GetClone(ICrossSection sourceObject) + { + ICrossSectionRepository newRepository = repositoryCloneStrategy.GetClone(sourceObject.SectionRepository); + targetObject = new() + { + SectionRepository = newRepository + }; + return targetObject; + } + } +} diff --git a/StructureHelperLogics/Models/CrossSections/CrossSectionRepositoryCloneStrategy.cs b/StructureHelperLogics/Models/CrossSections/CrossSectionRepositoryCloneStrategy.cs new file mode 100644 index 0000000..5ba37f7 --- /dev/null +++ b/StructureHelperLogics/Models/CrossSections/CrossSectionRepositoryCloneStrategy.cs @@ -0,0 +1,142 @@ +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Parameters; +using StructureHelperLogics.Models.Materials; +using StructureHelperLogics.NdmCalculations.Analyses.ByForces; +using StructureHelperLogics.NdmCalculations.Analyses.ByForces.LimitCurve; +using StructureHelperLogics.NdmCalculations.Cracking; +using StructureHelperLogics.NdmCalculations.Primitives; + +namespace StructureHelperLogics.Models.CrossSections +{ + public class CrossSectionRepositoryCloneStrategy : ICloneStrategy + { + private ICloningStrategy cloningStrategy; + private CrossSectionRepository targetRepository; + private IUpdateStrategy limitCurvesInputDataUpdateStrategy; + + public CrossSectionRepositoryCloneStrategy( + ICloningStrategy cloningStrategy, + IUpdateStrategy limitCurvesInputDataUpdateStrategy) + { + this.cloningStrategy = cloningStrategy; + this.limitCurvesInputDataUpdateStrategy = limitCurvesInputDataUpdateStrategy; + } + + public CrossSectionRepositoryCloneStrategy() : this ( + new DeepCloningStrategy(), + new LimitCurvesCalculatorInputDataUpdateStrategy()) + { + + } + + public ICrossSectionRepository GetClone(ICrossSectionRepository sourceObject) + { + targetRepository = new(); + ProcessForces(targetRepository, sourceObject); + ProcessMaterials(targetRepository, sourceObject); + ProcessPrimitives(targetRepository, sourceObject); + ProcessCalculators(targetRepository, sourceObject); + return targetRepository; + } + + private void ProcessCalculators(IHasCalculators targetObject, IHasCalculators sourceObject) + { + targetObject.Calculators.Clear(); + foreach (var calculator in sourceObject.Calculators) + { + var newCalculator = cloningStrategy.Clone(calculator); + if (calculator is IForceCalculator forceCalculator) + { + ProcessForceCalculator(newCalculator, forceCalculator); + } + else if (calculator is CrackCalculator crackCalculator) + { + ProcessCrackCalculator(newCalculator, crackCalculator); + } + else if (calculator is ILimitCurvesCalculator limitCalculator) + { + ProcessLimitCurvesCalculator(newCalculator, limitCalculator); + } + else + { + throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(calculator)); + } + targetRepository.Calculators.Add(newCalculator); + } + } + + private void ProcessLimitCurvesCalculator(ICalculator newCalculator, ILimitCurvesCalculator limitCalculator) + { + var sourceData = limitCalculator.InputData; + var targetData = ((ILimitCurvesCalculator)newCalculator).InputData; + limitCurvesInputDataUpdateStrategy.Update(targetData, sourceData); + foreach (var series in targetData.PrimitiveSeries) + { + List collection = UpdatePrimitivesCollection(series); + series.Collection.AddRange(collection); + } + } + + private void ProcessCrackCalculator(ICalculator newCalculator, CrackCalculator crackCalculator) + { + var sourceData = crackCalculator.InputData; + var targetData = ((ICrackCalculator)newCalculator).InputData; + ProcessPrimitives(targetData, sourceData); + ProcessForces(targetData, sourceData); + } + + private void ProcessForceCalculator(ICalculator newCalculator, IForceCalculator forceCalculator) + { + var sourceData = forceCalculator.InputData; + var targetData = ((IForceCalculator)newCalculator).InputData; + ProcessPrimitives(targetData, sourceData); + ProcessForces(targetData, sourceData); + } + + private List UpdatePrimitivesCollection(NamedCollection series) + { + List collection = new(); + foreach (var item in series.Collection) + { + var newItem = cloningStrategy.Clone(item); + collection.Add(newItem); + } + series.Collection.Clear(); + return collection; + } + + private void ProcessMaterials(IHasHeadMaterials targetObject, IHasHeadMaterials sourceObject) + { + targetObject.HeadMaterials.Clear(); + foreach (var material in sourceObject.HeadMaterials) + { + var newMaterial = cloningStrategy.Clone(material); + targetRepository.HeadMaterials.Add(newMaterial); + } + } + + private void ProcessForces(IHasForceActions targetObject, IHasForceActions sourceObject) + { + targetObject.ForceActions.Clear(); + foreach (var force in sourceObject.ForceActions) + { + var newForce = cloningStrategy.Clone(force); + targetObject.ForceActions.Add(newForce); + } + } + + private void ProcessPrimitives(IHasPrimitives targetObject, IHasPrimitives sourceObject) + { + targetObject.Primitives.Clear(); + foreach (var primitive in sourceObject.Primitives) + { + var newPrimitive = cloningStrategy.Clone(primitive); + var material = cloningStrategy.Clone(primitive.NdmElement.HeadMaterial); + newPrimitive.NdmElement.HeadMaterial = material; + targetObject.Primitives.Add(newPrimitive); + } + } + } +} diff --git a/StructureHelperLogics/Models/Materials/Logics/HeadMaterialBaseUpdateStrategy.cs b/StructureHelperLogics/Models/Materials/Logics/HeadMaterialBaseUpdateStrategy.cs index 6a69959..777f396 100644 --- a/StructureHelperLogics/Models/Materials/Logics/HeadMaterialBaseUpdateStrategy.cs +++ b/StructureHelperLogics/Models/Materials/Logics/HeadMaterialBaseUpdateStrategy.cs @@ -1,11 +1,6 @@ using StructureHelper.Models.Materials; using StructureHelperCommon.Infrastructures.Interfaces; using StructureHelperCommon.Services; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace StructureHelperLogics.Models.Materials { diff --git a/StructureHelperLogics/Models/Materials/Logics/HeadMaterialUpdateStrategy.cs b/StructureHelperLogics/Models/Materials/Logics/HeadMaterialUpdateStrategy.cs index 1964408..a7ca8b4 100644 --- a/StructureHelperLogics/Models/Materials/Logics/HeadMaterialUpdateStrategy.cs +++ b/StructureHelperLogics/Models/Materials/Logics/HeadMaterialUpdateStrategy.cs @@ -6,21 +6,29 @@ namespace StructureHelperLogics.Models.Materials { public class HeadMaterialUpdateStrategy : IUpdateStrategy { - private IUpdateStrategy updateStrategy = new HeadMaterialBaseUpdateStrategy(); + private IUpdateStrategy baseUpdateStrategy; private IUpdateStrategy helperMaterialUpdateStrategy; - public HeadMaterialUpdateStrategy(IUpdateStrategy helperMaterialUpdateStrategy) + public HeadMaterialUpdateStrategy( + IUpdateStrategy baseUpdateStrategy, + IUpdateStrategy helperMaterialUpdateStrategy) { + this.baseUpdateStrategy = baseUpdateStrategy; this.helperMaterialUpdateStrategy = helperMaterialUpdateStrategy; } - public HeadMaterialUpdateStrategy() : this(new HelperMaterialUpdateStrategy()) { } + public HeadMaterialUpdateStrategy() : this( + new HeadMaterialBaseUpdateStrategy(), + new HelperMaterialUpdateStrategy()) + { + + } public void Update(IHeadMaterial targetObject, IHeadMaterial sourceObject) { CheckObject.IsNull(sourceObject); CheckObject.IsNull(targetObject); if (ReferenceEquals(targetObject, sourceObject)) { return; } - updateStrategy.Update(targetObject, sourceObject); + baseUpdateStrategy.Update(targetObject, sourceObject); targetObject.HelperMaterial = sourceObject.HelperMaterial.Clone() as IHelperMaterial; helperMaterialUpdateStrategy.Update(targetObject.HelperMaterial, sourceObject.HelperMaterial); } diff --git a/StructureHelperLogics/Models/Materials/Logics/HelperMaterialUpdateStrategy.cs b/StructureHelperLogics/Models/Materials/Logics/HelperMaterialUpdateStrategy.cs index 6cf10f6..e688fce 100644 --- a/StructureHelperLogics/Models/Materials/Logics/HelperMaterialUpdateStrategy.cs +++ b/StructureHelperLogics/Models/Materials/Logics/HelperMaterialUpdateStrategy.cs @@ -63,13 +63,13 @@ namespace StructureHelperLogics.Models.Materials private void UpdateLibMaterial(IHelperMaterial targetObject, IHelperMaterial sourceObject) { - if (sourceObject is IConcreteLibMaterial) + if (sourceObject is IConcreteLibMaterial concreteLibMaterial) { - concreteStrategy.Update(targetObject as IConcreteLibMaterial, sourceObject as IConcreteLibMaterial); + concreteStrategy.Update(targetObject as IConcreteLibMaterial, concreteLibMaterial); } - else if (sourceObject is IReinforcementLibMaterial) + else if (sourceObject is IReinforcementLibMaterial reinforcementLibMaterial) { - reinforcementStrategy.Update(targetObject as IReinforcementLibMaterial, sourceObject as IReinforcementLibMaterial); + reinforcementStrategy.Update(targetObject as IReinforcementLibMaterial, reinforcementLibMaterial); } else { diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/IForceCalculator.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/IForceCalculator.cs index 0c428fd..8c457a3 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/IForceCalculator.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/IForceCalculator.cs @@ -8,6 +8,9 @@ using System.Threading.Tasks; namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces { + /// + /// Provides calculations of ndm primitives for force actions + /// public interface IForceCalculator : ICalculator, IHasActionByResult { IForceCalculatorInputData InputData { get; set; } diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/ILimitCurveCalculator.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/ILimitCurveCalculator.cs index c731812..645dd7d 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/ILimitCurveCalculator.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/ILimitCurveCalculator.cs @@ -5,7 +5,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces public interface ILimitCurveCalculator : ICalculator, IHasActionByResult { Action ActionToOutputResults { get; set; } - SurroundData SurroundData { get; set; } + ISurroundData SurroundData { get; set; } int PointCount { get; set; } ISurroundProc SurroundProcLogic { get; set; } } diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/ILimitCurvesCalculator.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/ILimitCurvesCalculator.cs new file mode 100644 index 0000000..26366d6 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/ILimitCurvesCalculator.cs @@ -0,0 +1,12 @@ +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Calculators; + +namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces +{ + public interface ILimitCurvesCalculator : ISaveable, ICalculator, IHasActionByResult + { + LimitCurvesCalculatorInputData InputData { get; set; } + string Name { get; set; } + } +} \ No newline at end of file diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/ILimitCurvesCalculatorInputData.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/ILimitCurvesCalculatorInputData.cs new file mode 100644 index 0000000..be6177b --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/ILimitCurvesCalculatorInputData.cs @@ -0,0 +1,17 @@ +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Parameters; +using StructureHelperLogics.NdmCalculations.Primitives; + +namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces +{ + public interface ILimitCurvesCalculatorInputData : IInputData, ICloneable + { + List CalcTerms { get; } + List LimitStates { get; } + int PointCount { get; set; } + List PredicateEntries { get; } + List> PrimitiveSeries { get; } + ISurroundData SurroundData { get; set; } + } +} \ No newline at end of file diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/ISurroundData.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/ISurroundData.cs new file mode 100644 index 0000000..5237863 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/ISurroundData.cs @@ -0,0 +1,14 @@ +using StructureHelperCommon.Models.Shapes; + +namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces +{ + public interface ISurroundData : ICloneable + { + double ConstZ { get; set; } + ConstOneDirectionConverter ConvertLogicEntity { get; set; } + double XMax { get; set; } + double XMin { get; set; } + double YMax { get; set; } + double YMin { get; set; } + } +} \ No newline at end of file diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/ISurroundProc.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/ISurroundProc.cs index b6e48d9..511e919 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/ISurroundProc.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/ISurroundProc.cs @@ -9,7 +9,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces { public interface ISurroundProc { - SurroundData SurroundData { get; set; } + ISurroundData SurroundData { get; set; } int PointCount { get; set; } List GetPoints(); } diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurveCalculator.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurveCalculator.cs index 4c24953..c5d79e7 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurveCalculator.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurveCalculator.cs @@ -13,7 +13,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces private ILimitCurveLogic limitCurveLogic; public string Name { get; set; } - public SurroundData SurroundData { get; set; } + public ISurroundData SurroundData { get; set; } public int PointCount { get; set; } public ISurroundProc SurroundProcLogic { get; set; } @@ -27,7 +27,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces public LimitCurveCalculator(ILimitCurveLogic limitCurveLogic) { this.limitCurveLogic = limitCurveLogic; - SurroundData = new(); + SurroundData = new SurroundData(); SurroundProcLogic = new RectSurroundProc(); } diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurveInputData.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurveInputData.cs deleted file mode 100644 index 1fd851c..0000000 --- a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurveInputData.cs +++ /dev/null @@ -1,73 +0,0 @@ -using StructureHelperCommon.Infrastructures.Enums; -using StructureHelperCommon.Infrastructures.Settings; -using StructureHelperCommon.Models.Calculators; -using StructureHelperCommon.Models.Forces; -using StructureHelperCommon.Models.Parameters; -using StructureHelperCommon.Models.Shapes; -using StructureHelperLogics.NdmCalculations.Primitives; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -//Copyright (c) 2023 Redikultsev Evgeny, Ekaterinburg, Russia -//All rights reserved. - -namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces -{ - public class LimitCurveInputData : IInputData, ICloneable - { - public List LimitStates { get; private set; } - public List CalcTerms { get; private set; } - public List> PrimitiveSeries {get; private set; } - public List PredicateEntries { get; private set; } - public SurroundData SurroundData { get; set; } - public int PointCount { get; set; } - public LimitCurveInputData() - { - LimitStates = new(); - CalcTerms = new(); - PredicateEntries = new(); - SurroundData = new(); - PointCount = 80; - PrimitiveSeries = new List>(); - } - public LimitCurveInputData(IEnumerable primitives) : this() - { - PrimitiveSeries.Add - (new NamedCollection() - { - Name = "V1", - Collection = primitives.ToList() - } - ); - } - - public object Clone() - { - var newItem = new LimitCurveInputData() - { - LimitStates = LimitStates.ToList(), - CalcTerms = CalcTerms.ToList(), - PredicateEntries = PredicateEntries.ToList(), - SurroundData = SurroundData.Clone() as SurroundData, - PointCount = PointCount - }; - foreach (var item in PrimitiveSeries) - { - var collection = item.Collection.ToList(); - newItem.PrimitiveSeries.Add - ( - new NamedCollection() - { - Name = item.Name, - Collection = collection - } - ); - } - return newItem; - - } - } -} diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurvesCalculator.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurvesCalculator.cs index 25a6e35..8bfd38f 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurvesCalculator.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurvesCalculator.cs @@ -11,7 +11,7 @@ using StructureHelperLogics.Services.NdmPrimitives; namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces { - public class LimitCurvesCalculator : ISaveable, ICalculator, IHasActionByResult + public class LimitCurvesCalculator : ILimitCurvesCalculator { private LimitCurvesResult result; private int curvesIterationCount; @@ -21,7 +21,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces public Guid Id { get; } public string Name { get; set; } - public LimitCurveInputData InputData { get; set; } + public LimitCurvesCalculatorInputData InputData { get; set; } public IResult Result => result; public Action ActionToOutputResults { get; set; } @@ -89,7 +89,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces }; var ndms = triangulateLogic.GetNdms(); TraceLogger?.AddMessage($"Number of elementary parts N={ndms.Count()} were obtainded successfully"); - TraceLogger?.AddMessage($"Summary area of elementary parts Asum={ndms.Sum(x=>x.Area * x.StressScale)}", TraceLogStatuses.Debug); + TraceLogger?.AddMessage($"Summary area of elementary parts Asum={ndms.Sum(x => x.Area * x.StressScale)}", TraceLogStatuses.Debug); foreach (var predicateEntry in InputData.PredicateEntries) { string calcName = $"{primitiveSeries.Name}_{predicateEntry.Name}_{limitState}_{calcTerm}"; diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurvesCalculatorInputData.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurvesCalculatorInputData.cs new file mode 100644 index 0000000..22b087b --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurvesCalculatorInputData.cs @@ -0,0 +1,51 @@ +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Infrastructures.Settings; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models.Parameters; +using StructureHelperCommon.Models.Shapes; +using StructureHelperLogics.NdmCalculations.Analyses.ByForces.LimitCurve; +using StructureHelperLogics.NdmCalculations.Primitives; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +//Copyright (c) 2023 Redikultsev Evgeny, Ekaterinburg, Russia +//All rights reserved. + +namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces +{ + public class LimitCurvesCalculatorInputData : ILimitCurvesCalculatorInputData + { + private ICloneStrategy cloneStrategy = new LimitCurvesCalculatorInputDataCloneStrategy(); + public List LimitStates { get; private set; } = new(); + public List CalcTerms { get; private set; } = new(); + public List> PrimitiveSeries { get; private set; } = new(); + public List PredicateEntries { get; private set; } = new(); + public ISurroundData SurroundData { get; set; } = new SurroundData(); + public int PointCount { get; set; } = 80; + public LimitCurvesCalculatorInputData() + { + } + public LimitCurvesCalculatorInputData(IEnumerable primitives) + { + PrimitiveSeries.Add + (new NamedCollection() + { + Name = "V1", + Collection = primitives.ToList() + } + ); + } + + public object Clone() + { + var newItem = cloneStrategy.GetClone(this); + return newItem; + + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurvesCalculatorInputDataCloneStrategy.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurvesCalculatorInputDataCloneStrategy.cs new file mode 100644 index 0000000..ed94434 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurvesCalculatorInputDataCloneStrategy.cs @@ -0,0 +1,32 @@ +using StructureHelperCommon.Infrastructures.Interfaces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces.LimitCurve +{ + + public class LimitCurvesCalculatorInputDataCloneStrategy : ICloneStrategy + { + private IUpdateStrategy updateStrategy; + + public LimitCurvesCalculatorInputDataCloneStrategy(IUpdateStrategy updateStrategy) + { + this.updateStrategy = updateStrategy; + } + + public LimitCurvesCalculatorInputDataCloneStrategy() : this (new LimitCurvesCalculatorInputDataUpdateStrategy()) + { + + } + + public ILimitCurvesCalculatorInputData GetClone(ILimitCurvesCalculatorInputData sourceObject) + { + LimitCurvesCalculatorInputData newItem = new(); + updateStrategy.Update(newItem, sourceObject); + return newItem; + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurvesCalculatorInputDataUpdateStrategy.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurvesCalculatorInputDataUpdateStrategy.cs new file mode 100644 index 0000000..da66da7 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurvesCalculatorInputDataUpdateStrategy.cs @@ -0,0 +1,42 @@ +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models.Parameters; +using StructureHelperCommon.Services; +using StructureHelperLogics.NdmCalculations.Primitives; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces.LimitCurve +{ + public class LimitCurvesCalculatorInputDataUpdateStrategy : IUpdateStrategy + { + public void Update(ILimitCurvesCalculatorInputData targetObject, ILimitCurvesCalculatorInputData sourceObject) + { + CheckObject.IsNull(targetObject, sourceObject, "Limit curve calculator input data"); + if (ReferenceEquals(targetObject, sourceObject)) { return; } + targetObject.LimitStates.Clear(); + targetObject.CalcTerms.Clear(); + targetObject.PredicateEntries.Clear(); + targetObject.LimitStates.AddRange(sourceObject.LimitStates); + targetObject.CalcTerms.AddRange(sourceObject.CalcTerms); + targetObject.PredicateEntries.AddRange(sourceObject.PredicateEntries); + targetObject.SurroundData = sourceObject.SurroundData.Clone() as ISurroundData; + targetObject.PointCount = sourceObject.PointCount; + foreach (var item in sourceObject.PrimitiveSeries) + { + var collection = item.Collection.ToList(); + targetObject.PrimitiveSeries.Add + ( + new NamedCollection() + { + Name = item.Name, + Collection = collection + } + ); + } + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/RectSurroundProc.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/RectSurroundProc.cs index 9a59403..c268a54 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/RectSurroundProc.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/RectSurroundProc.cs @@ -12,7 +12,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces { private List surroundList; - public SurroundData SurroundData { get; set; } + public ISurroundData SurroundData { get; set; } public int PointCount { get; set; } public RectSurroundProc() diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/RoundSurroundProc.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/RoundSurroundProc.cs index 4520f39..b9b2388 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/RoundSurroundProc.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/RoundSurroundProc.cs @@ -11,12 +11,12 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces { private List surroundList; - public SurroundData SurroundData { get; set; } + public ISurroundData SurroundData { get; set; } public int PointCount { get; set; } public RoundSurroundProc() { - SurroundData = new(); + SurroundData = new SurroundData(); } public List GetPoints() { diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/SurroundData.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/SurroundData.cs index 045e37c..6ac0b3b 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/SurroundData.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/SurroundData.cs @@ -14,7 +14,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces /// /// Limits of coordinates for workplane /// - public class SurroundData : ICloneable + public class SurroundData : ISurroundData { public double XMax { get; set; } public double XMin { get; set; } diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/Logics/LimitCurveInputDataUpdateStrategy.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/Logics/LimitCurveInputDataUpdateStrategy.cs index f45bdfd..92169b3 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/Logics/LimitCurveInputDataUpdateStrategy.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/Logics/LimitCurveInputDataUpdateStrategy.cs @@ -3,10 +3,10 @@ using StructureHelperCommon.Models.Parameters; namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces.Logics { - internal class LimitCurveInputDataUpdateStrategy : IUpdateStrategy + internal class LimitCurveInputDataUpdateStrategy : IUpdateStrategy { - SurroundDataUpdateStrategy surroundDataUpdateStrategy => new(); - public void Update(LimitCurveInputData targetObject, LimitCurveInputData sourceObject) + IUpdateStrategy surroundDataUpdateStrategy = new SurroundDataUpdateStrategy(); + public void Update(ILimitCurvesCalculatorInputData targetObject, ILimitCurvesCalculatorInputData sourceObject) { if (ReferenceEquals(targetObject, sourceObject)) { return; } targetObject.LimitStates.Clear(); diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/Logics/SurroundDataUpdateStrategy.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/Logics/SurroundDataUpdateStrategy.cs index 5bcba48..7ed53aa 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/Logics/SurroundDataUpdateStrategy.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/Logics/SurroundDataUpdateStrategy.cs @@ -8,9 +8,9 @@ using System.Threading.Tasks; namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces.Logics { - internal class SurroundDataUpdateStrategy : IUpdateStrategy + internal class SurroundDataUpdateStrategy : IUpdateStrategy { - public void Update(SurroundData targetObject, SurroundData sourceObject) + public void Update(ISurroundData targetObject, ISurroundData sourceObject) { if (ReferenceEquals(targetObject, sourceObject)) { return; } targetObject.XMax = sourceObject.XMax; diff --git a/StructureHelperLogics/Services/NdmPrimitives/ForcesParametersLogic.cs b/StructureHelperLogics/Services/NdmPrimitives/ForcesParametersLogic.cs index 9ae53a1..cb3b9cf 100644 --- a/StructureHelperLogics/Services/NdmPrimitives/ForcesParametersLogic.cs +++ b/StructureHelperLogics/Services/NdmPrimitives/ForcesParametersLogic.cs @@ -17,6 +17,7 @@ namespace StructureHelperLogics.Services.NdmPrimitives { const string prefixInitial = "Initial"; const string prefixActual = "Actual"; + private const string errorValue = "----"; IConvertUnitLogic operationLogic = new ConvertUnitLogic(); IGetUnitLogic unitLogic = new GetUnitLogic(); @@ -186,60 +187,60 @@ namespace StructureHelperLogics.Services.NdmPrimitives return parameters; } - private List> GetDistance(IEnumerable locNdms, IStrainMatrix? locStrainMatrix, PosNegFlag flag, string excentricityName, Func, IStrainMatrix, PosNegFlag, (double dX, double dY, double dSum)> func) + private List> GetDistance(IEnumerable locNdms, IStrainMatrix? locStrainMatrix, PosNegFlag flag, string eccentricityName, Func, IStrainMatrix, PosNegFlag, (double dX, double dY, double dSum)> func) { var parameters = new List>(); var unitType = UnitTypes.Length; var unit = unitLogic.GetUnit(unitType, "mm"); var unitName = unit.Name; var unitMultiPlayer = unit.Multiplyer; - var sumExcenticityX = new ValueParameter() + var sumEccenticityX = new ValueParameter() { IsValid = true, - Name = $"{excentricityName} excentricity", + Name = $"{eccentricityName} eccentricity", ShortName = $"e{firstAxisName.ToLower()},sum", Text = unitName, - Description = $"{excentricityName} force excentricity along {firstAxisName.ToUpper()}-axis" + Description = $"{eccentricityName} force excentricity along {firstAxisName.ToUpper()}-axis" }; var sumExcenticityY = new ValueParameter() { IsValid = true, - Name = $"{excentricityName} excentricity", + Name = $"{eccentricityName} eccentricity", ShortName = $"e{secondAxisName.ToLower()},sum", Text = unitName, - Description = $"{excentricityName} force excentricity along {secondAxisName.ToUpper()}-axis" + Description = $"{eccentricityName} force eccentricity along {secondAxisName.ToUpper()}-axis" }; var sumExcenticity = new ValueParameter() { IsValid = true, - Name = $"{excentricityName} excentricity", + Name = $"{eccentricityName} eccentricity", ShortName = $"e,sum", Text = unitName, - Description = $"{excentricityName} force excentricity" + Description = $"{eccentricityName} force eccentricity" }; try { - var sumExcentricityValue = func.Invoke(locNdms, locStrainMatrix, flag); - sumExcenticityX.Value = (sumExcentricityValue.dX * unitMultiPlayer).ToString(); - sumExcenticityY.Value = (sumExcentricityValue.dY * unitMultiPlayer).ToString(); - sumExcenticity.Value = (sumExcentricityValue.dSum * unitMultiPlayer).ToString(); + var sumEccentricityValue = func.Invoke(locNdms, locStrainMatrix, flag); + sumEccenticityX.Value = (sumEccentricityValue.dX * unitMultiPlayer).ToString(); + sumExcenticityY.Value = (sumEccentricityValue.dY * unitMultiPlayer).ToString(); + sumExcenticity.Value = (sumEccentricityValue.dSum * unitMultiPlayer).ToString(); } catch (Exception ex) { - sumExcenticityX.IsValid = false; - sumExcenticityX.Value = (double.NaN).ToString(); - sumExcenticityX.Description += $": {ex}"; + sumEccenticityX.IsValid = false; + sumEccenticityX.Value = errorValue; + sumEccenticityX.Description += $": {ex}"; sumExcenticityY.IsValid = false; - sumExcenticityY.Value = (double.NaN).ToString(); + sumExcenticityY.Value = errorValue; sumExcenticityY.Description += $": {ex}"; sumExcenticity.IsValid = false; - sumExcenticity.Value = (double.NaN).ToString(); + sumExcenticity.Value = errorValue; sumExcenticity.Description += $": {ex}"; } - parameters.Add(sumExcenticityX); + parameters.Add(sumEccenticityX); parameters.Add(sumExcenticityY); parameters.Add(sumExcenticity); return parameters; @@ -254,7 +255,7 @@ namespace StructureHelperLogics.Services.NdmPrimitives return parameters; } - private IEnumerable> GetLiverArms(IEnumerable locNdms, IStrainMatrix? locStrainMatrix, string excentricityName, Func, IStrainMatrix, (double dX, double dY, double dSum)> func) + private IEnumerable> GetLiverArms(IEnumerable locNdms, IStrainMatrix? locStrainMatrix, string eccentricityName, Func, IStrainMatrix, (double dX, double dY, double dSum)> func) { const string liverArm = "liver arm"; var parameters = new List>(); @@ -265,26 +266,26 @@ namespace StructureHelperLogics.Services.NdmPrimitives var sumLiverArmX = new ValueParameter() { IsValid = true, - Name = $"{excentricityName} {liverArm}", + Name = $"{eccentricityName} {liverArm}", ShortName = $"z,{firstAxisName.ToLower()}", Text = unitName, - Description = $"{excentricityName} {liverArm} along {firstAxisName.ToUpper()}-axis" + Description = $"{eccentricityName} {liverArm} along {firstAxisName.ToUpper()}-axis" }; var sumLiverArmY = new ValueParameter() { IsValid = true, - Name = $"{excentricityName} {liverArm}", + Name = $"{eccentricityName} {liverArm}", ShortName = $"z,{secondAxisName.ToLower()}", Text = unitName, - Description = $"{excentricityName} {liverArm} along {secondAxisName.ToUpper()}-axis" + Description = $"{eccentricityName} {liverArm} along {secondAxisName.ToUpper()}-axis" }; var sumLiverArm = new ValueParameter() { IsValid = true, - Name = $"{excentricityName} {liverArm}", + Name = $"{eccentricityName} {liverArm}", ShortName = $"z,sum", Text = unitName, - Description = $"{excentricityName} {liverArm}" + Description = $"{eccentricityName} {liverArm}" }; try { @@ -296,15 +297,15 @@ namespace StructureHelperLogics.Services.NdmPrimitives catch (Exception ex) { sumLiverArmX.IsValid = false; - sumLiverArmX.Value = (double.NaN).ToString(); + sumLiverArmX.Value = errorValue; sumLiverArmX.Description += $": {ex}"; sumLiverArmY.IsValid = false; - sumLiverArmY.Value = (double.NaN).ToString(); + sumLiverArmY.Value = errorValue; sumLiverArmY.Description += $": {ex}"; sumLiverArm.IsValid = false; - sumLiverArm.Value = (double.NaN).ToString(); + sumLiverArm.Value = errorValue; sumLiverArm.Description += $": {ex}"; } diff --git a/StructureHelperTests/UnitTests/UpdateStrategiesTests/HeadMaterialUpdateStrategyTests.cs b/StructureHelperTests/UnitTests/UpdateStrategiesTests/HeadMaterialUpdateStrategyTests.cs new file mode 100644 index 0000000..874320e --- /dev/null +++ b/StructureHelperTests/UnitTests/UpdateStrategiesTests/HeadMaterialUpdateStrategyTests.cs @@ -0,0 +1,163 @@ +using LoaderCalculator.Data.Materials; +using NUnit.Framework; +using StructureHelper.Models.Materials; +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models.Materials.Libraries; +using StructureHelperLogics.Models.Materials; +using System; +using System.Windows.Media; + +namespace StructureHelperTests.UnitTests.UpdateStrategiesTests +{ + + + [TestFixture] + public class HeadMaterialUpdateStrategyTests + { + private HeadMaterialUpdateStrategy _strategy; + + [SetUp] + public void SetUp() + { + _strategy = new HeadMaterialUpdateStrategy( + new MockBaseUpdateStrategy(), + new MockHelperMaterialUpdateStrategy() + ); + } + + [Test] + public void Update_ShouldThrowException_WhenTargetObjectIsNull() + { + var sourceObject = new MockHeadMaterial(); + + Assert.Throws(() => _strategy.Update(null, sourceObject)); + } + + [Test] + public void Update_ShouldThrowException_WhenSourceObjectIsNull() + { + var targetObject = new MockHeadMaterial(); + + Assert.Throws(() => _strategy.Update(targetObject, null)); + } + + [Test] + public void Update_ShouldNotThrow_WhenTargetAndSourceAreSameReference() + { + var targetAndSource = new MockHeadMaterial(); + + Assert.DoesNotThrow(() => _strategy.Update(targetAndSource, targetAndSource)); + } + + [Test] + public void Update_ShouldUpdateBaseProperties() + { + // Arrange + var targetObject = new MockHeadMaterial { Name = "Original", Color = Color.FromRgb(0,0,0) }; + var sourceObject = new MockHeadMaterial { Name = "Updated", Color = Color.FromRgb(255, 0, 0), HelperMaterial = new MockHelperMaterial() }; + + // Act + _strategy.Update(targetObject, sourceObject); + + // Assert + Assert.AreEqual("Updated", targetObject.Name, "Name should be updated"); + Assert.AreEqual(Color.FromRgb(255, 0, 0), targetObject.Color, "Color should be updated"); + } + + [Test] + public void Update_ShouldCloneAndUpdateHelperMaterial() + { + // Arrange + MockHeadMaterial targetObject = new (){ HelperMaterial = new MockHelperMaterial { Property = "Original" } }; + var sourceObject = new MockHeadMaterial { HelperMaterial = new MockHelperMaterial { Property = "Updated" } }; + + // Act + _strategy.Update(targetObject, sourceObject); + + // Assert + Assert.AreEqual("Updated", (targetObject.HelperMaterial as MockHelperMaterial).Property, "HelperMaterial property should be updated"); + Assert.AreNotSame(sourceObject.HelperMaterial, targetObject.HelperMaterial, + "HelperMaterial should be cloned, not directly assigned"); + } + + #region Mocks + private class MockHeadMaterial : IHeadMaterial + { + public string Name { get; set; } + public Color Color { get; set; } + public IHelperMaterial HelperMaterial { get; set; } + + public Guid Id => throw new NotImplementedException(); + + public object Clone() + { + return new MockHeadMaterial + { + Name = this.Name, + Color = this.Color, + HelperMaterial = this.HelperMaterial?.Clone() as IHelperMaterial + }; + } + + public IMaterial GetLoaderMaterial(LimitStates limitState, CalcTerms calcTerm) + { + throw new NotImplementedException(); + } + + public IMaterial GetCrackedLoaderMaterial(LimitStates limitState, CalcTerms calcTerm) + { + throw new NotImplementedException(); + } + } + + private class MockHelperMaterial : IHelperMaterial + { + public string Property { get; set; } + + public Guid Id => throw new NotImplementedException(); + + public List SafetyFactors { get; set; } + + public object Clone() + { + return new MockHelperMaterial { Property = this.Property }; + } + + public IMaterial GetCrackedLoaderMaterial(LimitStates limitState, CalcTerms calcTerm) + { + throw new NotImplementedException(); + } + + public IMaterial GetLoaderMaterial(LimitStates limitState, CalcTerms calcTerm) + { + throw new NotImplementedException(); + } + } + + private class MockBaseUpdateStrategy : IUpdateStrategy + { + public void Update(IHeadMaterial targetObject, IHeadMaterial sourceObject) + { + if (targetObject == null || sourceObject == null) return; + + targetObject.Name = sourceObject.Name; + targetObject.Color = sourceObject.Color; + } + } + + private class MockHelperMaterialUpdateStrategy : IUpdateStrategy + { + public void Update(IHelperMaterial targetObject, IHelperMaterial sourceObject) + { + if (targetObject != null && sourceObject != null) + { + (targetObject as MockHelperMaterial).Property = (sourceObject as MockHelperMaterial).Property; + } + } + } + #endregion + } + +}