Skip to content

Commit

Permalink
2098 Archicad Connector geometry fidelity
Browse files Browse the repository at this point in the history
  • Loading branch information
József L. Kiss committed Feb 9, 2023
1 parent 19215cb commit c18c3b6
Show file tree
Hide file tree
Showing 39 changed files with 1,927 additions and 703 deletions.
1 change: 1 addition & 0 deletions ConnectorArchicad/AddOn/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ function (SetCompilerOptions target)
target_compile_options (${target} PUBLIC /W4 /WX
/Zc:wchar_t-
/wd4499
/wd4996
)
else ()
target_compile_options (${target} PUBLIC -Wall -Wextra -Werror
Expand Down
4 changes: 4 additions & 0 deletions ConnectorArchicad/AddOn/Sources/AddOn/AddOnMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "Commands/GetWindowData.hpp"
#include "Commands/GetBeamData.hpp"
#include "Commands/GetColumnData.hpp"
#include "Commands/GetObjectData.hpp"
#include "Commands/GetSlabData.hpp"
#include "Commands/GetRoomData.hpp"
#include "Commands/GetProjectInfo.hpp"
Expand All @@ -23,6 +24,7 @@
#include "Commands/CreateWindow.hpp"
#include "Commands/CreateBeam.hpp"
#include "Commands/CreateColumn.hpp"
#include "Commands/CreateObject.hpp"
#include "Commands/CreateSlab.hpp"
#include "Commands/CreateZone.hpp"
#include "Commands/CreateDirectShape.hpp"
Expand Down Expand Up @@ -175,6 +177,7 @@ static GSErrCode RegisterAddOnCommands ()
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::GetSubElementInfo> ()));
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::GetBeamData> ()));
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::GetColumnData> ()));
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::GetObjectData> ()));
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::GetRoomData> ()));
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::GetSlabData> ()));
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::GetProjectInfo> ()));
Expand All @@ -183,6 +186,7 @@ static GSErrCode RegisterAddOnCommands ()
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::CreateWindow> ()));
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::CreateBeam> ()));
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::CreateColumn> ()));
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::CreateObject> ()));
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::CreateSlab> ()));
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::CreateZone> ()));
CHECKERROR (ACAPI_Install_AddOnCommandHandler (NewOwned<AddOnCommands::CreateDirectShape> ()));
Expand Down
72 changes: 72 additions & 0 deletions ConnectorArchicad/AddOn/Sources/AddOn/AttributeManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include "AttributeManager.hpp"

GSErrCode AttributeManager::GetMaterial (const ModelInfo::Material& material, API_Attribute& attribute)
{
GS::UniString materialName (material.GetName ());
char typeId = API_MaterialID;
GS::UniString key = materialName + typeId;

if (cache.Get (key, &attribute)) {
return NoError;
} else {
BNZeroMemory (&attribute, sizeof (API_Attribute));

attribute.header.uniStringNamePtr = &materialName;
attribute.header.typeID = API_MaterialID;

GSErrCode err = ACAPI_Attribute_Get (&attribute);
if (NoError == err) {
cache.Add (key, attribute);
}

if (APIERR_BADNAME == err) {
attribute.material.mtype = APIMater_GeneralID;
attribute.material.ambientPc = 100;
attribute.material.diffusePc = 0;
attribute.material.specularPc = 0;

attribute.material.transpPc = material.GetTransparency ();
attribute.material.shine = 50;
attribute.material.transpAtt = 400;
attribute.material.emissionAtt = 0;

attribute.material.surfaceRGB.f_red = material.GetAmbientColor ().red / 65535.0;
attribute.material.surfaceRGB.f_green = material.GetAmbientColor ().green / 65535.0;
attribute.material.surfaceRGB.f_blue = material.GetAmbientColor ().blue / 65535.0;

attribute.material.specularRGB.f_red = .0;
attribute.material.specularRGB.f_green = .0;
attribute.material.specularRGB.f_blue = .0;

attribute.material.emissionRGB.f_red = material.GetEmissionColor ().red / 65535.0;
attribute.material.emissionRGB.f_green = material.GetEmissionColor ().green / 65535.0;
attribute.material.emissionRGB.f_blue = material.GetEmissionColor ().blue / 65535.0;

err = ACAPI_Attribute_Create (&attribute, 0);
if (NoError == err) {
cache.Add (key, attribute);
}
}

return err;
}
}


GSErrCode AttributeManager::GetDefaultMaterial (API_Attribute& attribute, GS::UniString& name)
{
GS_RGBColor ambientColor;
ambientColor.red = 0x7f * 256;
ambientColor.green = 0x7f * 256;
ambientColor.blue = 0x7f * 256;

GS_RGBColor emissionColor;
emissionColor.red = 0x0;
emissionColor.green = 0x0;
emissionColor.blue = 0x0;

name = "Default Speckle Surface";
ModelInfo::Material material (name, 0.0, ambientColor, emissionColor);

return GetMaterial (material, attribute);
}
15 changes: 15 additions & 0 deletions ConnectorArchicad/AddOn/Sources/AddOn/AttributeManager.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef ATTRIBUTE_MANAGER_HPP
#define ATTRIBUTE_MANAGER_HPP

#include "ModelInfo.hpp"

class AttributeManager {
private:
GS::HashTable< GS::UniString, API_Attribute> cache;

public:
GSErrCode GetMaterial (const ModelInfo::Material& material, API_Attribute& attribute);
GSErrCode GetDefaultMaterial (API_Attribute& attribute, GS::UniString& name);
};

#endif
172 changes: 9 additions & 163 deletions ConnectorArchicad/AddOn/Sources/AddOn/Commands/CreateBeam.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,184 +199,30 @@ static GSErrCode GetBeamFromObjectState (const GS::ObjectState& os, API_Element&
return Error;
}

API_AssemblySegmentSchemeData defaultBeamSegmentScheme;
if (memo->assemblySegmentSchemes != nullptr) {
defaultBeamSegmentScheme = memo->assemblySegmentSchemes[0];
memo->assemblySegmentSchemes = (API_AssemblySegmentSchemeData*) BMAllocatePtr ((element.beam.nSchemes) * sizeof (API_AssemblySegmentSchemeData), ALLOCATE_CLEAR, 0);
} else {
return Error;
}

API_AssemblySegmentCutData defaultBeamSegmentCut;
if (memo->assemblySegmentCuts != nullptr) {
defaultBeamSegmentCut = memo->assemblySegmentCuts[0];
memo->assemblySegmentCuts = (API_AssemblySegmentCutData*) BMAllocatePtr ((element.beam.nCuts) * sizeof (API_AssemblySegmentCutData), ALLOCATE_CLEAR, 0);
} else {
return Error;
}

#pragma region Segment
GS::ObjectState allSegments;
if (os.Contains (Beam::segmentData))
os.Get (Beam::segmentData, allSegments);
if (os.Contains (PartialObjects::SegmentData))
os.Get (PartialObjects::SegmentData, allSegments);

for (UInt32 idx = 0; idx < element.beam.nSegments; ++idx) {
GS::ObjectState currentSegment;
allSegments.Get (GS::String::SPrintf (Beam::BeamSegmentName, idx + 1), currentSegment);
allSegments.Get (GS::String::SPrintf (AssemblySegmentData::SegmentName, idx + 1), currentSegment);

memo->beamSegments[idx] = defaultBeamSegment;
if (!currentSegment.IsEmpty ()) {

if (currentSegment.Contains (Beam::circleBased))
currentSegment.Get (Beam::circleBased, memo->beamSegments[idx].assemblySegmentData.circleBased);
ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, assemblySegmentData.circleBased);

if (currentSegment.Contains (Beam::nominalHeight))
currentSegment.Get (Beam::nominalHeight, memo->beamSegments[idx].assemblySegmentData.nominalHeight);
ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, assemblySegmentData.nominalHeight);

if (currentSegment.Contains (Beam::nominalWidth))
currentSegment.Get (Beam::nominalWidth, memo->beamSegments[idx].assemblySegmentData.nominalWidth);
ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, assemblySegmentData.nominalWidth);

if (currentSegment.Contains (Beam::isWidthAndHeightLinked))
currentSegment.Get (Beam::isWidthAndHeightLinked, memo->beamSegments[idx].assemblySegmentData.isWidthAndHeightLinked);
ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, assemblySegmentData.isWidthAndHeightLinked);

if (currentSegment.Contains (Beam::isHomogeneous))
currentSegment.Get (Beam::isHomogeneous, memo->beamSegments[idx].assemblySegmentData.isHomogeneous);
ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, assemblySegmentData.isHomogeneous);

if (currentSegment.Contains (Beam::endWidth))
currentSegment.Get (Beam::endWidth, memo->beamSegments[idx].assemblySegmentData.endWidth);
ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, assemblySegmentData.endWidth);

if (currentSegment.Contains (Beam::endHeight))
currentSegment.Get (Beam::endHeight, memo->beamSegments[idx].assemblySegmentData.endHeight);
ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, assemblySegmentData.endHeight);

if (currentSegment.Contains (Beam::isEndWidthAndHeightLinked))
currentSegment.Get (Beam::isEndWidthAndHeightLinked, memo->beamSegments[idx].assemblySegmentData.isEndWidthAndHeightLinked);
ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, assemblySegmentData.isEndWidthAndHeightLinked);

if (currentSegment.Contains (Beam::modelElemStructureType)) {
API_ModelElemStructureType realStructureType = API_BasicStructure;
GS::UniString structureName;
currentSegment.Get (Beam::modelElemStructureType, structureName);

GS::Optional<API_ModelElemStructureType> tmpStructureType = structureTypeNames.FindValue (structureName);
if (tmpStructureType.HasValue ())
realStructureType = tmpStructureType.Get ();
memo->beamSegments[idx].assemblySegmentData.modelElemStructureType = realStructureType;
}
ACAPI_ELEMENT_MASK_SET (beamMask, API_BeamSegmentType, assemblySegmentData.modelElemStructureType);

if (currentSegment.Contains (Beam::profileAttrName)) {
GS::UniString attrName;
currentSegment.Get (Beam::profileAttrName, attrName);

if (!attrName.IsEmpty ()) {
API_Attribute attrib;
BNZeroMemory (&attrib, sizeof (API_Attribute));
attrib.header.typeID = API_ProfileID;
CHCopyC (attrName.ToCStr (), attrib.header.name);
err = ACAPI_Attribute_Get (&attrib);

if (err == NoError)
memo->beamSegments[idx].assemblySegmentData.profileAttr = attrib.header.index;
}
}

if (currentSegment.Contains (Beam::buildingMaterial)) {
GS::UniString attrName;
currentSegment.Get (Beam::buildingMaterial, attrName);

if (!attrName.IsEmpty ()) {
API_Attribute attrib;
BNZeroMemory (&attrib, sizeof (API_Attribute));
attrib.header.typeID = API_BuildingMaterialID;
CHCopyC (attrName.ToCStr (), attrib.header.name);
err = ACAPI_Attribute_Get (&attrib);

if (err == NoError)
memo->beamSegments[idx].assemblySegmentData.buildingMaterial = attrib.header.index;
}
}
}
}
#pragma endregion
Utility::CreateOneSegmentData (currentSegment, memo->beamSegments[idx].assemblySegmentData, beamMask);

#pragma region Scheme
GS::ObjectState allSchemes;
if (os.Contains (Beam::schemeData))
os.Get (Beam::schemeData, allSchemes);

for (UInt32 idx = 0; idx < element.beam.nSchemes; ++idx) {
if (!allSchemes.IsEmpty ()) {
GS::ObjectState currentScheme;
allSchemes.Get (GS::String::SPrintf (Beam::SchemeName, idx + 1), currentScheme);

memo->assemblySegmentSchemes[idx] = defaultBeamSegmentScheme;
if (!currentScheme.IsEmpty ()) {

if (currentScheme.Contains (Beam::lengthType)) {
API_AssemblySegmentLengthTypeID lengthType = APIAssemblySegment_Fixed;
GS::UniString lengthTypeName;
currentScheme.Get (Beam::lengthType, lengthTypeName);

GS::Optional<API_AssemblySegmentLengthTypeID> type = segmentLengthTypeNames.FindValue (lengthTypeName);
if (type.HasValue ())
lengthType = type.Get ();
memo->assemblySegmentSchemes[idx].lengthType = lengthType;

if (lengthType == APIAssemblySegment_Fixed && currentScheme.Contains (Beam::fixedLength)) {
currentScheme.Get (Beam::fixedLength, memo->assemblySegmentSchemes[idx].fixedLength);
memo->assemblySegmentSchemes[idx].lengthProportion = 0.0;
} else if (lengthType == APIAssemblySegment_Proportional && currentScheme.Contains (Beam::lengthProportion)) {
currentScheme.Get (Beam::lengthProportion, memo->assemblySegmentSchemes[idx].lengthProportion);
memo->assemblySegmentSchemes[idx].fixedLength = 0.0;
}
}
}
}
}
#pragma endregion

#pragma region Cut
GS::ObjectState allCuts;
if (os.Contains (Beam::cutData))
os.Get (Beam::cutData, allCuts);

for (UInt32 idx = 0; idx < element.beam.nCuts; ++idx) {
GS::ObjectState currentCut;
allCuts.Get (GS::String::SPrintf (Beam::CutName, idx + 1), currentCut);

memo->assemblySegmentCuts[idx] = defaultBeamSegmentCut;
if (!currentCut.IsEmpty ()) {

if (currentCut.Contains (Beam::cutType)) {
API_AssemblySegmentCutTypeID realCutType = APIAssemblySegmentCut_Vertical;
GS::UniString structureName;
currentCut.Get (Beam::cutType, structureName);

GS::Optional<API_AssemblySegmentCutTypeID> tmpCutType = assemblySegmentCutTypeNames.FindValue (structureName);
if (tmpCutType.HasValue ())
realCutType = tmpCutType.Get ();
memo->assemblySegmentCuts[idx].cutType = realCutType;
}
if (currentCut.Contains (Beam::customAngle)) {
currentCut.Get (Beam::customAngle, memo->assemblySegmentCuts[idx].customAngle);
}
}
}
#pragma endregion
Utility::CreateAllSchemeData (os, element.beam.nSchemes, element, beamMask, memo);
Utility::CreateAllCutData (os, element.beam.nCuts, element, beamMask, memo);

#pragma region Hole
GS::ObjectState allHoles;
UInt32 holesCount = 0;

if (os.Contains (Beam::holeData)) {
os.Get (Beam::holeData, allHoles);
if (os.Contains (PartialObjects::HoleData)) {
os.Get (PartialObjects::HoleData, allHoles);
holesCount = allHoles.GetFieldCount ();
}

Expand Down Expand Up @@ -418,10 +264,10 @@ static GSErrCode GetBeamFromObjectState (const GS::ObjectState& os, API_Element&
}
}
}
#pragma endregion

return NoError;
}
#pragma endregion

GS::String CreateBeam::GetName () const
{
Expand Down
Loading

0 comments on commit c18c3b6

Please sign in to comment.