app
Fusion - the Fusion 360 Bridge
Public Made by Adomby adom
Drive Autodesk Fusion 360 from the cloud via Adom Bridge: component libraries, IPC package generation, board layout, exports (STEP/Gerbers/BOM/CPL), fast APS cloud search, and parametric modeling.
master
Drew Owens
Share frozen native Rust mechanical development checkpoint and qualification scope
b2d7cdb
26d ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
// Bounded typed root physical-property observation. No setters or SDK pointers
// cross the ABI; all Ptr ownership is local to this owning-thread invocation.
#include <array>
#include <Fusion/BRep/BRepFaces.h>
#include <Fusion/Components/Occurrences.h>
#include <Fusion/MeshBody/MeshBodies.h>
static_assert(sizeof(AfPhysicalState)==104 && offsetof(AfPhysicalState,mass_kg)==56 && offsetof(AfPhysicalState,center_cm)==80,"physical ABI");
static_assert(static_cast<uint32_t>(adsk::fusion::HighCalculationAccuracy)==2,"SDK high accuracy enum");
static int ph_body(AfContext*c,AfExtrudeDiagnostic*diag,const Ptr<adsk::fusion::Component>&root,
const Ptr<adsk::fusion::BRepBody>&body,uint64_t&faces) {
if(!body)return 7;
bool live=body->isValid();if(!ex_ok(c,diag,130)||!live)return 3;
auto parent=body->parentComponent();if(!ex_ok(c,diag,131)||parent!=root)return 6;
bool transient=body->isTransient();if(!ex_ok(c,diag,132)||transient)return 6;
auto context=body->assemblyContext();if(!ex_ok(c,diag,133)||context)return 6;
bool solid=body->isSolid();if(!ex_ok(c,diag,134)||!solid)return 6;
auto list=body->faces();if(!ex_ok(c,diag,135)||!list)return 7;
faces=list->count();if(!ex_ok(c,diag,136)||faces==0)return 6;
return 0;
}
extern "C" int af_root_physical(AfContext*c,AfDocumentRef*d,uint64_t max_bodies,uint64_t max_faces,AfPhysicalState*out,AfBytes sink,void*user,AfExtrudeDiagnostic*diag) noexcept {
if(!out||!sink||!diag||max_bodies>128||max_faces>20000)return 1;
*out={};*diag={};diag->sdk_error=-1;diag->stage=1;
try{
Ptr<adsk::fusion::Design> design;int status=af_design(c,d,design);if(status)return status;
auto root=design->rootComponent();if(!ex_ok(c,diag,100)||!root)return 7;
bool live=root->isValid();if(!ex_ok(c,diag,101)||!live)return 3;
auto before=root->revisionId();if(!ex_ok(c,diag,102))return 7;
if(!sink(user,0,before.data(),before.size()))return 5;
auto intent=design->designIntent();if(!ex_ok(c,diag,103))return 7;out->design_intent=static_cast<uint32_t>(intent);
bool configured=design->isConfiguredDesign();if(!ex_ok(c,diag,104))return 7;
bool configuration=design->isConfiguration();if(!ex_ok(c,diag,105))return 7;out->configured=configured||configuration?1:0;
if(intent!=adsk::fusion::HybridDesignIntentType||out->configured)return 6;
auto occurrences=root->occurrences();if(!ex_ok(c,diag,106)||!occurrences)return 7;
out->root_occurrences=occurrences->count();if(!ex_ok(c,diag,107)||out->root_occurrences)return 6;
auto mesh=root->meshBodies();if(!ex_ok(c,diag,108)||!mesh)return 7;
out->mesh_bodies=mesh->count();if(!ex_ok(c,diag,109)||out->mesh_bodies)return 6;
auto bodies=root->bRepBodies();if(!ex_ok(c,diag,110)||!bodies)return 7;
out->root_bodies=bodies->count();if(!ex_ok(c,diag,111)||out->root_bodies>max_bodies)return 6;
std::array<Ptr<adsk::fusion::BRepBody>,128> retained;
std::array<uint64_t,128> face_counts{};
for(size_t i=0;i<out->root_bodies;++i){
retained[i]=bodies->item(i);if(!ex_ok(c,diag,112)||!retained[i])return 7;
for(size_t j=0;j<i;++j)if(retained[j]==retained[i])return 6;
status=ph_body(c,diag,root,retained[i],face_counts[i]);if(status)return status;
if(face_counts[i]>max_faces-out->face_count)return 6;out->face_count+=face_counts[i];
}
// No physical calculation until the complete finite body/face admission.
auto properties=root->getPhysicalProperties(adsk::fusion::HighCalculationAccuracy);if(!ex_ok(c,diag,150)||!properties)return 7;
live=properties->isValid();if(!ex_ok(c,diag,151)||!live)return 3;
out->accuracy=static_cast<uint32_t>(properties->accuracy());if(!ex_ok(c,diag,152))return 7;
out->mass_kg=properties->mass();if(!ex_ok(c,diag,153))return 7;
out->volume_cm3=properties->volume();if(!ex_ok(c,diag,154))return 7;
out->area_cm2=properties->area();if(!ex_ok(c,diag,155))return 7;
auto center=properties->centerOfMass();if(!ex_ok(c,diag,156)||!center)return 7;
auto xyz=center->asArray();if(!ex_ok(c,diag,157)||xyz.size()!=3)return 7;
std::copy(xyz.begin(),xyz.end(),out->center_cm);
// Reacquire this exact document/design/root and every body membership.
Ptr<adsk::fusion::Design> current;status=af_design(c,d,current);if(status)return status;
if(current!=design)return 6;
auto current_root=current->rootComponent();if(!ex_ok(c,diag,170)||current_root!=root)return 6;
live=root->isValid();if(!ex_ok(c,diag,171)||!live)return 3;
auto current_bodies=root->bRepBodies();if(!ex_ok(c,diag,172)||!current_bodies)return 7;
auto count=current_bodies->count();if(!ex_ok(c,diag,173)||count!=out->root_bodies)return 6;
for(size_t i=0;i<count;++i){
auto member=current_bodies->item(i);if(!ex_ok(c,diag,174)||member!=retained[i])return 6;
uint64_t faces=0;status=ph_body(c,diag,root,retained[i],faces);if(status)return status;
if(faces!=face_counts[i])return 6;
}
auto current_occurrences=root->occurrences();if(!ex_ok(c,diag,175)||!current_occurrences)return 7;
auto occurrence_count=current_occurrences->count();if(!ex_ok(c,diag,176)||occurrence_count!=out->root_occurrences)return 6;
auto current_mesh=root->meshBodies();if(!ex_ok(c,diag,177)||!current_mesh)return 7;
auto mesh_count=current_mesh->count();if(!ex_ok(c,diag,178)||mesh_count!=out->mesh_bodies)return 6;
auto current_intent=design->designIntent();if(!ex_ok(c,diag,179)||current_intent!=intent)return 6;
configured=design->isConfiguredDesign();if(!ex_ok(c,diag,180)||configured)return 6;
configuration=design->isConfiguration();if(!ex_ok(c,diag,181)||configuration)return 6;
auto after=root->revisionId();if(!ex_ok(c,diag,182))return 7;
if(!sink(user,1,after.data(),after.size()))return 5;
return 0;
}catch(...){return 4;}
}