We value your input!
Please participate in Archicad 28 Home Screen and Tooltips/Quick Tutorials survey

Archicad C++ API
About Archicad add-on development using the C++ API.
SOLVED!

Functions to help find overlapping objects

Anonymous
Not applicable
Hello guys,

I have to find out if two object elements are overlapping. Are there any functions that can return something that would help me - for example object boundary position or whatever else?

The only one that I found helpful so far is ACAPI_Element_GetHotspots and if there is no easier way I am going to get the boundary hotspots of the objects and think of some algorithm to calculate the objects positions and if they are overlapping. The objects are made and imported by myself so I can put hotspots wherever I want (I think).
1 ACCEPTED SOLUTION

Accepted Solutions
Solution
Tibor Lorantfy
Graphisoft Alumni
Graphisoft Alumni
Hi,

You can use ACAPI_Element_GetCollisions to detect collisions between elements (this function is available from API 21).
Here is an example from the Element_Test example Add-On, it detects the collisions between the selected elements:
void	Do_DetectCollisionsBasedOnSelection (void)
{
	API_SelectionInfo 	selectionInfo;
	API_Neig**			selNeig;
	GSErrCode			err;

	// Get selection
	err = ACAPI_Selection_Get (&selectionInfo, &selNeig, true);
	BMKillHandle ((GSHandle *) &selectionInfo.marquee.coords);

	if (err != NoError && err != APIERR_NOSEL) {
		BMKillHandle ((GSHandle *) &selNeig);
		ErrorBeep ("ACAPI_Selection_GetInfo", err);
		return;
	}

	if (err == APIERR_NOSEL || selectionInfo.typeID == API_SelEmpty) {
		WriteReport_Alert ("No selected elements");
		return;
	}

	GS::Array<API_Guid> guidList1, guidList2;
	GS::Array<GS::Pair<API_CollisionElem, API_CollisionElem>> collisions;

	for (Int32 i = 0; i < selectionInfo.sel_nElemEdit; i++) {
		guidList1.Push ((*selNeig).guid);
		guidList2.Push ((*selNeig).guid);
	}
	BMKillHandle ((GSHandle *) &selNeig);

	// Detect collisions
	API_CollisionDetectionSettings colDetSettings;
	colDetSettings.volumeTolerance = 0.0001;
	colDetSettings.performSurfaceCheck = true;
	colDetSettings.surfaceTolerance = 0.0001;
	err = ACAPI_Element_GetCollisions (guidList1, guidList2, collisions, colDetSettings);
	Do_DumpCollisions (collisions);
}
Regards,
Tibor

View solution in original post

6 REPLIES 6
dfintha
Graphisoft Alumni
Graphisoft Alumni
Hello,

You can use the APIDb_CalcBoundsID functionality of ACAPI_Database to get a bounding box of the 3D extent of your object.

Best regards,
Dénes
Solution
Tibor Lorantfy
Graphisoft Alumni
Graphisoft Alumni
Hi,

You can use ACAPI_Element_GetCollisions to detect collisions between elements (this function is available from API 21).
Here is an example from the Element_Test example Add-On, it detects the collisions between the selected elements:
void	Do_DetectCollisionsBasedOnSelection (void)
{
	API_SelectionInfo 	selectionInfo;
	API_Neig**			selNeig;
	GSErrCode			err;

	// Get selection
	err = ACAPI_Selection_Get (&selectionInfo, &selNeig, true);
	BMKillHandle ((GSHandle *) &selectionInfo.marquee.coords);

	if (err != NoError && err != APIERR_NOSEL) {
		BMKillHandle ((GSHandle *) &selNeig);
		ErrorBeep ("ACAPI_Selection_GetInfo", err);
		return;
	}

	if (err == APIERR_NOSEL || selectionInfo.typeID == API_SelEmpty) {
		WriteReport_Alert ("No selected elements");
		return;
	}

	GS::Array<API_Guid> guidList1, guidList2;
	GS::Array<GS::Pair<API_CollisionElem, API_CollisionElem>> collisions;

	for (Int32 i = 0; i < selectionInfo.sel_nElemEdit; i++) {
		guidList1.Push ((*selNeig).guid);
		guidList2.Push ((*selNeig).guid);
	}
	BMKillHandle ((GSHandle *) &selNeig);

	// Detect collisions
	API_CollisionDetectionSettings colDetSettings;
	colDetSettings.volumeTolerance = 0.0001;
	colDetSettings.performSurfaceCheck = true;
	colDetSettings.surfaceTolerance = 0.0001;
	err = ACAPI_Element_GetCollisions (guidList1, guidList2, collisions, colDetSettings);
	Do_DumpCollisions (collisions);
}
Regards,
Tibor
Anonymous
Not applicable
Wonderful! Thank you both! I think I will combine both your methods!
Anonymous
Not applicable
Wow!
ACAPI_Element_GetCollisions needs 1 to 3 minutes to return - 3 elements with 3 collisions.
My CPU is 100%, MacBook Pro 2017!
Is it possible?
Tibor Lorantfy
Graphisoft Alumni
Graphisoft Alumni
n.mihaylov wrote:
ACAPI_Element_GetCollisions needs 1 to 3 minutes to return - 3 elements with 3 collisions.
How many elements do you input to ACAPI_Element_GetCollisions function? All elements from your project?
Anonymous
Not applicable
I check every time and I have only 3 elements in guidList1 and guidList2:

ACAPI_Element_GetCollisions (guidList1, guidList2, collisions, colDetSettings);