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

Fit drawing to Layout(How to change the "bound" in API_DrawingType)

Nayan
Booster
When we place a drawing onto a layout, sometimes the drawing is bigger than the layout so it overlaps.
What I am trying to achieve is to resize the drawing to fit into the layout?

To achieve this I am trying to chage the ratio ("API_DrawingType.drawing.ratio") but it's not working as expected because can not update the value of the bound("API_DrawingType.bound").

GS::Array<API_Guid>  drawingList;
			err = ACAPI_Element_GetElemList(API_DrawingID, &drawingList);
API_Element mask;
				ACAPI_ELEMENT_MASK_CLEAR(mask);
				ACAPI_ELEMENT_MASK_SET(mask, API_DrawingType, nameType);
				ACAPI_ELEMENT_MASK_SET(mask, API_DrawingType, numberingType);
				ACAPI_ELEMENT_MASK_SET(mask, API_DrawingType, name);
				ACAPI_ELEMENT_MASK_SET(mask, API_DrawingType, customNumber);
				ACAPI_ELEMENT_MASK_SET(mask, API_DrawingType, bounds);
				ACAPI_ELEMENT_MASK_SET(mask, API_DrawingType, ratio);

API_Element element = {};
					element.header.guid = drawingGuid;
					err = ACAPI_Element_Get(&element);
					if (err == NoError) {
						element.drawing.nameType = APIName_CustomName;
						element.drawing.numberingType = APINumbering_CustomNum;
						CHCopyC("Test", element.drawing.name);
						CHCopyC("Test", element.drawing.customNumber);
                                                //-----------------------------------------------------------------------------
                                               //Right now doing it manually
                                              //layout size = 392 and drawingSize = 680
                                              //ratio = layout size / drawing size
                                             //          = 392 / 680 = .57647
                                             //---------------------------------------------------------------------------------
						element.drawing.ratio = .57647;
						element.drawing.bounds.xMin = 0.1010;
						element.drawing.bounds.xMax = 0.4929;
						element.drawing.bounds.yMin = 0.0140;
						element.drawing.bounds.yMax = 0.4059;
						err = ACAPI_Element_Change(&element, &mask, nullptr, 0, true);
Can anyone kindly help me to figure out what's doing wrong and how can I update the bound values here?
Or is there any other approach to fit the drawing to the layout?
Thanks in Advance.
1 ACCEPTED SOLUTION

Accepted Solutions
Solution
You might also need to adjust the frame polygon in the ElementMemo and cut the drawing with it. The following lines should give you an idea of what to add / change to do this:

	ACAPI_ELEMENT_MASK_SET(mask, API_DrawingType, isCutWithFrame);

        //....
	element.drawing.isCutWithFrame = true;

        //....
	if (element.drawing.poly.nCoords != 5
		|| element.drawing.poly.nSubPolys != 1
		|| element.drawing.poly.nArcs != 0) {
		DBPrintf("Can only do rectangular polygons for now!");
		return;
	}

	API_ElementMemo memo;
	err = ACAPI_Element_GetMemo  (element.header.guid, &memo);
	if (err != NoError) {
		DBPrintf ("Couldn't get Element Memo!");
		ACAPI_DisposeElemMemoHdls(&memo);
		return;
	}

	if (memo.coords != nullptr && memo.pends != nullptr) {
		(*memo.coords)[1].x = element.drawing.bounds.xMin;
		(*memo.coords)[1].y = element.drawing.bounds.yMin;
		(*memo.coords)[2].x = element.drawing.bounds.xMax;
		(*memo.coords)[2].y = element.drawing.bounds.yMin;
		(*memo.coords)[3].x = element.drawing.bounds.xMax;
		(*memo.coords)[3].y = element.drawing.bounds.yMax;
		(*memo.coords)[4].x = element.drawing.bounds.xMin;
		(*memo.coords)[4].y = element.drawing.bounds.yMax;
		(*memo.coords)[5].x = (*memo.coords)[1].x;
		(*memo.coords)[5].y = (*memo.coords)[1].y;
	}

        // Adapt your Element_Change line to this
	err = ACAPI_Element_Change (&element, &mask, &memo, APIMemoMask_All, true);
	ACAPI_DisposeElemMemoHdls(&memo);
Bernd Schwarzenbacher - Archicad Add-On Developer - Get Add-Ons & Archicad Tips on my Website: bschwb.com

View solution in original post

3 REPLIES 3
Solution
You might also need to adjust the frame polygon in the ElementMemo and cut the drawing with it. The following lines should give you an idea of what to add / change to do this:

	ACAPI_ELEMENT_MASK_SET(mask, API_DrawingType, isCutWithFrame);

        //....
	element.drawing.isCutWithFrame = true;

        //....
	if (element.drawing.poly.nCoords != 5
		|| element.drawing.poly.nSubPolys != 1
		|| element.drawing.poly.nArcs != 0) {
		DBPrintf("Can only do rectangular polygons for now!");
		return;
	}

	API_ElementMemo memo;
	err = ACAPI_Element_GetMemo  (element.header.guid, &memo);
	if (err != NoError) {
		DBPrintf ("Couldn't get Element Memo!");
		ACAPI_DisposeElemMemoHdls(&memo);
		return;
	}

	if (memo.coords != nullptr && memo.pends != nullptr) {
		(*memo.coords)[1].x = element.drawing.bounds.xMin;
		(*memo.coords)[1].y = element.drawing.bounds.yMin;
		(*memo.coords)[2].x = element.drawing.bounds.xMax;
		(*memo.coords)[2].y = element.drawing.bounds.yMin;
		(*memo.coords)[3].x = element.drawing.bounds.xMax;
		(*memo.coords)[3].y = element.drawing.bounds.yMax;
		(*memo.coords)[4].x = element.drawing.bounds.xMin;
		(*memo.coords)[4].y = element.drawing.bounds.yMax;
		(*memo.coords)[5].x = (*memo.coords)[1].x;
		(*memo.coords)[5].y = (*memo.coords)[1].y;
	}

        // Adapt your Element_Change line to this
	err = ACAPI_Element_Change (&element, &mask, &memo, APIMemoMask_All, true);
	ACAPI_DisposeElemMemoHdls(&memo);
Bernd Schwarzenbacher - Archicad Add-On Developer - Get Add-Ons & Archicad Tips on my Website: bschwb.com
Nayan
Booster
Thanks @bschwb for the reply.
If I want to clip/cut the drawing. Let I want to crop / split the drawing to half. In that case should I work with only the memo.coords value?
You should also make sure that element.poly is consistent with the memo.coords values. See https://archicadapi.graphisoft.com/documentation/api_polygon for more details.

I'm unsure what should happen to the element.bounds value if you are clipping the drawing. If I were you I would try two options: 1. keep the element.bounds to the size of the unclipped drawing or 2. also adapt the element.bounds value to the clipped drawing. And then use whichever gives the correct / better results.
Bernd Schwarzenbacher - Archicad Add-On Developer - Get Add-Ons & Archicad Tips on my Website: bschwb.com