SelectionCommandInput, want to collect multiple paths for sweeping

SelectionCommandInput, want to collect multiple paths for sweeping

metd01567
Advocate Advocate
1,443 Views
8 Replies
Message 1 of 9

SelectionCommandInput, want to collect multiple paths for sweeping

metd01567
Advocate
Advocate

I've got a repetitive design task that requires a solution to sweep's "single path/single intersecting profile" restriction.  In concept, I'll clone a user selected reference profile and re-orient it for each selected path.  I mashed up the pipe example with the Command Input API sample, and have a partial solution working.  The "path" selection isn't clean though.  I'd like a "Path" filter that works like the existing Sweep dialog, highlighting the entire chained path vs individual SketchCurves. I didn't find anything like that in the SelectionCommandInput filters

 

I'm currently using a SelectCommandInput with filter: "SkectchCurve".  This highlights the individual segments as I roll over the sketch, and if I double-click I get entire chained paths.  But that doesn't support selection of multiple paths, and isn't as elegant as native Sweep's user interface.  In theory I could build my own with a selectionEvent handler.  Before I go down that road I'd like to know if there's an existing selection filter, or other API mechanism that gives the desired behavior.

 

0 Likes
Accepted solutions (1)
1,444 Views
8 Replies
Replies (8)
Message 2 of 9

goyals
Autodesk
Autodesk

There is a way where you can create a chain path from an input path. Please look at the below code

 

product = app.activeProduct;
design = adsk.fusion.Design(product);

comp = design.rootComponent;
features = comp.features;
sweepPath = features.createPath(path, isChainSelection);



Shyam Goyal
Sr. Software Dev. Manager
0 Likes
Message 3 of 9

metd01567
Advocate
Advocate

Thanks, I do something similar, but I'm searching for multiple paths.  Here's what I do in the execute handler.

    for thisEntity in range(0, pathSelectionInput.selectionCount):

        selectedPath = adsk.fusion.SketchCurve.cast(pathSelectionInput.selection(thisEntity).entity)
        if selectedPath == None:
            ui.messageBox('software error: path selection could not be used')
            return
        doSweep(selectedSketch, selectedPath)

This works with the "SketchCurve" selection filter if I choose one and only one curve for each path.  In that case I get a single SketchCurve entity for each path.  As a user, when the paths are complex, I need to see all the curves so I know I haven't missed anything.  But if I double-click a curve for each path (so the entire path is highlighted), I get a big furball with all the curves from all the paths.

 

Here's what I did in the create handler to specify 1 or more curves.  Would be much nicer if the last line could use: "SketchPaths" or something like that as a filter.

            # Create a selection input for paths
            pathSelectionInput = childInputs.addSelectionInput('pathSelection', 'Paths', 'select any segment of the path, the complete chain will be used')
            pathSelectionInput.setSelectionLimits(1)
            pathSelectionInput.addSelectionFilter("SketchCurves")

I know how to get what I want (in theory) by handling input change, selectionEvent and validation handlers.  It would be a learning experience, but if there's an easier way I'd rather not.

 

0 Likes
Message 4 of 9

metd01567
Advocate
Advocate

OK, I don't think there will be a "Path" filter anytime soon, and I doubt anyone has a nice solution to hand me.  I'll give a running account as I think of things to try.  Maybe someone can keep me from going down the ratholes.

 

I'm stuck with the SketchCurve filter, which highlights individual SketchCurves, and returns a single collection.  To emulate the native Sweep dialog's behavior (which I like), I'll implement a selectionEvent handler to extend each single-curve selection to all of the curves in the chained path.  The SelectionEventArgs provided to the hander has an "additionalEntities" method, so the chained curves can be inserted.  I'm guessing that when the user clicks on the highlighted path, the additional entities will drop into the SelectionCommandInput.

 

Unlike Sweep, since I'm allowing multiple paths to be selected, these "path" selections will each drop a ball of SketchCurves into the SelectionInput, which will build up into a bigger ball of SketchCurves.  Those will have to be sorted back into paths by the execute handler.  Won't be easy, but should be possible.  Via a separate forum topic I've learned how to compare the transient curves in a path to the linked SketchCurve objects.

0 Likes
Message 5 of 9

metd01567
Advocate
Advocate

Extending the selection really wasn't too bad.  With this handler, paths are highlighted as the cursor hovers over the drawing.  As predicted, when a highlighted path is clicked, all the path's curves are added to the input.  Next is sorting out the ball of curves.

 

# Event handler that reacts to user hovering over a selection.
class MySelectionEventHandler(adsk.core.SelectionEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        try:

            app = adsk.core.Application.get()
            ui = app.userInterface
            product = app.activeProduct
            design = adsk.fusion.Design.cast(product)
            comp = design.rootComponent
            feats = comp.features

            eventArgs = adsk.core.SelectionEventArgs.cast(args)
            if eventArgs:
                if eventArgs.activeInput.id == "pathSelection":

                    sketchCurve = adsk.fusion.SketchCurve.cast(eventArgs.selection.entity)
                    if not sketchCurve:
                        ui.messageBox("software error selection is not a curve")
                        return

                    # convert the path selection object to a usable path - chained curve by default
                    path = feats.createPath(sketchCurve)

                    # create a collection of sketch curves from the path's source curves
                    segments = adsk.core.ObjectCollection.create()
                    for thisEntity in path:
                        pathCurve = thisEntity.entity
                        if pathCurve != sketchCurve:
                            # exclude the original curve, or it will be deselected
                            segments.add(pathCurve)

                    # push the extra selections into the input
                    eventArgs.additionalEntities = segments

        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
            onSelection = MySelectionEventHandler()
            cmd.selectionEvent.add(onSelection)
            _handlers.append(onSelection)

 

 

Message 6 of 9

metd01567
Advocate
Advocate
Accepted solution

Sorting was also easy:

    ###############################################
    # copy the sketch curves into a "raw" collection
    raw = adsk.core.ObjectCollection.create()    
    for thisEntity in range(pathSelectionInput.selectionCount):
        raw.add(pathSelectionInput.selection(thisEntity).entity)
    
    # completed paths go into the "cooked" collection
    cooked = adsk.core.ObjectCollection.create()
    
    while raw.count:
        # randomly take a raw curve and make a path of it
        thisCurve = raw.item(0)
        path = feats.createPath(thisCurve)
        
        # save the path, and remove its curves from the raw collection
        cooked.add(path)
        for thisPathEntity in path:
            raw.removeByItem(thisPathEntity.entity)

And now I have a collection of paths to work with.

0 Likes
Message 7 of 9

Anonymous
Not applicable

Hi @metd01567 ,

Thanks for your interesting post and sharing your solution.

I tested your solution for selecting just one path (to find if it solves my problem). But it does not work correctly when I want to deselect a previously selected path. Have you encountered the same problem? If yes, do you have any suggestions for solving it?

Message 8 of 9

metd01567
Advocate
Advocate

Surprisingly, I never tried that.  You're right, it doesn't work correctly.  That's what I get for writing: "Sorting was also easy".

 

It shouldn't be too hard to figure out, once I get the cobwebs out.  I'll fix it at some point but I don't know when.

 

I would probably start with a very small sketch, and dump or inspect the collected segments vs the additionalEntities at each step.

Message 9 of 9

Anonymous
Not applicable

Thank you for your reply and describing the method you are likely to use to solve the problem.

0 Likes