2024 Technology Preview Program:
Master powerful new features and shape the latest BIM-enabled innovations
2023-10-25 02:49 PM - edited 2023-10-25 02:50 PM
Hello everyone,
This is my first post in this forum, so I hope everything is fine in it.
Over the last few months I have been developing an ArchiCAD add-on for the company I work at. The Add-On is pretty much finished, however, there is one issue that bugs us.
At some point in the addon, I am creating a bunch of morphs. We want the morphs to have Hard Hidden edges. I noticed that the API setting for this (HardVisible, HardHidden and SoftHidden) basically serves the same purpose as the EdgeType buttons in the AC GUI (Hard, Hidden and Soft).
typedef enum {
APIMorphEdgeType_SoftHiddenEdge,
APIMorphEdgeType_HardHiddenEdge,
APIMorphEdgeType_HardVisibleEdge
} API_MorphEdgeTypeID;
However, no matter how many different things I try, I cannot get the morphs to be imported with the hard-hidden setting. They always get imported as hard-visible.
Note that, selecting all the morphs inside the GUI and manually clicking the "Hidden Edge" button, succeeds to set the morphs edge type, and the result is what we want.
Also note that my addon also creates Mesh objects, which do succesfuly get imported with hidden edges. Our problem is only with the morphs.
Here is a summary of how I am creating the morphs (I will omit very long parts of the code, so there might be errors in the attached code):
Please note: The AC class is a small static class that I created that wraps the very repetitive ACAPI calls.
GSErrCode Importer::CreateMorph(...) {
API_Element acMorph;
API_ElementMemo memo;
GSErrCode err = AC::InitAPIElement(API_MorphID, acMorph, memo); // A small function that wraps the BNZeroMemory functions and all that stuff
// Note: I am clearly setting the HardHiddenEdge
acMorph.morph.edgeType = APIMorphEdgeType_HardHiddenEdge;
acMorph.morph.bodyType = APIMorphBodyType_SolidBody;
acMorph.morph.castShadow = true;
acMorph.morph.receiveShadow = true;
// Transformation matrix for morph.
acMorph.morph.tranmat = AC::GetMorphTMX(*T);
// construct the body structure
auto bodyData = AC::InitMorphBodyData();
// Set the body shape, materials, etc (long code so I ommit it)
// close the body and copy it to the memo
err = ACAPI_Body_Finish (bodyData, &memo.morphBody, &memo.morphMaterialMapTable);
if(err != NoError)
... handling errors
err = ACAPI_Body_Dispose (&bodyData);
if(err != NoError)
... handling errors
err = ACAPI_Element_Create (&acMorph, &memo);
if(err != NoError)
... handling errors
ACAPI_DisposeElemMemoHdls (&memo);
return err;
}
Once the addon finishes its execution, the morphs have the Hard Visible edge type.
Furthermore, if I do the following while debugging:
void AC::SetMorphHiddenEdges(API_Guid g)
{
API_Element elem;
GetElementFromGuid(g, &elem);
// elem.morph.edgeType = APIMorphEdgeType_HardVisibleEdge although it was set in the CreateMorphFunction to be HardHidden???
// Explicitly set it to hard hidden
elem.morph.edgeType = APIMorphEdgeType_HardHiddenEdge;
auto err = ACAPI_Element_Change(&elem, nullptr, nullptr, 0, true);
// err is NoError!
GetElementFromGuid(g, &elem);
// elem.morph.edgeType is hardvisible again!
return;
}
it is clearly shown by my debugger that after calling the Element Change function, and retrieving the morph again by its guid, the edge type has been reset again to the hard visible.
I also tried using this method, with no success:
void AC::SetMorphHiddenEdges(API_Guid g)
{
API_Element elem;
API_Element pars;
API_Element mask;
BNZeroMemory(&elem, sizeof(API_Element));
GetElementFromGuid(g, &elem);
// elem.morph.edgeType is hardVisible, lets try to fix that...
BNZeroMemory(&pars, sizeof(API_Element));
BNZeroMemory(&mask, sizeof(API_Element));
ACAPI_ELEMENT_MASK_CLEAR(mask);
ACAPI_ELEMENT_MASK_SET(mask, API_MorphType, edgeType);
pars.header.type = API_MorphID;
pars.morph.edgeType = APIMorphEdgeType_HardHiddenEdge;
GS::Array<API_Guid> guids({ g });
auto err = ACAPI_Element_ChangeMore(guids, &pars, nullptr, &mask, 0, true);
BNZeroMemory(&elem, sizeof(API_Element));
GetElementFromGuid(g, &elem);
// elem.morph.edgeType is still hard visible!
}
Am I missing something? How can I change this setting from the API?
Any help is greatly appreciated. Also, if I must post some extra information, please do not hesitate to ask me!
2023-10-25 08:59 PM
Hi Manel,
To me it looks like you are doing everything right. I was curious and tried it myself and also found the same behavior as you.
Curiously these 3 things seem to be ignored by ACAPI_Element_Create:
I'm wondering if there's some bug in the API. The 3 mentioned fields are aligned in memory right after each other, so that might be a clue, but it's really shooting in the dark.
Also, when creating a morph manually in Archicad, one can only choose Hard Visible edges. That might also be related.
Sorry I couldn't be of more help, but I hope knowing that you are not the only one stumped by this might help a bit 😅
Best,
Bernd
2023-10-27 11:28 AM
Hello Bernd,
Thanks for the reply 🙂
Yes it seems to be a bug, the interesting thing is that for us it happens in every version that our addon supports (from AC 23 to AC 27), so my thoughts where that either I was doing something horribly wrong, or this feature is just so unpopular that no one else noticed?
Anyways thanks for the help, greatly appreciated!
- Manel
2024-03-05 07:59 AM
@ManelCG @BerndSchwarzenbacher Any updates on this? I am also facing the same
2024-03-05 10:49 AM
No, as of today we still haven't found a solution to this problem. It very much looks like an API bug or some oversight. Really hoping that this gets fixed in some upcoming version as we would benefit from this feature working as intended. There have been an embarrassing amount of hours gone into trying to fix this 😅