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: 

Add plugin button and menu item in Fusion 360 with C++

1 REPLY 1
Reply
Message 1 of 2
khoa.ho
1028 Views, 1 Reply

Add plugin button and menu item in Fusion 360 with C++

Hello everyone. I am trying to create a button in quick access toolbar and menu item in Fusion 360 with C++. Here is the code:

 

#pragma unmanaged

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

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

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

// CommandCreated event handler.
class CommandCreatedEventHandler : public adsk::core::CommandCreatedEventHandler
{
public:
    void notify(const Ptr<CommandCreatedEventArgs>& eventArgs) override
    {
        if (eventArgs)
        {
        }
    }
private:
} onCommandCreated;

extern "C" XI_EXPORT bool run(const char* context)
{
    app = Application::get();
    if (!app)
        return false;

    ui = app->userInterface();
    if (!ui)
        return false;

    const std::string commandId = "MyCommand";
    const std::string commandName = "My Command Name";
    const std::string commandDescription = "My Command Name";
    const std::string workspaceToUse = "FusionSolidEnvironment";
    const std::string panelToUse = "SolidMakePanel";

    Ptr<CommandDefinitions> commandDefinitions = ui->commandDefinitions();
    if (!commandDefinitions)
        return false;

    // Be fault tolerant in case the command is already added.
    Ptr<CommandDefinition> commandDefinition = commandDefinitions->itemById(commandId);
    if (!commandDefinition)
    {
        std::string resourcePath = ""; // "./resources";
        commandDefinition = commandDefinitions->addButtonDefinition(
            commandId,
            commandName,
            commandDescription,
            resourcePath);// absolute resource file path is specified
    }

    if (!commandDefinition)
        return false;

    Ptr<CommandCreatedEvent> commandCreatedEvent = commandDefinition->commandCreated();
    if (!commandCreatedEvent)
        return false;
    commandCreatedEvent->add(&onCommandCreated);
    //commandDefinition->execute();

    // Add a command button on Quick Access Toolbar
    Ptr<Toolbars> toolbars = ui->toolbars();
    Ptr<Toolbar> toolbarQAT = toolbars->itemById("QAT");
    Ptr<ToolbarControls> toolbarControlsQAT = toolbarQAT->controls();
    Ptr<ToolbarControl> toolbarControlQAT = toolbarControlsQAT->itemById(commandId);
    if (!toolbarControlQAT)
    {
        toolbarControlQAT = toolbarControlsQAT->addCommand(commandDefinition, commandId);
        toolbarControlQAT->isVisible(true);
    }

    // Add a command on create panel in modeling workspace
    Ptr<Workspaces> workspaces = ui->workspaces();
    Ptr<Workspace> modelingWorkspace = workspaces->itemById(workspaceToUse);
    Ptr<ToolbarPanels> toolbarPanels = modelingWorkspace->toolbarPanels();
    Ptr<ToolbarPanel> toolbarPanel = toolbarPanels->itemById(panelToUse);
    Ptr<ToolbarControls> toolbarControlsPanel = toolbarPanel->controls();
    Ptr<ToolbarControl> toolbarControlPanel = toolbarControlsPanel->itemById(commandId);
    if (!toolbarControlPanel)
    {
        toolbarControlPanel = toolbarControlsPanel->addCommand(commandDefinition, commandId);
        toolbarControlPanel->isVisible(true);
    }

    //// Prevent this module from being terminate when the script returns, because we are waiting for event handlers to fire
    //adsk::autoTerminate(false);

    return true;
}

extern "C" XI_EXPORT bool stop(const char* context)
{
    if (ui)
    {
        ui->messageBox("in stop");
        ui = nullptr;
    }

    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

#pragma managed

However, the code causes error in loading this plugin, the error is at Memory.h 

 

T* operator->() const { assert(ptr_ != nullptr); if (ptr_ == nullptr) throw std::exception(); return ptr_; }

 

Thanks.

1 REPLY 1
Message 2 of 2
ekinsb
in reply to: khoa.ho

I found a couple of small errors and have fixed them in the code below.  I found them by debugging your code and stepping through, watching to make sure no null pointers were being returned.  In the case where null pointers are returned you can use the Application.getLastError method to get a description of what caused the last error.

 

To create a button on a toolbar you have to have an icon.  Toolbars only show icons and aren't able to display a command that only has the name.  I've attached the Resources folder I used for testing.

 

#pragma unmanaged

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

using namespace adsk::core;
using namespace adsk::fusion;
//using namespace adsk::cam;

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

// CommandCreated event handler.
class CommandCreatedEventHandler : public adsk::core::CommandCreatedEventHandler
{
public:
	void notify(const Ptr<CommandCreatedEventArgs>& eventArgs) override
	{
		if (eventArgs)
		{
			ui->messageBox("Command Created.");
		}
	}
private:
} onCommandCreated;

extern "C" XI_EXPORT bool run(const char* context)
{
	app = Application::get();
	if (!app)
		return false;

	ui = app->userInterface();
	if (!ui)
		return false;

	const std::string commandId = "MyCommand";
	const std::string commandName = "My Command Name";
	const std::string commandDescription = "My Command Name";
	const std::string workspaceToUse = "FusionSolidEnvironment";
	const std::string panelToUse = "SolidMakePanel";

	Ptr<CommandDefinitions> commandDefinitions = ui->commandDefinitions();
	if (!commandDefinitions)
		return false;

	// Be fault tolerant in case the command is already added.
	Ptr<CommandDefinition> commandDefinition = commandDefinitions->itemById(commandId);
	if (!commandDefinition)
	{
		std::string resourcePath = "Resources/Sample";
		commandDefinition = commandDefinitions->addButtonDefinition(
			commandId,
			commandName,
			commandDescription,
			resourcePath); // absolute resource file path is specified
	}

	if (!commandDefinition)
	{
		std::string errMessage;
		int rc = app->getLastError(&errMessage);
		ui->messageBox(errMessage);

		return false;
	}

	Ptr<CommandCreatedEvent> commandCreatedEvent = commandDefinition->commandCreated();
	if (!commandCreatedEvent)
		return false;
	commandCreatedEvent->add(&onCommandCreated);
	//commandDefinition->execute();

	// Add a command button on Quick Access Toolbar
	Ptr<Toolbars> toolbars = ui->toolbars();
	Ptr<Toolbar> toolbarQAT = toolbars->itemById("QAT");
	Ptr<ToolbarControls> toolbarControlsQAT = toolbarQAT->controls();
	Ptr<ToolbarControl> toolbarControlQAT = toolbarControlsQAT->itemById(commandId);
	if (!toolbarControlQAT)
	{
		toolbarControlQAT = toolbarControlsQAT->addCommand(commandDefinition, commandId);
		toolbarControlQAT->isVisible(true);
	}

	// Add a command on create panel in modeling workspace
	Ptr<Workspaces> workspaces = ui->workspaces();
	Ptr<Workspace> modelingWorkspace = workspaces->itemById(workspaceToUse);
	Ptr<ToolbarPanels> toolbarPanels = modelingWorkspace->toolbarPanels();
	Ptr<ToolbarPanel> toolbarPanel = toolbarPanels->itemById(panelToUse);
	Ptr<ToolbarControls> toolbarControlsPanel = toolbarPanel->controls();
	Ptr<ToolbarControl> toolbarControlPanel = toolbarControlsPanel->itemById(commandId);
	if (!toolbarControlPanel)
	{
		toolbarControlPanel = toolbarControlsPanel->addCommand(commandDefinition, commandId);
		toolbarControlPanel->isVisible(true);
	}

	if (ui)
	{
		ui->messageBox("Finished start");
	}

	return true;
}

extern "C" XI_EXPORT bool stop(const char* context)
{
	if (ui)
	{
		const std::string commandId = "MyCommand";
		const std::string workspaceToUse = "FusionSolidEnvironment";
		const std::string panelToUse = "SolidMakePanel";

		Ptr<Toolbars> toolbars = ui->toolbars();
		Ptr<Toolbar> toolbarQAT = toolbars->itemById("QAT");
		Ptr<ToolbarControls> toolbarControlsQAT = toolbarQAT->controls();
		Ptr<ToolbarControl> toolbarControlQAT = toolbarControlsQAT->itemById(commandId);
		if (toolbarControlQAT)
		{
			toolbarControlQAT->deleteMe();
		}

		Ptr<ToolbarPanelList> toolbarPanels = ui->allToolbarPanels();
		Ptr<ToolbarPanel> toolbarPanel = toolbarPanels->itemById(panelToUse);
		Ptr<ToolbarControls> toolbarControlsPanel = toolbarPanel->controls();
		Ptr<ToolbarControl> toolbarControl = toolbarControlsPanel->itemById(commandId);
		if (toolbarControl)
		{
			toolbarControl->deleteMe();
		}

		Ptr<CommandDefinitions> commandDefinitions = ui->commandDefinitions();
		Ptr<CommandDefinition> commandDefinition = commandDefinitions->itemById(commandId);
		if (commandDefinition)
		{
			commandDefinition->deleteMe();
		}

		ui->messageBox("in stop");
		ui = nullptr;
	}

	app = nullptr;
	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

#pragma managed

Brian Ekins
Inventor and Fusion 360 API Expert
Mod the Machine blog

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

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report