The Global Archicad Community

Stay informed. Get help. Share your knowledge.

Discussions about using GRAPHISOFT's tools (Archicad API, BIMx API, BIMcloud API) for independent software developers

Moderators: ejrolon, Barry Kelly, Karl Ottenstein, LaszloNagy, Gordana Radonic, nbalogh, gkmethy, mnguyen, Viktor Kovacs, Mihály Palenik, Tibor Lorántfy, rmasaki, MOREH Tamas, Akos Somorjai, Ed Brown

By Arc
#288936
Hello. I want to ask if there is any way to check if an element/body is an instance of another in Archicad 22's API. I have tried many things such as checking Guids of the various components, comparing indexes of polygons. But after much testing, it is extremely difficult to verify whether or not an element still remains an instance of element.

In Archicad 21, I used to be able to extract the ModelerAPI::BaseElem from the ModellerAPI::Element and check the hash value to compare between other base elements to determine whether they share the same geometry. Archicad 22 seems to have deprecated this class and I no longer have access to it.

I much appreciate any advice and apologise if I utilise terms not native to Archicad.
User avatar
By Akos Somorjai
#288996
Hi,

AC 22 introduced the ModelerAPI::BaseElemId to solve that kind of issue. This can be used to compare instances of elements, it has operator== defined. It can also serve as a hashable key.

Call elem.GetBaseElemId() to access it.

Regards, Akos
By Arc
#289098
Thank you for the reply.

I tried to use it but I encountered a problem where I cannot seem to obtain the BaseElemId without at the same time requiring to extract a lot of other types of Ids as well.
Code: Select all
ModelerAPI::Element element;
ModelerAPI::BaseElemId baseId;
element.GetBaseElemId(&baseId);
Code: Select all
ModelerAPI::Element element;
ModelerAPI::BaseElemId baseId = element.GetBaseElemId();
Neither of the above seem to be able to just give me the BaseElemId. The first one requires me to also add a bunch of parameters that I don't know how to initialise and does not seem to accept nullpointers. The second one cannot work because it is a void function and thus does not return anything. Is there an example I can refer to as reference with regards to using this function?
User avatar
By Akos Somorjai
#289529
Arc wrote: Thu Nov 22, 2018 11:08 am Thank you for the reply.

Is there an example I can refer to as reference with regards to using this function?
Here it is:
Code: Select all
void ElementExporter::GetBaseElemId (const ModelerAPI::Element& element, ModelerAPI::BaseElemId* baseElemId)
{
	GS::NonInterruptibleProcessControl processControl;
	element.GetBaseElemId (baseElemId,
		processControl,
		ModelerAPI::Element::EdgeColorInBaseElemId::NotIncluded,
		ModelerAPI::Element::PolygonAndFaceTextureMappingInBaseElemId::NotIncluded,
		ModelerAPI::Element::BodyTextureMappingInBaseElemId::NotIncluded,
		ModelerAPI::Element::EliminationInfoInBaseElemId::NotIncluded);
}
Regards, Akos
By drjustice
#328543
Hi, I'm looking into a similar issue and would need clarification.

Let's say I have 2 chairs placed & orientated at different locations of the model. If I just extract the geometries of the Elements via their mesh bodies, each chair will have vertices at different spots (eg: the object's tranformation appears to be baked into the vertices I obtain).

Are you saying that if I use BaseElemId, I will be able to get the same hash for two objects that are placed at different locations, and that to extract the vertices in local coordinate of the bodies, I will need to multiply the vertices by the inverse of ModelerAPI::Element.GetElemLocalToWorldTransformation() for one of them?
By drjustice
#328658
Following up on my own thread: Yes, I confirm that to obtain the geometry in local coordinates, apply the inverse of the element's transform.
By drjustice
#328834
.. or, to get the geometry's local coordinates, the easier way is to specify the reference coordinate system.

Code: Select all
meshBody.GetVertex(vertexId, &positionW);

is the same as

Code: Select all
meshBody.GetVertex(vertexId, &positionW, ModelerAPI::CoordinateSystem::World);

but you can also use:

Code: Select all
meshBody.GetVertex(vertexId, &positionL, ModelerAPI::CoordinateSystem::ElemLocal);