We are trying to export attached model "E3D V6 Hotend 1,75mm universal v6.f3d" while exporting we are getting isVisible status incorrect and it is working fine for other models.
We are using following code snippet :
adsk::core::Ptr<adsk::fusion::BRepBodies> bBodies = rootComponent->bRepBodies();
for (int j = 0; j < bodyCount; j++)
{
...
adsk::core::Ptr<adsk::fusion::BRepBody> body1 = bBodies->item(j);
bool isTransientBody = body1->isTransient();
if(isTransientBody)
continue;
adsk::core::Ptr<adsk::fusion::BRepFaces> bfaces = body1->faces();
if(body1->isVisible())
partData.m_isVisible = body1->isVisible();
...
}
Here the isVisible API is always returning false although some of the parts are visible in model space.
As per our investigation the isVisible API returning values depending on isTransient status. While debugging the above model we observed that isVisible API returns false although isTransient API returns false for the part which is visible in the model space. We have also found that isVisible API works fine if we delete the sub assembly "Single Parts" from the model.
Please guide us to understand isVisible API and its working and allow us to export only visible model from the attached "E3D V6 Hotend 1,75mm universal v6.f3d" Fusion360 model.
Yes, BRepBody.isVisible property is only valid if the BRepBody.IsTransient property is false.
Alternatively, in your case, have you considered using Occurrence.isVisible Property which gives the
visible state of the occurrence in the assembly?
Here is the code you can use for testing:
bool getOccVisibleState() { Ptr<Application> app = Application::get(); if (!app) return false; ui = app->userInterface(); if (!ui) return false; Ptr<Product> product = app->activeProduct(); if (!product) return false; Ptr<Design> design = product; if (!design) return false; // Get the root component of the active design Ptr<Component> rootComp = design->rootComponent(); if(!rootComp) return false; // Iterate through all of the occurrences in the assembly. Ptr<OccurrenceList> occList = rootComp->allOccurrences(); if(!occList) return false; for (size_t i = 0; i < occList->count(); ++i) { Ptr<Occurrence> occ = occList->item(i); if(!occ) return false; bool visibleStatusOcc = occ->isVisible();; std::string strOcc = occ->name()+ " Visible status is : "+ std::string(visibleStatusOcc ? "t" : "f"); ui->messageBox(strOcc); } return true; }
Hope this helps.
Transient bodies are only returned in very special cases and never when traversing the model in the way that you're doing. An example of when a transient body is returned is when you perform an interference analysis and ask for the interference bodies. In this case these bodies don't exist in the model but are returned as a representation of the interference volumes. The bodies you interact with in Fusion are never transient.
In your sample code you're getting the bodies that are in the root component, which in your sample file there aren't any. To get the bodies in the entire assembly you need to traverse through the assembly occurrences and get the bodies. The important thing is doing this is to keep the context of the assembly so that the bodies you get will be proxies. With respect to a specific component a body could be set to be visible but in the context of the assembly it could be invisible. You can read more about occurrences and proxies here: http://help.autodesk.com/view/fusion360/ENU/?guid=GUID-88A4DB43-CFDD-4CFF-B124-7EE67915A07A
Here's some sample code that does this and reports the visible status for every body in the assembly.
def run(context): ui = None try: app = adsk.core.Application.get() ui = app.userInterface product = app.activeProduct design = adsk.fusion.Design.cast(product) # Get the root component of the active design rootComp = design.rootComponent print ('\nResults') showBodies(rootComp.occurrences, 0) except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) def showBodies(occs, level): occ = adsk.fusion.Occurrence.cast(None) for occ in occs: print(' ' * (level*3) + occ.name) body = adsk.fusion.BRepBody.cast(None) for body in occ.bRepBodies: print(' ' * (level*3+3) + body.name + ', isVisible: ' + str(body.isVisible)) showBodies(occ.childOccurrences, level + 1)