Choose your top Archicad wishes!

Read more
Archicad C++ API
About Archicad add-on development using the C++ API.

Help with setting morph's hidden edges in the API

ManelCG
Contributor

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!

4 REPLIES 4

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:

  • elem.morph.level seems to always come out to 1.0
  • elem.morph.bodyType seems to always result in APIMorphBodyType_Solid
  • elem.morph.edgeType seems to always come out to APIMorphEdgeType_HardVisibleEdge

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

Bernd Schwarzenbacher - Archicad Add-On Developer - Get Add-Ons & Archicad Tips on my Website: Archi-XT.com

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

Aathil
Contributor

@ManelCG @BerndSchwarzenbacher  Any updates on this? I am also facing the same

ManelCG
Contributor

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 😅

Didn't find the answer?

Check other topics in this Forum

Back to Forum

Read the latest accepted solutions!

Accepted Solutions

Start a new conversation!