BIM Coordinator Program (INT) April 22, 2024

Find the next step in your career as a Graphisoft Certified BIM Coordinator!

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

How to get the door vector

minami
Participant

I want to get the "vector" of the selected door.
I tried to get it from dirVector of API_DoorType, but it didn't work.
How can I get a vector successfully?
Also, please let me know if there is another way to get the vector of the door.

void test() {
	//選択された要素の取得
	API_SelectionInfo selectionInfo;
	GS::Array<API_Neig> selNeigs;
	GSErrCode err = ACAPI_Selection_Get(&selectionInfo, &selNeigs, true);
	BMKillHandle((GSHandle*)&selectionInfo.marquee.coords);
	if (err == APIERR_NOSEL || selectionInfo.typeID == API_SelEmpty) {
		WriteReport_Alert("No selected elements");
		return;
	}
	GS::Array<API_Neig> selectElemGuids;
	API_Element sectElement;
	for (int i = 0; i < selNeigs.GetSize(); ++i) {
		//要素のIDを取得
		API_Guid selectElemGuid = selNeigs[i].guid;
		API_Element testElem;
		testElem.header.guid = selectElemGuid;

		ACAPI_Element_Get(&testElem);
		GS::UniString test = u8"実行確認用";
	}
}

code.pngarchicad25.png
1 ACCEPTED SOLUTION

Accepted Solutions
Solution

Hi minami,

 

I think startPoint also only works for polygonal walls. For other walls you have to use objLoc. It measures the distance along the reference line from the beginning point of the wall to the center point of the door.

For straight walls first normalize the wall vector to a unit vector and then multiply by objLoc should work if I remember it correctly. Something like:

wallVec = wall.endC - wall.begC
doorPos = wall.begC + objPos * wallVec / wallVec.GetLength()
Bernd Schwarzenbacher - Archicad Add-On Developer - Get Add-Ons & Archicad Tips on my Website: Archi-XT.com

View solution in original post

4 REPLIES 4

Hi minami,

According to the documentation (https://archicadapi.Graphisoft.com/documentation/api_windowtype-api_doortype?s=doortype) the "dirVector" field is only relevant for doors in polygonal walls. So in case of your straight wall it's not useful.


I ran into this problem a while ago, but can't remember all the details. Roughly what I did is to calculate the vector from the parent wall beginning and end point. wall.endC - wall.begC and rotate 90deg. The parent wall GUID should be in the "owner" field of the door.
For curved walls you could rotate the radius vector to the center of the door (door.objLoc).


All of this is even trickier if you also want to have the vector point in the correct opening side for all possible door flip settings. You need to check door.openingBase.refSide/oSide.

I hope this helps a bit.

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

Hi Bernd,

 

Thank you for the quick reply.
I will try the advice quickly !

It is different from vector, but could you tell me about the following?
I want to get the startPoint of the door, but it's not working as well as the dirVector.
How can I get the door position correctly?
Also, please tell me if there is another way to get the position of the door.

 

thank you.

Solution

Hi minami,

 

I think startPoint also only works for polygonal walls. For other walls you have to use objLoc. It measures the distance along the reference line from the beginning point of the wall to the center point of the door.

For straight walls first normalize the wall vector to a unit vector and then multiply by objLoc should work if I remember it correctly. Something like:

wallVec = wall.endC - wall.begC
doorPos = wall.begC + objPos * wallVec / wallVec.GetLength()
Bernd Schwarzenbacher - Archicad Add-On Developer - Get Add-Ons & Archicad Tips on my Website: Archi-XT.com

Hi Bernd,

thank you for your answer.
Thanks to that I was able to get the vector and center point of the door.
Upload the created code.

Thank you.

void test() {
	//選択された要素の取得
	API_SelectionInfo selectionInfo;
	GS::Array<API_Neig> selNeigs;
	GSErrCode err = ACAPI_Selection_Get(&selectionInfo, &selNeigs, true);
	BMKillHandle((GSHandle*)&selectionInfo.marquee.coords);
	if (err == APIERR_NOSEL || selectionInfo.typeID == API_SelEmpty) {
		WriteReport_Alert("No selected elements");
		return;
	}
	GS::Array<API_Neig> selectElemGuids;
	API_Element sectElement;
	for (int i = 0; i < selNeigs.GetSize(); ++i) {
		//要素のIDを取得
		API_Guid selectElemGuid = selNeigs[i].guid;
		API_Element doorElem;
		doorElem.header.guid = selectElemGuid;
		ACAPI_Element_Get(&doorElem);

		API_Element wallElem;
		wallElem.header.guid = doorElem.door.owner;
		ACAPI_Element_Get(&wallElem);
		API_Coord end = wallElem.wall.endC;
		API_Coord beg = wallElem.wall.begC;

		API_Vector wallVec = {end.x - beg.x, end.y - beg.y };
		double sizeVec = sqrt(pow(wallVec.x, 2) + pow(wallVec.y, 2));
		API_Coord wallUnitVec = { wallVec.x / sizeVec, wallVec.y / sizeVec };
		API_Coord moveVec = {wallVec.x * doorElem.door.objLoc /sizeVec, wallVec.y * doorElem.door.objLoc / sizeVec };
		API_Coord doorPos = {wallElem.wall.begC.x + moveVec.x, wallElem.wall.begC.y + moveVec.y };
		API_Coord normVec = {sqrt(pow(wallUnitVec.y, 2) / (pow(wallUnitVec.x, 2) + pow(wallUnitVec.y, 2))), sqrt(pow(wallUnitVec.x, 2) / (pow(wallUnitVec.x, 2) + pow(wallUnitVec.y, 2)))};
		GS::UniString test = u8"実行確認用";
	}
}
Learn and get certified!