Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bjorn/cnx-880-add-sections-and-materials-as-proxies #499

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Speckle.Connectors.CSiShared.Utils;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Converters.CSiShared.Utils;

namespace Speckle.Connectors.CSiShared.Bindings;

Expand All @@ -25,18 +26,6 @@ public CsiSharedSelectionBinding(IBrowserBridge parent, ICsiApplicationService c
/// </remarks>
public SelectionInfo GetSelection()
{
// TODO: Since this is standard across CSi Suite - better stored in an enum?
var objectTypeMap = new Dictionary<int, string>
{
{ 1, "Point" },
{ 2, "Frame" },
{ 3, "Cable" },
{ 4, "Tendon" },
{ 5, "Area" },
{ 6, "Solid" },
{ 7, "Link" }
};

int numberItems = 0;
int[] objectType = Array.Empty<int>();
string[] objectName = Array.Empty<string>();
Expand All @@ -48,10 +37,10 @@ public SelectionInfo GetSelection()

for (int i = 0; i < numberItems; i++)
{
var typeKey = objectType[i];
var typeName = objectTypeMap.TryGetValue(typeKey, out var name) ? name : $"Unknown ({typeKey})";
var typeKey = (ModelObjectType)objectType[i];
var typeName = typeKey.ToString();

encodedIds.Add(ObjectIdentifier.Encode(typeKey, objectName[i]));
encodedIds.Add(ObjectIdentifier.Encode(objectType[i], objectName[i]));
typeCounts[typeName] = (typeCounts.TryGetValue(typeName, out var count) ? count : 0) + 1; // NOTE: Cross-framework compatibility (net 48 and net8)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
using Speckle.Converters.Common;
using Speckle.Converters.CSiShared;
using Speckle.Converters.CSiShared.Utils;

namespace Speckle.Connectors.CSiShared.HostApp.Helpers;

/// <summary>
/// Base frame section property extractor for CSi products.
/// </summary>
/// <remarks>
/// Handles common Csi API calls for frame section properties
/// Provides foundation for application-specific extractors.
/// </remarks>
public class CsiFrameSectionPropertyExtractor : IFrameSectionPropertyExtractor
{
private readonly IConverterSettingsStore<CsiConversionSettings> _settingsStore;

public CsiFrameSectionPropertyExtractor(IConverterSettingsStore<CsiConversionSettings> settingsStore)
{
_settingsStore = settingsStore;
}

public void ExtractProperties(string sectionName, Dictionary<string, object?> properties)
{
GetMaterialName(sectionName, properties);
GetSectionProperties(sectionName, properties);
GetPropertyModifiers(sectionName, properties);
}

private void GetMaterialName(string sectionName, Dictionary<string, object?> properties)
{
// get material name
string materialName = string.Empty;
_settingsStore.Current.SapModel.PropFrame.GetMaterial(sectionName, ref materialName);

// append to General Data of properties dictionary
Dictionary<string, object?> generalData = DictionaryUtils.EnsureNestedDictionary(
properties,
SectionPropertyCategory.GENERAL_DATA
);
generalData["material"] = materialName;
}

private void GetSectionProperties(string sectionName, Dictionary<string, object?> properties)
{
double crossSectionalArea = 0,
shearAreaInMajorAxisDirection = 0,
shearAreaInMinorAxisDirection = 0,
torsionalConstant = 0,
momentOfInertiaAboutMajorAxis = 0,
momentOfInertiaAboutMinorAxis = 0,
sectionModulusAboutMajorAxis = 0,
sectionModulusAboutMinorAxis = 0,
plasticModulusAboutMajorAxis = 0,
plasticModulusAboutMinorAxis = 0,
radiusOfGyrationAboutMajorAxis = 0,
radiusOfGyrationAboutMinorAxis = 0;

_settingsStore.Current.SapModel.PropFrame.GetSectProps(
sectionName,
ref crossSectionalArea,
ref shearAreaInMajorAxisDirection,
ref shearAreaInMinorAxisDirection,
ref torsionalConstant,
ref momentOfInertiaAboutMajorAxis,
ref momentOfInertiaAboutMinorAxis,
ref sectionModulusAboutMajorAxis,
ref sectionModulusAboutMinorAxis,
ref plasticModulusAboutMajorAxis,
ref plasticModulusAboutMinorAxis,
ref radiusOfGyrationAboutMajorAxis,
ref radiusOfGyrationAboutMinorAxis
);

Dictionary<string, object?> mechanicalProperties = DictionaryUtils.EnsureNestedDictionary(
properties,
SectionPropertyCategory.SECTION_PROPERTIES
);
mechanicalProperties["area"] = crossSectionalArea;
mechanicalProperties["As2"] = shearAreaInMajorAxisDirection;
mechanicalProperties["As3"] = shearAreaInMinorAxisDirection;
mechanicalProperties["torsion"] = torsionalConstant;
mechanicalProperties["I22"] = momentOfInertiaAboutMajorAxis;
mechanicalProperties["I33"] = momentOfInertiaAboutMinorAxis;
mechanicalProperties["S22"] = sectionModulusAboutMajorAxis;
mechanicalProperties["S33"] = sectionModulusAboutMinorAxis;
mechanicalProperties["Z22"] = plasticModulusAboutMajorAxis;
mechanicalProperties["Z33"] = plasticModulusAboutMinorAxis;
mechanicalProperties["R22"] = radiusOfGyrationAboutMajorAxis;
mechanicalProperties["R33"] = radiusOfGyrationAboutMinorAxis;
}

private void GetPropertyModifiers(string sectionName, Dictionary<string, object?> properties)
{
double[] stiffnessModifiersArray = [];
_settingsStore.Current.SapModel.PropFrame.GetModifiers(sectionName, ref stiffnessModifiersArray);

Dictionary<string, object?> modifiers =
new()
{
["crossSectionalAreaModifier"] = stiffnessModifiersArray[0],
["shearAreaInLocal2DirectionModifier"] = stiffnessModifiersArray[1],
["shearAreaInLocal3DirectionModifier"] = stiffnessModifiersArray[2],
["torsionalConstantModifier"] = stiffnessModifiersArray[3],
["momentOfInertiaAboutLocal2AxisModifier"] = stiffnessModifiersArray[4],
["momentOfInertiaAboutLocal3AxisModifier"] = stiffnessModifiersArray[5],
["mass"] = stiffnessModifiersArray[6],
["weight"] = stiffnessModifiersArray[7],
};

Dictionary<string, object?> generalData = DictionaryUtils.EnsureNestedDictionary(
properties,
SectionPropertyCategory.GENERAL_DATA
);
generalData["modifiers"] = modifiers;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
using Speckle.Converters.Common;
using Speckle.Converters.CSiShared;
using Speckle.Converters.CSiShared.Utils;

namespace Speckle.Connectors.CSiShared.HostApp.Helpers;

/// <summary>
/// Base material property extractor for CSi products.
/// </summary>
/// <remarks>
/// Currently, all material property extraction can happen on a CsiShared level which simplifies things a lot.
/// Properties depend on the directional symmetry of the material, hence the switch statements.
/// </remarks>
public class CsiMaterialPropertyExtractor
{
/// <summary>
/// Property strings for all mechanical properties, used by numerous methods.
/// </summary>
private static class MechanicalPropertyNames
{
public const string MODULUS_OF_ELASTICITY = "modulusOfElasticity";
public const string MODULUS_OF_ELASTICITY_ARRAY = "modulusOfElasticityArray";
public const string POISSON_RATIO = "poissonRatio";
public const string POISSON_RATIO_ARRAY = "poissonRatioArray";
public const string THERMAL_COEFFICIENT = "thermalCoefficient";
public const string THERMAL_COEFFICIENT_ARRAY = "thermalCoefficientArray";
public const string SHEAR_MODULUS = "shearModulus";
public const string SHEAR_MODULUS_ARRAY = "shearModulusArray";
}

private readonly IConverterSettingsStore<CsiConversionSettings> _settingsStore;

public CsiMaterialPropertyExtractor(IConverterSettingsStore<CsiConversionSettings> settingsStore)
{
_settingsStore = settingsStore;
}

public void ExtractProperties(string materialName, Dictionary<string, object?> properties)
{
GetGeneralProperties(materialName, properties);
GetWeightAndMassProperties(materialName, properties);
GetMechanicalProperties(materialName, properties);
}

private void GetGeneralProperties(string materialName, Dictionary<string, object?> properties)
{
{
eMatType materialType = default;
int materialColor = 0;
string materialNotes = string.Empty;
string materialGuid = string.Empty;

_settingsStore.Current.SapModel.PropMaterial.GetMaterial(
materialName,
ref materialType,
ref materialColor,
ref materialNotes,
ref materialGuid
);

var generalData = DictionaryUtils.EnsureNestedDictionary(properties, SectionPropertyCategory.GENERAL_DATA);
generalData["name"] = materialName;
generalData["type"] = materialType.ToString();
generalData["notes"] = materialNotes;
}
}

private void GetWeightAndMassProperties(string materialName, Dictionary<string, object?> properties)
{
double weightPerUnitVolume = double.NaN;
double massPerUnitVolume = double.NaN;

_settingsStore.Current.SapModel.PropMaterial.GetWeightAndMass(
materialName,
ref weightPerUnitVolume,
ref massPerUnitVolume
);

var weightAndMass = DictionaryUtils.EnsureNestedDictionary(properties, "Weight and Mass");
weightAndMass["w"] = weightPerUnitVolume;
weightAndMass["m"] = massPerUnitVolume;
}

private void GetMechanicalProperties(string materialName, Dictionary<string, object?> properties)
{
int materialDirectionalSymmetryKey = 0;
eMatType materialType = default;

_settingsStore.Current.SapModel.PropMaterial.GetTypeOAPI(
materialName,
ref materialType,
ref materialDirectionalSymmetryKey
);

var materialDirectionalSymmetryValue = materialDirectionalSymmetryKey switch
{
0 => DirectionalSymmetryType.ISOTROPIC,
1 => DirectionalSymmetryType.ORTHOTROPIC,
2 => DirectionalSymmetryType.ANISOTROPIC,
3 => DirectionalSymmetryType.UNIAXIAL,
_ => throw new ArgumentException($"Unknown symmetry type: {materialDirectionalSymmetryKey}")
};

var mechanicalProperties = DictionaryUtils.EnsureNestedDictionary(properties, "Mechanical Properties");
mechanicalProperties["directionalSymmetryType"] = materialDirectionalSymmetryValue.ToString();

GetMechanicalPropertiesByType(materialName, materialDirectionalSymmetryValue, mechanicalProperties);
}

private void GetMechanicalPropertiesByType(
string materialName,
DirectionalSymmetryType directionalSymmetryType,
Dictionary<string, object?> mechanicalProperties
)
{
switch (directionalSymmetryType)
{
case DirectionalSymmetryType.ISOTROPIC:
ExtractIsotropicProperties(materialName, mechanicalProperties);
break;
case DirectionalSymmetryType.ORTHOTROPIC:
ExtractOrthotropicProperties(materialName, mechanicalProperties);
break;
case DirectionalSymmetryType.ANISOTROPIC:
ExtractAnisotropicProperties(materialName, mechanicalProperties);
break;
case DirectionalSymmetryType.UNIAXIAL:
ExtractUniaxialProperties(materialName, mechanicalProperties);
break;
default:
throw new ArgumentException($"Unknown directional symmetry type: {directionalSymmetryType}");
}
}

private void ExtractIsotropicProperties(string materialName, Dictionary<string, object?> mechanicalProperties)
{
double modulusOfElasticity = double.NaN;
double poissonRatio = double.NaN;
double thermalCoefficient = double.NaN;
double shearModulus = double.NaN;

_settingsStore.Current.SapModel.PropMaterial.GetMPIsotropic(
materialName,
ref modulusOfElasticity,
ref poissonRatio,
ref thermalCoefficient,
ref shearModulus
);

mechanicalProperties[MechanicalPropertyNames.MODULUS_OF_ELASTICITY] = modulusOfElasticity;
mechanicalProperties[MechanicalPropertyNames.POISSON_RATIO] = poissonRatio;
mechanicalProperties[MechanicalPropertyNames.THERMAL_COEFFICIENT] = thermalCoefficient;
mechanicalProperties[MechanicalPropertyNames.SHEAR_MODULUS] = shearModulus;
}

private void ExtractOrthotropicProperties(string materialName, Dictionary<string, object?> mechanicalProperties)
{
double[] modulusOfElasticityArray = [];
double[] poissonRatioArray = [];
double[] thermalCoefficientArray = [];
double[] shearModulusArray = [];

_settingsStore.Current.SapModel.PropMaterial.GetMPOrthotropic(
materialName,
ref modulusOfElasticityArray,
ref poissonRatioArray,
ref thermalCoefficientArray,
ref shearModulusArray
);

mechanicalProperties[MechanicalPropertyNames.MODULUS_OF_ELASTICITY_ARRAY] = modulusOfElasticityArray;
mechanicalProperties[MechanicalPropertyNames.POISSON_RATIO_ARRAY] = poissonRatioArray;
mechanicalProperties[MechanicalPropertyNames.THERMAL_COEFFICIENT_ARRAY] = thermalCoefficientArray;
mechanicalProperties[MechanicalPropertyNames.SHEAR_MODULUS_ARRAY] = shearModulusArray;
}

private void ExtractAnisotropicProperties(string materialName, Dictionary<string, object?> mechanicalProperties)
{
double[] modulusOfElasticityArray = [];
double[] poissonRatioArray = [];
double[] thermalCoefficientArray = [];
double[] shearModulusArray = [];

_settingsStore.Current.SapModel.PropMaterial.GetMPAnisotropic(
materialName,
ref modulusOfElasticityArray,
ref poissonRatioArray,
ref thermalCoefficientArray,
ref shearModulusArray
);

mechanicalProperties[MechanicalPropertyNames.MODULUS_OF_ELASTICITY_ARRAY] = modulusOfElasticityArray;
mechanicalProperties[MechanicalPropertyNames.POISSON_RATIO_ARRAY] = poissonRatioArray;
mechanicalProperties[MechanicalPropertyNames.THERMAL_COEFFICIENT_ARRAY] = thermalCoefficientArray;
mechanicalProperties[MechanicalPropertyNames.SHEAR_MODULUS_ARRAY] = shearModulusArray;
}

private void ExtractUniaxialProperties(string materialName, Dictionary<string, object?> mechanicalProperties)
{
double modulusOfElasticity = double.NaN;
double thermalCoefficient = double.NaN;

_settingsStore.Current.SapModel.PropMaterial.GetMPUniaxial(
materialName,
ref modulusOfElasticity,
ref thermalCoefficient
);

mechanicalProperties[MechanicalPropertyNames.MODULUS_OF_ELASTICITY] = modulusOfElasticity;
mechanicalProperties[MechanicalPropertyNames.THERMAL_COEFFICIENT] = thermalCoefficient;
}
}
Loading
Loading