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.

Create a custom paint tool

mats1
Contributor

Hi all, i would like to create a tool where users can select attributes (materials) and paint them onto elements of their choosing. The problem i am having right now is that when using

 

 

 

ACAPI_Notification_CatchSelectionChange

 

 

 

 

 

 

 

static GSErrCode SelectionChangeHandler(const API_Neig* selElemNeig) {

    // Pseudo code
    if (selElemNeig->neigID != APINeig_None) {
        auto err = ACAPI_CallUndoableCommand("Change element", []() {
            return ACAPI_Element_Change(...);
        });
        // err is Unkown Error when printed
        // after this the SelectionChangeHandler is being called repeatedly indefinitely
    }
    else
        ACAPI_WriteReport("All elements deselected", false);

    return NoError;
}   // SelectionChangeHandler

 

 

 

 I am unable to update the element inside of the callback, im guessing based of the docs its not allowed to do DB operations on a seperate thread.

I also tried using 

 

 

 

        API_Neig clickedNeig;

        ClickAnElem("Click an elem to select/deselect", API_ZombieElemID, &clickedNeig);

        auto err = ACAPI_CallUndoableCommand("Change element", []() {
            return ACAPI_Element_Change(...);
            });

 

 

 

Which works but i want to be able to select many things and paint accordingly. having this solution in a while loop ofcourse blocks the UI so the user cannot interact with other panels visible until ESC key is pressed. I have buttons in my to stop painting or changing colors.


9 REPLIES 9
Barry Kelly
Moderator

Does this have to be an API solution?

Can you just use the surface painter tool that is already there in Archicad?

 

Barry.

One of the forum moderators.
Versions 6.5 to 27
i7-10700 @ 2.9Ghz, 32GB ram, GeForce RTX 2060 (6GB), Windows 10
Lenovo Thinkpad - i7-1270P 2.20 GHz, 32GB RAM, Nvidia T550, Windows 11
mats1
Contributor

Hi, unfortunately this is not possible since i want to both create the colors and paint them in the same palette. I understand the surface painter is exactly for picking colors and painting elements but i would like to create my own, and it seems to be impossible with the available APIs.

 

Mats.

mats1
Contributor

This is now resolved. The trick was when we changed the element the user had selected this function was called again and became an infinite repeating loop. Checking if the same element was updated twice solved it.

static GSErrCode SelectionChangeHandler(const API_Neig* selElemNeig) {

    // Pseudo code
    if (selElemNeig->neigID != APINeig_None) {
        auto err = ACAPI_CallUndoableCommand("Change element", []() {
            return ACAPI_Element_Change(...);
        });
        // err is Unkown Error when printed
        // after this the SelectionChangeHandler is being called repeatedly indefinitely
    }
    else
        ACAPI_WriteReport("All elements deselected", false);

    return NoError;
}   // SelectionChangeHandler

 

mats1
Contributor

Hi,

I am currently working on a project in ArchiCAD 28, and I am trying to create a functionality similar to the Surface Painter tool. The goal is to apply colors or materials to objects by clicking on them, but only applying the color to the specific parts I click on—just like how Surface Painter works.

Here’s what I want to achieve:

  • I have a set of colors (or materials) available.
  • I need to click on a 3D object (or surface) in the ArchiCAD environment.
  • Once clicked, the selected color should be applied only to the clicked area (similar to the Surface Painter behavior).

I’ve been exploring the ArchiCAD API, but I’m unsure of the best approach to get this specific behavior. Can anyone provide insights into how I can capture mouse clicks on objects or surfaces and apply materials to the specific part clicked?

Any help, code snippets, or guidance would be greatly appreciated!

Thanks in advance!

Personly, i'm a soft user, i use directly a gdl object with associated texture for painting wall if there are differrent painting on the wall like different color in bottom part and top part,or atistitic painting on dwelling building.

Please excuse my english.I have base, but i don't practice usually in office.

 

Hi,
im not sure i understand how a gdl object works. Are you painting based on selection or are you creating your own objects with respective paintings. I.e are you detecting user clicks and painting accordingly?

i define a surface by gdl standard vertex associate to surface, with a maximum of point.for the moment i use only for planar surface.You just have to put dhe object on the plane with a normal vector to the surface with a very small distance in order to have no confusion of surface between the structural surface(metal,concrete,wood panel).

with the primitive elements include body command.

(vert teve vect edge,pgon body base and material....)

you have 1024 parameters in a basic object, to help you.

actually i think the problem is about how to improve the gdl interface,like import and create parameters via excel like  a "list of elements"..

and test each view inside.

Am i understanding this correctly. For you to paint an object you create a new surface very close along the normal vector of the original surface? 

I was thinking of modifying the existing one, do you know how would this be possible using the c++ apis? 

VChristophe
Participant

Just use the form tool above the wall, and manage your draft by note the color RGB,define by color or photoshop.

more simple.and have a special ID for painting ,and the price to associate with.

Aikido, omote and oura.

and for more complicated form you use verpex and mapping like painting under a dome in Toscane, if its original painting or mapping the texture to go fast.

its a fast example in the pictures under .Mapping its the fast way when picture already exist.

Capture d’écran 2024-11-21 102241.jpgCapture d’écran 2024-11-21 102516.jpg