Developer forum
Showing results for 
Search instead for 
Did you mean: 

Auto-generation add-on for column CAD compatibility

Not applicable
I'm still an API beginner. I've been dealing with C ++ 10 years ago.
Area(or Zone) and text were created by inserting the precast columns and column name layers drawn in CAD drawings using merge to worksheet function.
I want to create an add-on that uses this and calculates the outline size of the area to create a column object and select the column Text nearest to each area as this object and input it as the id of the column object. Would it be easy to develop based on an example

Ralph Wessel
Probably the most relevant example project is "Element_Test". This shows you have to create a new column, and how to find or edit existing elements.
Ralph Wessel BArch

Not applicable

I had a similar idea once. When its ready are you going to publish this Addin?

Not applicable
We are reviewing the sample files. However, many results are written in a report window using a function called "WriterReport". Even if you run the add-on as a demo version and check the File / Information / Report menu,
How can I see the result?
For example, if you run Do_ListSelection (void) in the Selection example file, you do not know the result.

Ralph Wessel
Debug into the add-on and set breakpoints wherever you want to inspect variable contents.
Ralph Wessel BArch

Not applicable
To install Debugging tools, download Graphisoft Visual Studio debug visualizers as directed by the Tools for debugging site, copy GS.natvis, IO.natvis 2 files to the / Documents / Visual Studio 2015 / Visualizers folder and restart Visual Studio . And I loaded the apx example files that I built in the Archicad 21 add-on manager.
In Visual Studio, I set up breakpoints with F9 and started debugging by pressing F5
The following error occurs. What is the problem?

Not applicable
In Debugging in the Project Properties setting window, you specified the path of Archicad.exe to Command item, and Debug was able to execute. Thank you.

Not applicable
Here is the big execution flow for the addons I'm going to develop.

Using Archicad's Merge function, select the Column_layer and Column_Name_Layer layers in DWG to generate Polyline and Text.

1, Find a polyline quadrilateral element list with a specific layer.
2 Calculate the horizontal and vertical dimensions of the column by calculating the distance of the vertex of the polyline.
3, Get a list of Text with a specific layer, and get the base point and Text value.
4. Find the minimum distance between the diagonal intersection of the polyline and the text reference point.
5. Enter Text as the ID of the column element and enter the horizontal and vertical dimensions.
6. Create a column element.

What functions should be used when developing an execution function in this order?

What else is there?
In particular, how do you find the distance of the four vertices of Polyline?

Ralph Wessel
You will probably want to use ACAPI_Element_GetElemList to find the 2d elements to construct the columns from.

I recommend also checking what 2D elements are created when the DWG is merged. Columns might be defined as any of the following:

- Four separate lines
- One to four polylines
- A combination of lines and polylines
- A fill (closed polygon)
- A library part (from an AutoCAD block), which might include the text label

The techniques for finding the elements and extracting relevant geometry will vary according to the element type. It's also possible there may be duplicates, e.g. a fill overlapping 4 bounding lines.
Ralph Wessel BArch

Not applicable
I am considering how to create an Element.
If column_outLine_layer calculates the column dimension value (500mm * 500mm) with 2D polyline
           If column_name_layer is 2D text and the column element id (13-101-0100) is input

For API_ColumnType
coreDepth = vertical dimension
coreWidth = horizontal dimension
height = column height
origoPos.x =x coordinate of origin point
origoPos.y = y coordinate of origin point

To create an API_Element element
I created the API_ElementMemo element at the same time

We need to create a column element

Column Element id value (13-101-0100) Could not find the value of the variable in the structure where you can enter the character variable.
Can I enter the value of a column variable corresponding to the picture below in a variable value?

Ralph Wessel
The ID is set in API_ElementMemo.elemInfoString
Ralph Wessel BArch

Not applicable
ACAPI_Element_Create (& columnElem, & columnMemo); An error has occurred during debugging.
What's wrong?
GSErrCode err;
GS::Array<API_Guid> polylineList, textList;

err = ACAPI_Element_GetElemList(API_PolyLineID, &polylineList);
WriteReport("Number of total polyline: %u", (GS::UIntForStdio) polylineList.GetSize());
err = ACAPI_Element_GetElemList(API_TextID, &textList);
WriteReport("Number of total Text: %u", (GS::UIntForStdio) textList.GetSize());

Int32 i,j;
API_Element polyElem, textElem, columnElem;
API_ElementMemo polyMemo, textMemo, columnMemo;
API_Coord cenCoord;
API_Guid guid;
char text[20];
double a, b,x,y,minDist,Dist;
for (i = 0 ; i < 1; i++) //polylineList.GetSize(); i++)
BNZeroMemory(&polyElem, sizeof(API_Element));
BNZeroMemory(&polyMemo, sizeof(API_ElementMemo));
polyElem.header.guid = polylineList;
err = ACAPI_Element_Get(&polyElem);
err = ACAPI_Element_GetMemo(polyElem.header.guid, &polyMemo);
b = DistCPtr(&(*polyMemo.coords)[1], &(*polyMemo.coords)[2]);
a = DistCPtr(&(*polyMemo.coords)[2], &(*polyMemo.coords)[3]);
cenCoord.x = ((*polyMemo.coords)[1].x + (*polyMemo.coords)[2].x + (*polyMemo.coords)[3].x + (*polyMemo.coords)[4].x) / 4;
cenCoord.y = ((*polyMemo.coords)[1].y + (*polyMemo.coords)[2].y + (*polyMemo.coords)[3].y + (*polyMemo.coords)[4].y) / 4;
minDist = 100000000000000;
for (j=0 ; j<textList.GetSize(); j++)
BNZeroMemory(&textElem, sizeof(API_Element));
BNZeroMemory(&textMemo, sizeof(API_ElementMemo));
textElem.header.guid = textList;
err = ACAPI_Element_Get(&textElem);
err = ACAPI_Element_GetMemo(textElem.header.guid, &textMemo);
Dist = DistCPtr(&textElem.text.loc, &cenCoord);

if (Dist < minDist)
minDist = Dist;
strcpy(text, *textMemo.textContent);
guid = textElem.header.guid;

BNZeroMemory(&columnElem, sizeof(API_Element));
BNZeroMemory(&columnMemo, sizeof(API_ElementMemo));

columnElem.header.typeID = API_ColumnID;

GSErrCode err = ACAPI_Element_GetDefaults(&columnElem, nullptr);
columnElem.column.coreWidth = a;
columnElem.column.coreDepth = b;
columnElem.column.origoPos = cenCoord;
columnMemo.coords = (API_Coord**)BMhAllClear((5) * sizeof(API_Coord));
columnMemo.elemInfoString = new GS::UniString(text);
GS::UniString *elemInfoString= columnMemo.elemInfoString;

(*columnMemo.coords)[1].x = (*polyMemo.coords)[1].x;
(*columnMemo.coords)[1].y = (*polyMemo.coords)[1].y;
(*columnMemo.coords)[2].x = (*polyMemo.coords)[2].x;
(*columnMemo.coords)[2].y = (*polyMemo.coords)[2].y;
(*columnMemo.coords)[3].x = (*polyMemo.coords)[3].x;
(*columnMemo.coords)[3].y = (*polyMemo.coords)[3].y;
(*columnMemo.coords)[4].x = (*polyMemo.coords)[4].x;
(*columnMemo.coords)[4].y = (*polyMemo.coords)[4].y;
(*columnMemo.coords)[5].x = (*polyMemo.coords)[5].x;
(*columnMemo.coords)[5].y = (*polyMemo.coords)[5].y;

err = ACAPI_Element_Create(&columnElem, &columnMemo); // nullptr);// ==> Error

Ralph Wessel
Take a look at the documentation for ACAPI_Element_GetMemo. It lists the memos that are relevant to every element type. For API_ColumnID, this includes gables, customOrigProfile and stretchedProfile, but not coords.

You should be able to make this work by setting columnElem.column.coreWidth and columnElem.column.coreDepth. You don't need to set a bounding polygon for a simple rectangle or circle.

Edit: Be careful with your array bounds - I notice you allocate memory for 5 coordinates, but then reference (*polyMemo.coords)[5]. Remember that C/C++ arrays are zero-based, so you can safely reference [0]…[size - 1]
Ralph Wessel BArch

Not applicable
Thanks Ralph Wessel !

Success Ha Ha Ha

Not applicable
What parts do I need to modify to make this add-on an API with a name other than Element_Test? What if I change the project name as well?

Ralph Wessel
I can't remember all the details off the top of my head, but I think it's primarily named from the project settings Linker > General > Output File

This is generally easier to do by simply editing the files with a text editor, e.g. Find/Replace the expression "Element_Test". You can also rename the project/solution files.
Ralph Wessel BArch

Not applicable
I'm developing a routine to automatically generate beams using CAD data.
The basic development direction is
1) Call up the line list representing the contour of the beam
2) Find a line that is parallel and spaced by a certain width and calculates the width of the beam.
3) After drawing the centerline of the same length
4) Create a rectangular beam with the same information.
So far development has been completed with the test data.
In order to enter the height of the beam,
You want to modify the value of the beam member with the same ID by inputting the beam name and the dimension together, and entering the horizontal and vertical dimensions of the member corresponding to the name, respectively. I have the following questions.
1) How to find a list of elements with a specific layer name (ex: "exp1")?
    How do I find a text element with a layer name "t1"?
2) What is the function formula that calculates the points that meet on the extension line in the algorithm that finds the intersection point of two straight lines in 2D plane?
3) How can I retrieve a list of elements with a specific ID and change the attribute information?

Ralph Wessel
park wrote:
I have the following questions.
1) How to find a list of elements with a specific layer name (ex: "exp1")?
    How do I find a text element with a layer name "t1"?
Elements store the index of the layer they are on (not the name), so you need to look up the layer first to retrieve its index. Don't hardcode the index because it can change. Then you will need to iterate through the elements to search for the required layer index. If you're searching for a specific element type, e.g. text, you can use ACAPI_Element_GetElemList to filter for that type.
park wrote:
2) What is the function formula that calculates the points that meet on the extension line in the algorithm that finds the intersection point of two straight lines in 2D plane?
I wrote my own methods for this before the ARCHICAD API existed, so I don't know what it has to offer in this respect.
park wrote:
3) How can I retrieve a list of elements with a specific ID and change the attribute information?
You will have to iterate through all the elements to find those with a specific ID – I'm not aware of a shortcut. If you change any attribute, an element can be written back to the database with ACAPI_Element_Change.
Ralph Wessel BArch

Not applicable
ACAPI_ELEMENT_MASK_SET(mask, API_BeamType, height );

element.beam.height = beamList.height;

err = ACAPI_Element_Change(&element, &mask, &memo, 0, true);
err = ACAPI_Element_Get(&element);
err = ACAPI_Element_GetMemo(element.header.guid, &memo);

Firstly, the beam member generated from the plan view is read by the list data
We want to change the height of the beam member.
I programmed the above to change the height of the beam member

The height of the beam member is not changed.

Not applicable
When I checked the error, I noticed a NotEditeable error and turned on the layer. But how do you edit attribute information with editability?

Still looking?

Browse more topics

Back to forum

See latest solutions

Accepted solutions

Start a new discussion!