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.
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