Fusion crush when faces add to activeselections

Fusion crush when faces add to activeselections

Anonymous
Not applicable
1,251 Views
10 Replies
Message 1 of 11

Fusion crush when faces add to activeselections

Anonymous
Not applicable

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.

0 Likes
1,252 Views
10 Replies
Replies (10)
Message 2 of 11

marshaltu
Autodesk
Autodesk

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 Developer
>
0 Likes
Message 3 of 11

Anonymous
Not applicable

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

0 Likes
Message 4 of 11

Anonymous
Not applicable
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

0 Likes
Message 5 of 11

Anonymous
Not applicable
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)
0 Likes
Message 6 of 11

Anonymous
Not applicable

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

 

0 Likes
Message 7 of 11

ekinsb
Alumni
Alumni

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
0 Likes
Message 8 of 11

Anonymous
Not applicable
Brian. Thanks so much.

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



0 Likes
Message 9 of 11

Anonymous
Not applicable

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

0 Likes
Message 10 of 11

ekinsb
Alumni
Alumni

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

Anonymous
Not applicable

@ekinsb You are The Master!

 

Thanks very much for your help.

0 Likes