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: 

Fusion crush when faces add to activeselections

10 REPLIES 10
Reply
Message 1 of 11
VitautTryputsin
423 Views, 10 Replies

Fusion crush when faces add to activeselections

Hello. Some faces in model have attributes. When I run my command "Create Pieces", method "collectPieces" collect all faces with attributes. Next, in method "setActiveSelections" some faces add to activeSelections (code below). If i run my command normally - all is ok. If my command "Create Pieces"  is already running, and i run "Create Pieces" again, Fusion crush when faces add to activeselections. if I check activeselections and faces - they are valid. How to solve this problem? My commandInput have SelectionInput object. If i remove SelectionInput from commandInput, Fusion will not crush, when command restarted. It may be a problem with SelectionInput? 

def setActiveSelections(piece):
    global currentPiece
    currentPiece=piece
    app = adsk.core.Application.get()
    ui  = app.userInterface
    activeselections_ = ui.activeSelections
    activeselections_.clear()
    for face in piece.faces:
        if face.isValid:
            activeselections_.add(face)  #Here Fusion crush

Regards.

10 REPLIES 10
Message 2 of 11
marshaltu
in reply to: VitautTryputsin

Hello,

 

It would be great if you can send me(marshal dot tu at autodesk dot com) a sample to reproduce the issue. It is difficult for us to judge what could be root cause with limit information.

 

Thanks,

Marshal



Marshal Tu
Fusion 360 Developer
Autodesk, Inc.

Message 3 of 11
VitautTryputsin
in reply to: marshaltu

Marshal, thank you for help. I send you mail.

Message 4 of 11

Is there any update on this. I'm having the same problem.

I have a valid selection and when I try to add a valid face to it, it just dies

Message 5 of 11

Hello, I solved this problem in the following way. I add faces to selection by selection id. Example below:

curSel = commandInputs_.itemById(const.facesSelectionInputId)
curSel.clearSelection()

for face in piece.faces:
if face.isValid:
curSel.addSelection(face)
Message 6 of 11

Hi and thanks so much for responding so quickly.

 

I'm struggling to make the leap from the snippet you provided to creating a solution in my own code. 

 

It's my 1st script and I'm selecting the faces programatically if they satisfy certain conditions but it comes down to the fact that I have 2 valid  brepfaces. 

 

The snippet I have that fails is as follows: 

 

 

function alignFaces(face1,face2) {
  var app = adsk.core.Application.get();
  var ui  = app.userInterface;

  // Add these faces to the active selection.
  var theseSelections = ui.activeSelections;
  
  // clear any selections pre existing
  theseSelections.clear;
  
  // add the 1st face to italics  
  theseSelections.add(face1);
  
  ui.activeSelections.add(face2);

  // Get the Align Component command and execute it.
  var alignCommand = ui.commandDefinitions.itemById('AlignComponentsCmd');
  alignCommand.execute();

}

Are you able to help me make the leap? 

 

Hopefully

 

Message 7 of 11
ekinsb
in reply to: pbs.websuntangled

I don't know what the "AlignComponents" command is.  There is a command named that but I don't think it's available in the UI. The name of the Align command that you see in the modify panel is "AlignCmd".  Below is my sample code where I have one function that adds an attribute to a set of selected faces and another one that will select those faces and execute the Align command.

 

var ui;

function run(context) {

    "use strict";
    if (adsk.debug === true) {
        /*jslint debug: true*/
        debugger;
        /*jslint debug: false*/
    }
 
    try {
        var app = adsk.core.Application.get();
        ui = app.userInterface;
        

        //addAttributes(ui);
        
        var design = adsk.fusion.Design(app.activeProduct);
        var attribs = design.findAttributes('Align', 'Align');
        var face1 = attribs[0].parent;
        var face2 = attribs[1].parent;
        alignFaces(face1, face2);
    } 
    catch (e) {
        if (ui) {
            ui.messageBox('Failed : ' + (e.description ? e.description : e));
        }
    }
    
    adsk.terminate();     
}


function addAttributes(ui) {
    try {
        var faces = [];
        for (var i=0; i < ui.activeSelections.count; ++i ) {
            ui.messageBox(i.toString());
            var foundFace = adsk.fusion.BRepFace(ui.activeSelections.item(i).entity);
            faces.push(foundFace);
        }
        
        for (i=0; i<faces.length; ++i) {
            var face = faces[i];
            var attrib = face.attributes.add('Align', 'Align', 'Align');
        }
    }
    catch (e) {
        if (ui) {
            ui.messageBox('Failed : ' + (e.description ? e.description : e));
        }
    }    
}


function alignFaces(face1,face2) {
    try {
        // Add these faces to the active selection.
        var theseSelections = ui.activeSelections;

        // clear any selections pre existing
        theseSelections.clear();

        // add the faces to the selection.
        theseSelections.add(face1);
        theseSelections.add(face2);

        // Get the Align Component command and execute it.
        var alignCommand = ui.commandDefinitions.itemById('AlignCmd');
        alignCommand.execute();
    }
    catch (e) {
        if (ui) {
            ui.messageBox('Failed : ' + (e.description ? e.description : e));
        }
    }    
}

Brian Ekins
Inventor and Fusion 360 API Expert
Mod the Machine blog
Message 8 of 11
pbs.websuntangled
in reply to: ekinsb

Brian. Thanks so much.

I'll check in the morning as I have some time then.



Message 9 of 11

On closer inspection, the bit that is failing for me is functionally identical.

 

I suspect it must be to do with the way I am selecting my faces. I've removed all the looping structure that seems irrelevant to me and the chain that gets me to a face is as follows:

 

var thisOccurrence = rootComp.allOccurrences.item(i); 

// ...

var thisComponent = thisOccurrence.component;

// ...

var thisBody = thisComponent.bRepBodies.item(i);

// ...

var thisBodyFaces = thisBody.faces;

/// ... 

var thisFace = thisBodyFaces.item(i);

// ... 

// create an array to store the potential faces to lay flat on
var candidateFaces = [];
candidateFaces.push(thisFace);

// ...

var thisFace = candidateFaces[i];

return thisFace;

// ...

// faceOfTheLayoutBoard was retrieved using the same code but with different criteria
alignFaces(faceOfTheTheLayoutBoard,thisFace);

// ...

function alignFaces(face1,face2) {
try {

var app = adsk.core.Application.get();
ui = app.userInterface;

// Add these faces to the active selection.
var theseSelections = ui.activeSelections;

// clear any selections pre existing
theseSelections.clear();

// add the faces to the selection.
theseSelections.add(face1);
theseSelections.add(face2);

// Get the Align Component command and execute it.
var alignCommand = ui1.commandDefinitions.itemById('AlignCmd');
alignCommand.execute();
}
catch (e) {
if (ui) {
ui.messageBox('Failed : ' + (e.description ? e.description : e));
}
}
}

When i use the debugger, it shows that thisFace is a brepface 

 

When I execute the line 

 theseSelections.add(face1);

 it falls over and dies

Message 10 of 11
ekinsb
in reply to: pbs.websuntangled

What you've run into is a context/proxy issue.  Let me use your code to try and explain and to best understand it lets assume you have a design that contains two instances of the same component.  You could create this by creating a box and specifying that you want to create a new component.  Three things are created in that step.  A new component, a body in that component, and an occurrence which references the component.  What you see in the UI is a representation of the component with respect to the occurrence.  The UI makes this confusing because it refers to everything as a "Component" but there is also an "Occurrence".  You can read a more detailed description of this in the Fusion API help.

 

Anyway in your case after the copy you'll have two occurrences that both reference the same component.  In your code below you're getting one of those occurrences and then getting the component it references and then getting a face within that component.  The problem is that when you got the component from the occurrence you left the context of the assembly and now are in the context of the component.  Let's say you want to get the "top" face of the part.  But because you have two occurrences of the part there are two "top" faces.  If you just have the face in the component, Fusion doesn't understand which of the two faces in the assembly you want.

 

var thisComponent = thisOccurrence.component;
var thisBody = thisComponent.bRepBodies.item(i);
var thisBodyFaces = thisBody.faces;
var thisFace = thisBodyFaces.item(i);

 

Once you've found the face in the component you want you need to get the equivalent face for the specific occurrence.  The code below will do that.  It creates a new BRepFace object that understands which occurrence it is relative to.  It's this face that you can select in the assembly because it's know in the context of the assembly.

 

var topFace1 = thisFace.createForAssemblyContext(thisOccurrence);

 


Brian Ekins
Inventor and Fusion 360 API Expert
Mod the Machine blog
Message 11 of 11
pbs.websuntangled
in reply to: ekinsb

@ekinsb You are The Master!

 

Thanks very much for your help.

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