Community
Fusion API and Scripts
Got a new add-in to share? Need something specialized to be scripted? Ask questions or share what you’ve discovered with the community.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Updating custom graphics fom an addin (sample code included)

0 REPLIES 0
Reply
Message 1 of 1
codereclaimers
391 Views, 0 Replies

Updating custom graphics fom an addin (sample code included)

Hi folks,

 

I ran into an issue when I tried creating and updating custom graphics (in particular, meshes) based on the settings from an addin's controls.  Updates would appear for a fraction of a second, but they disappeared and the initial mesh came back.

 

My problem was that I was trying to update the custom graphics objects inside the Command's inputChanged handler, when I should have been doing it from inside the executePreview handler.

 

Below is a sample C++ addin I've tried to boil down to the bare minimum to do this in a way that works (or appears to, anyway), in case anybody else finds it useful.  If you can spot any other dumb things I'm doing in it, please let me know.

 

Cheers,

Alan

 

#include <Core/CoreAll.h>
#include <Fusion/FusionAll.h>

using namespace adsk::core;
using namespace adsk::fusion;

std::string const testButtonID = "testButtonID";
std::string const dropdownCommandID = "dropdownCommandInput";

Ptr<Application> app;
Ptr<UserInterface> ui;

std::string const graphicsGroupName = "testCustomGraphicsID";

void DestroyCustomGraphics()
{
    if (app)
    {
        Ptr<Design> des = app->activeProduct();
        auto root = des->rootComponent();

        // Remove any custom graphics groups we've created.
        auto groups = root->customGraphicsGroups();
        for (size_t g = 0; g < groups->count(); ++g)
        {
            auto group = groups->item(g);
            if (graphicsGroupName == group->id())
            {
                group->deleteMe();
            }
        }

        // Update current view.
        auto viewport = app->activeViewport();
        if (viewport)
        {
            viewport->refresh();
        }
    }
}

void CreateCustomGraphics(std::vector<double> const& vertices, std::vector<int> const& indices)
{
    DestroyCustomGraphics();

    Ptr<Design> des = app->activeProduct();
    auto root = des->rootComponent();

    // Create a new graphics group on the root component.
    auto graphicsGroup = root->customGraphicsGroups()->add();

    // Set an ID on the group so we can find it later.
    graphicsGroup->id(graphicsGroupName);

    // Create the mesh in the new group.
    auto coords = CustomGraphicsCoordinates::create(vertices);
    auto mesh = graphicsGroup->addMesh(coords, indices, {}, {});

    // Refresh the active view.
    app->activeViewport()->refresh();
}

void UpdateCustomGraphics(Ptr<CommandInputs>& inputs)
{
    DestroyCustomGraphics();

    Ptr<DropDownCommandInput> distanceInput = inputs->itemById(dropdownCommandID);
    std::vector<int> indices = { 0, 1, 2 };
    std::vector<double> vertices;
    if (distanceInput->selectedItem()->name() == "XY plane")
    {
        vertices = { 0, 0, 0,
                     1, 0, 0,
                     0, 1, 0 };
    }
    else if (distanceInput->selectedItem()->name() == "YZ plane")
    {
        vertices = { 0, 0, 0,
                     0, 1, 0,
                     0, 0, 1 };
    }
    else if (distanceInput->selectedItem()->name() == "ZX plane")
    {
        vertices = { 0, 0, 0,
                     0, 0, 1,
                     1, 0, 0 };
    }
    CreateCustomGraphics(vertices, indices);
}

class CommandDestroyedHandler : public CommandEventHandler
{
public:
    void notify(const Ptr<CommandEventArgs>&) override
    {
        DestroyCustomGraphics();
    }
};

class CommandPreviewHandler : public CommandEventHandler
{
public:
    void notify(const Ptr<CommandEventArgs>& args) override
    {
        UpdateCustomGraphics(args->command()->commandInputs());
    }
};

class TestCommandCreatedHandler : public CommandCreatedEventHandler
{
public:
    void notify(const Ptr<CommandCreatedEventArgs>& eventArgs) override
    {
        auto command = eventArgs->command();
        command->destroy()->add(&onCommandDestroyed_);
        command->executePreview()->add(&onCommandPreview_);

        // Define the inputs.
        auto inputs = command->commandInputs();
        if (inputs)
        {
            auto dropDownCommandInput = inputs->addDropDownCommandInput(dropdownCommandID, "Triangle Plane", LabeledIconDropDownStyle);
            if (dropDownCommandInput)
            {
                auto dropdownItems = dropDownCommandInput->listItems();
                dropdownItems->add("XY plane", true);
                dropdownItems->add("YZ plane", false);
                dropdownItems->add("ZX plane", false);
            }

            // Create graphics based on defaults.
            UpdateCustomGraphics(inputs);
        }
    }
private:
    CommandDestroyedHandler onCommandDestroyed_;
    CommandPreviewHandler onCommandPreview_;
} onCommandCreatedOnPanel;

extern "C" XI_EXPORT bool run(const char* context)
{
    try
    {
        app = Application::get();
        ui = app->userInterface();

        DestroyCustomGraphics();

        // add a button command on Quick Access Toolbar
        auto toolbars = ui->toolbars();
        auto toolbarQAT = toolbars->itemById("QAT");
        auto toolbarControlsQAT = toolbarQAT->controls();
        auto btnCmdToolbarCtlQAT = toolbarControlsQAT->itemById(testButtonID);
        if (btnCmdToolbarCtlQAT)
        {
            btnCmdToolbarCtlQAT->deleteMe();
            btnCmdToolbarCtlQAT = nullptr;
        }

        if (!btnCmdToolbarCtlQAT)
        {
            auto commandDefinitions = ui->commandDefinitions();
            auto btnCmdDefinitionQAT = commandDefinitions->itemById(testButtonID);
            if (!btnCmdDefinitionQAT)
            {
                const std::string commandName = "Test Custom Graphics";
                const std::string commandDescription = "test custom graphics";
                const std::string commandResources = "./resources";

                btnCmdDefinitionQAT = commandDefinitions->addButtonDefinition(testButtonID, commandName, commandDescription, commandResources);
            }

            auto btnCmdCreatedEvent = btnCmdDefinitionQAT->commandCreated();
            btnCmdCreatedEvent->add(&onCommandCreatedOnPanel);
            btnCmdToolbarCtlQAT = toolbarControlsQAT->addCommand(btnCmdDefinitionQAT);
            btnCmdToolbarCtlQAT->isVisible(true);
        }

        return true;
    }
    catch (std::exception& e)
    {
        if (ui)
        {
            ui->messageBox("run() Failed:\n" + std::string(e.what()));
        }
        return false;
    }
}

extern "C" XI_EXPORT bool stop(const char* context)
{
    try
    {
        DestroyCustomGraphics();

        if (ui)
        {
            auto toolbars = ui->toolbars();
            auto toolbarQAT = toolbars->itemById("QAT");
            auto toolbarControlsQAT = toolbarQAT->controls();
            auto btnCmdToolbarCtlQAT = toolbarControlsQAT->itemById(testButtonID);
            if (btnCmdToolbarCtlQAT)
            {
                btnCmdToolbarCtlQAT->deleteMe();
            }

            auto commandDefinitions = ui->commandDefinitions();
            auto btnCmdDefinitionQAT = commandDefinitions->itemById(testButtonID);
            if (btnCmdDefinitionQAT)
            {
                btnCmdDefinitionQAT->deleteMe();
            }

            ui = nullptr;
            app = nullptr;
        }
    }
    catch (std::exception& e)
    {
        if (ui)
        {
            ui->messageBox("stop() Failed:\n" + std::string(e.what()));
        }
    }

    return true;
}


#ifdef XI_WIN

#include <windows.h>

BOOL APIENTRY DllMain(HMODULE hmodule, DWORD reason, LPVOID reserved)
{
    switch (reason)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

#endif // XI_WIN
0 REPLIES 0

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Technology Administrators


Autodesk Design & Make Report