Selection Events API Sample

Description

The sample demos how to use selection events of a command.

Code Samples

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

#include <algorithm>

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

Ptr<Application> app;
Ptr<UserInterface> ui;
std::vector<Ptr<BRepEdge> > selectedEdges;

class MyCommandExecutePreviewHandler : public CommandEventHandler
{
public:
	void notify(const Ptr<CommandEventArgs>& eventArgs) override
	{
		Ptr<Design> design = app->activeProduct();
		if (!design)
			return;
		Ptr<Component> root = design->rootComponent();
		if (!root)
			return;
		Ptr<CustomGraphicsGroups> cggroups = root->customGraphicsGroups();
		if (!cggroups)
			return;
		Ptr<CustomGraphicsGroup> cggroup = cggroups->add();
		if (!cggroup)
			return;
		for (size_t i = 0; i < selectedEdges.size(); ++i)
		{
			Ptr<BRepEdge> edge = selectedEdges[i];
			if (!edge)
				continue;
			Ptr<Point3D> ptOnEdge = edge->pointOnEdge();
			if (!ptOnEdge)
				return;
			Ptr<Matrix3D> transform = Matrix3D::create();
			if (!transform)
				return;
			transform->translation(ptOnEdge->asVector());
			Ptr<CustomGraphicsText> cgtext = cggroup->addText(std::to_string(i+1), "Arial Black", 1, transform);
			if (!cgtext)
				return;
			Ptr<Color> color = Color::create(0, 255, 0, 255);
			if (!color)
				return;
			Ptr<CustomGraphicsSolidColorEffect> cgcolor = CustomGraphicsSolidColorEffect::create(color);
			if (!cgcolor)
				return;
			cgtext->color(cgcolor);
		}
	}
};

class MyCommandDestroyHandler : public CommandEventHandler
{
public:
	void notify(const Ptr<CommandEventArgs>& eventArgs) override
	{
		adsk::terminate();
	}
};

class MyPreSelectHandler : public SelectionEventHandler
{
public:
	void notify(const Ptr<SelectionEventArgs>& eventArgs) override
	{
		if (!eventArgs)
			return;
		Ptr<Selection> selection = eventArgs->selection();
		if (!selection)
			return;
		Ptr<BRepEdge> edge = selection->entity();
		if (!edge)
			return;
		eventArgs->additionalEntities(edge->tangentiallyConnectedEdges());
	}
};

class MyPreSelectMouseMoveHandler : public SelectionEventHandler
{
public:
	void notify(const Ptr<SelectionEventArgs>& eventArgs) override
	{
		if (!eventArgs)
			return;
		Ptr<Selection> selection = eventArgs->selection();
		if (!selection)
			return;
		Ptr<BRepEdge> edge = selection->entity();
		if (!edge)
			return;
		Ptr<Curve3D> geom = edge->geometry();
		if (!geom)
			return;
		Ptr<Design> design = app->activeProduct();
		if (!design)
			return;
		Ptr<Component> root = design->rootComponent();
		if (!root)
			return;
		Ptr<CustomGraphicsGroups> cggroups = root->customGraphicsGroups();
		if (!cggroups)
			return;
		Ptr<CustomGraphicsGroup> cggroup = cggroups->add();
		if (!cggroup)
			return;
		cggroup->id(std::to_string(edge->tempId()));
		Ptr<CustomGraphicsCurve> cgcurve = cggroup->addCurve(geom);
		if (!cgcurve)
			return;
		cgcurve->weight(10);
		Ptr<Color> color = Color::create(255, 0, 0, 255);
		if (!color)
			return;
		Ptr<CustomGraphicsSolidColorEffect> cgcolor = CustomGraphicsSolidColorEffect::create(color);
		if (!cgcolor)
			return;
		cgcurve->color(cgcolor);
	}
};

class MyPreSelectEndHandler : public SelectionEventHandler
{
public:
	void notify(const Ptr<SelectionEventArgs>& eventArgs) override
	{
		if (!eventArgs)
			return;
		Ptr<Selection> selection = eventArgs->selection();
		if (!selection)
			return;
		Ptr<BRepEdge> edge = selection->entity();
		if (!edge)
			return;
		Ptr<Design> design = app->activeProduct();
		if (!design)
			return;
		Ptr<Component> root = design->rootComponent();
		if (!root)
			return;
		Ptr<CustomGraphicsGroups> cggroups = root->customGraphicsGroups();
		if (!cggroups)
			return;
		std::string edgeId = std::to_string(edge->tempId());
		for (size_t i = 0; i < cggroups->count(); ++i)
		{
			Ptr<CustomGraphicsGroup> group = cggroups->item(i);
			if (group && (group->id() == edgeId))
			{
				group->deleteMe();
				break;
			}
		}
	}
};

class MySelectHandler : public SelectionEventHandler
{
public:
	void notify(const Ptr<SelectionEventArgs>& eventArgs) override
	{
		if (!eventArgs)
			return;
		Ptr<Selection> selection = eventArgs->selection();
		if (!selection)
			return;
		Ptr<BRepEdge> edge = selection->entity();
		if (!edge)
			return;
		selectedEdges.emplace_back(edge);
	}
};

class MyUnSelectHandler : public SelectionEventHandler
{
public:
	void notify(const Ptr<SelectionEventArgs>& eventArgs) override
	{
		if (!eventArgs)
			return;
		Ptr<Selection> selection = eventArgs->selection();
		if (!selection)
			return;
		Ptr<BRepEdge> edge = selection->entity();
		if (!edge)
			return;
		for (std::vector<Ptr<BRepEdge> >::iterator it = selectedEdges.begin(); it != selectedEdges.end(); ++it)
		{
			if ((*it) && ((*it)->tempId() == edge->tempId()))
			{
				selectedEdges.erase(it);
				break;
			}
		}
	}
};

class MyCommandCreatedHandler : public CommandCreatedEventHandler
{
public:
	void notify(const Ptr<CommandCreatedEventArgs>& eventArgs) override
	{
		if (!eventArgs)
			return;
		Ptr<Command> cmd = eventArgs->command();
		if (!cmd)
			return;
		cmd->isExecutedWhenPreEmpted(false);
		Ptr<CommandInputs> inputs = cmd->commandInputs();
		if (!inputs)
			return;
		Ptr<SelectionCommandInput> selectInput = inputs->addSelectionInput("SelectionEventsSample", "Edges", "Please select edges");
		if (!selectInput)
			return;
		selectInput->addSelectionFilter(SelectionCommandInput::Edges);
		selectInput->setSelectionLimits(1);
		Ptr<CommandEvent> executePreview = cmd->executePreview();
		if (!executePreview)
			return;
		executePreview->add(&m_cmdPreviewHandler);
		Ptr<CommandEvent> destroy = cmd->destroy();
		if (!destroy)
			return;
		destroy->add(&m_cmdDestroyHandler);
		Ptr<SelectionEvent> preSelect = cmd->preSelect();
		if (!preSelect)
			return;
		preSelect->add(&m_preSelectHandler);
		Ptr<SelectionEvent> preSelectMouseMove = cmd->preSelectMouseMove();
		if (!preSelectMouseMove)
			return;
		preSelectMouseMove->add(&m_preSelectMouseMoveHandler);
		Ptr<SelectionEvent> preSelectEnd = cmd->preSelectEnd();
		if (!preSelectEnd)
			return;
		preSelectEnd->add(&m_preSelectEndHandler);
		Ptr<SelectionEvent> select = cmd->select();
		if (!select)
			return;
		select->add(&m_selectHandler);
		Ptr<SelectionEvent> unselect = cmd->unselect();
		if (!unselect)
			return;
		unselect->add(&m_unSelectHandler);
	}

private:
	MyCommandExecutePreviewHandler m_cmdPreviewHandler;
	MyCommandDestroyHandler m_cmdDestroyHandler;
	MyPreSelectHandler m_preSelectHandler;
	MyPreSelectMouseMoveHandler m_preSelectMouseMoveHandler;
	MyPreSelectEndHandler m_preSelectEndHandler;
	MySelectHandler m_selectHandler;
	MyUnSelectHandler m_unSelectHandler;
} myCmdCreatedHandler;

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

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

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

	Ptr<CommandDefinition> myCmdDef = cmdDefs->itemById("SelectionEventsSample_Cpp");
	if (!myCmdDef)
		myCmdDef = cmdDefs->addButtonDefinition("SelectionEventsSample_Cpp", "Selection Events Sample", "", "");
	if (!myCmdDef)
		return false;

	Ptr<CommandCreatedEvent> createdEvent = myCmdDef->commandCreated();
	if (!createdEvent)
		return false;
	createdEvent->add(&myCmdCreatedHandler);

	// Execute the command definition.
	myCmdDef->execute();

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

	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
#Author-Autodesk
#Description-Demo how to use selection events of a command.

import adsk.core, adsk.fusion, adsk.cam, traceback

ui = adsk.core.UserInterface.cast(None)
handlers = []
selectedEdges = []

class MyCommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            cmd = args.command
            cmd.isExecutedWhenPreEmpted = False
            inputs = cmd.commandInputs
            
            selectInput = inputs.addSelectionInput('SelectionEventsSample', 'Edges', 'Please select edges')
            selectInput.addSelectionFilter(adsk.core.SelectionCommandInput.Edges)
            selectInput.setSelectionLimits(1)
            
            # Connect to the command related events.
            onExecutePreview = MyCommandExecutePreviewHandler()
            cmd.executePreview.add(onExecutePreview)
            handlers.append(onExecutePreview)        

            onDestroy = MyCommandDestroyHandler()
            cmd.destroy.add(onDestroy)
            handlers.append(onDestroy)  
            
            onPreSelect = MyPreSelectHandler()
            cmd.preSelect.add(onPreSelect)
            handlers.append(onPreSelect)
            
            onPreSelectMouseMove = MyPreSelectMouseMoveHandler()
            cmd.preSelectMouseMove.add(onPreSelectMouseMove)
            handlers.append(onPreSelectMouseMove)

            onPreSelectEnd = MyPreSelectEndHandler()
            cmd.preSelectEnd.add(onPreSelectEnd)
            handlers.append(onPreSelectEnd)

            onSelect = MySelectHandler()
            cmd.select.add(onSelect)
            handlers.append(onSelect) 
            
            onUnSelect = MyUnSelectHandler()
            cmd.unselect.add(onUnSelect)            
            handlers.append(onUnSelect) 
        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
                
class MyCommandExecutePreviewHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            app = adsk.core.Application.get()
            design = adsk.fusion.Design.cast(app.activeProduct)
            if design:
                cggroup = design.rootComponent.customGraphicsGroups.add()
                for i in range(0, len(selectedEdges)):
                    edge = adsk.fusion.BRepEdge.cast(selectedEdges[i])
                    transform = adsk.core.Matrix3D.create()
                    transform.translation = edge.pointOnEdge.asVector()
                    cgtext = cggroup.addText(str(i+1), 'Arial Black', 1, transform)
                    cgtext.color = adsk.fusion.CustomGraphicsSolidColorEffect.create(adsk.core.Color.create(0,255,0,255))
        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))                

class MyCommandDestroyHandler(adsk.core.CommandEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            # when the command is done, terminate the script
            # this will release all globals which will remove all event handlers
            adsk.terminate()
        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
                
class MyPreSelectHandler(adsk.core.SelectionEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            selectedEdge = adsk.fusion.BRepEdge.cast(args.selection.entity)
            if selectedEdge:
                args.additionalEntities = selectedEdge.tangentiallyConnectedEdges        
        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) 
                
class MyPreSelectMouseMoveHandler(adsk.core.SelectionEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            app = adsk.core.Application.get()
            design = adsk.fusion.Design.cast(app.activeProduct)
            selectedEdge = adsk.fusion.BRepEdge.cast(args.selection.entity) 
            if design and selectedEdge:
                group = design.rootComponent.customGraphicsGroups.add()
                group.id = str(selectedEdge.tempId)
                cgcurve = group.addCurve(selectedEdge.geometry)
                cgcurve.color = adsk.fusion.CustomGraphicsSolidColorEffect.create(adsk.core.Color.create(255,0,0,255))
                cgcurve.weight = 10      
        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
                
class MyPreSelectEndHandler(adsk.core.SelectionEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            app = adsk.core.Application.get()
            design = adsk.fusion.Design.cast(app.activeProduct)
            selectedEdge = adsk.fusion.BRepEdge.cast(args.selection.entity) 
            if design and selectedEdge:
                for group in design.rootComponent.customGraphicsGroups:
                    if group.id == str(selectedEdge.tempId):
                        group.deleteMe()
                        break       
        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
                
class MySelectHandler(adsk.core.SelectionEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            selectedEdge = adsk.fusion.BRepEdge.cast(args.selection.entity) 
            if selectedEdge:
                selectedEdges.append(selectedEdge)
        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
                
class MyUnSelectHandler(adsk.core.SelectionEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:
            selectedEdge = adsk.fusion.BRepEdge.cast(args.selection.entity) 
            if selectedEdge:
                selectedEdges.remove(selectedEdge)
        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

def run(context):
    global ui
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        
        myCmdDef = ui.commandDefinitions.itemById('SelectionEventsSample_Python')
        if myCmdDef is None:
            myCmdDef = ui.commandDefinitions.addButtonDefinition('SelectionEventsSample_Python', 'Selection Events Sample', '', '')
        
        # Connect to the command created event.
        onCommandCreated = MyCommandCreatedHandler()
        myCmdDef.commandCreated.add(onCommandCreated)
        handlers.append(onCommandCreated)
        
        # Execute the command.
        myCmdDef.execute()

        # prevent this module from being terminate when the script returns, because we are waiting for event handlers to fire
        adsk.autoTerminate(False)

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))