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
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
// Included by sdk.cpp so the context and retained-document ABI remain private.
// This file performs typed property/method calls only. Rust owns operation
// planning, JSON, revisions, result classification and rollback policy.
#include <Core/Application/Products.h>
#include <Core/Application/UnitsManager.h>
#include <Core/Application/ValueInput.h>
#include <Fusion/Fusion/Design.h>
#include <Fusion/Components/Component.h>
#include <Fusion/Components/Components.h>
#include <Fusion/Fusion/Parameter.h>
#include <Fusion/Fusion/ParameterList.h>
#include <Fusion/Fusion/UserParameter.h>
#include <Fusion/Fusion/UserParameters.h>
#include <Fusion/Fusion/Timeline.h>
#include <Fusion/Fusion/TimelineObject.h>
#include <Fusion/BRep/BRepBodies.h>
#include <Fusion/Sketch/Sketches.h>
#include <cmath>
#include <string>
static bool af_input(const char* value, size_t len) {
if ((!value && len != 0) || len > 65536) return false;
for (size_t i = 0; i < len; ++i) if (value[i] == '\0') return false;
return true;
}
static std::string af_string(const char* value, size_t len) {
return len ? std::string(value, len) : std::string();
}
static int af_design(AfContext* context, AfDocumentRef* document, Ptr<adsk::fusion::Design>& out) {
int result = check_document(context, document); if (result) return result;
if (!valid(context)) return 3;
if (!document->document->isValid() || context->app->getLastError() != 0) return 3;
auto products = document->document->products();
if (context->app->getLastError() != 0 || !products) return 7;
auto product = products->itemByProductType("DesignProductType");
if (context->app->getLastError() != 0 || !product) return 7;
out = product;
if (!out || !out->isValid() || context->app->getLastError() != 0) return 3;
auto owner = out->parentDocument();
if (context->app->getLastError() != 0 || owner != document->document) return 3;
return 0;
}
static int af_active_document(AfContext* context, AfDocumentRef* document) {
auto active = context->app->activeDocument();
if (context->app->getLastError() != 0) return 7;
return active == document->document ? 0 : 6;
}
extern "C" int af_design_state(AfContext* context, AfDocumentRef* document, AfDesignState* out, AfBytes sink, void* user) noexcept {
if (!out || !sink) return 1;
*out = {};
try {
Ptr<adsk::fusion::Design> design;
int status = af_design(context, document, design); if (status) return status;
auto active = context->app->activeDocument();
if (context->app->getLastError() != 0) return 7;
out->active = active == document->document ? 1 : 0;
auto type = design->designType();
if (context->app->getLastError() != 0) return 7;
if (type != adsk::fusion::DirectDesignType && type != adsk::fusion::ParametricDesignType) return 6;
out->parametric = type == adsk::fusion::ParametricDesignType ? 1 : 0;
auto root = design->rootComponent();
if (context->app->getLastError() != 0 || !root) return 7;
auto name = root->name();
if (context->app->getLastError() != 0) return 7;
auto revision = root->revisionId();
if (context->app->getLastError() != 0 || revision.empty()) return 7;
auto units = design->unitsManager();
if (context->app->getLastError() != 0 || !units) return 7;
auto default_units = units->defaultLengthUnits();
if (context->app->getLastError() != 0 || default_units.empty()) return 7;
auto components = design->allComponents();
if (context->app->getLastError() != 0 || !components) return 7;
out->component_count = components->count();
if (context->app->getLastError() != 0) return 7;
auto bodies = root->bRepBodies();
if (context->app->getLastError() != 0 || !bodies) return 7;
out->body_count = bodies->count();
if (context->app->getLastError() != 0) return 7;
auto sketches = root->sketches();
if (context->app->getLastError() != 0 || !sketches) return 7;
out->sketch_count = sketches->count();
if (context->app->getLastError() != 0) return 7;
if (out->parametric) {
auto timeline = design->timeline();
if (context->app->getLastError() != 0 || !timeline) return 7;
out->timeline_count = timeline->count();
if (context->app->getLastError() != 0) return 7;
auto position = timeline->markerPosition();
if (context->app->getLastError() != 0 || position < 0) return 7;
out->timeline_position = static_cast<uint64_t>(position);
}
if (!sink(user, 0, name.data(), name.size())) return 5;
if (!sink(user, 1, revision.data(), revision.size())) return 5;
if (!sink(user, 2, default_units.data(), default_units.size())) return 5;
return 0;
} catch (...) { return 4; }
}
extern "C" int af_parameter_count(AfContext* context, AfDocumentRef* document, uint64_t* out) noexcept {
if (!out) return 1;
*out = 0;
try {
Ptr<adsk::fusion::Design> design;
int status = af_design(context, document, design); if (status) return status;
auto parameters = design->allParameters();
if (context->app->getLastError() != 0 || !parameters) return 7;
*out = parameters->count();
return context->app->getLastError() == 0 ? 0 : 7;
} catch (...) { return 4; }
}
extern "C" int af_parameter_read(AfContext* context, AfDocumentRef* document, uint64_t index, AfParameter* out, AfBytes sink, void* user) noexcept {
if (!out || !sink) return 1;
*out = {};
try {
Ptr<adsk::fusion::Design> design;
int status = af_design(context, document, design); if (status) return status;
auto parameters = design->allParameters();
if (context->app->getLastError() != 0 || !parameters) return 7;
auto count = parameters->count();
if (context->app->getLastError() != 0) return 7;
if (index >= count || index > SIZE_MAX) return 6;
auto parameter = parameters->item(static_cast<size_t>(index));
if (context->app->getLastError() != 0 || !parameter) return 7;
if (!parameter->isValid() || context->app->getLastError() != 0) return 3;
auto name = parameter->name();
if (context->app->getLastError() != 0) return 7;
auto expression = parameter->expression();
if (context->app->getLastError() != 0) return 7;
auto unit = parameter->unit();
if (context->app->getLastError() != 0) return 7;
auto comment = parameter->comment();
if (context->app->getLastError() != 0) return 7;
out->is_deletable = parameter->isDeletable() ? 1 : 0;
if (context->app->getLastError() != 0) return 7;
const char* object_type = parameter->objectType();
if (!object_type || context->app->getLastError() != 0) return 7;
out->is_user = std::string(object_type) == adsk::fusion::UserParameter::classType() ? 1 : 0;
auto value_type = parameter->valueType();
if (context->app->getLastError() != 0) return 7;
std::string text;
if (value_type == adsk::fusion::NumericParameterValueType) {
out->value_type = 0;
out->value = parameter->value();
if (context->app->getLastError() != 0 || !std::isfinite(out->value)) return 7;
} else if (value_type == adsk::fusion::TextParameterValueType) {
out->value_type = 1;
text = parameter->textValue();
if (context->app->getLastError() != 0) return 7;
} else { return 6; }
if (!sink(user, 0, name.data(), name.size())) return 5;
if (!sink(user, 1, expression.data(), expression.size())) return 5;
if (!sink(user, 2, unit.data(), unit.size())) return 5;
if (!sink(user, 3, comment.data(), comment.size())) return 5;
if (!sink(user, 4, text.data(), text.size())) return 5;
return 0;
} catch (...) { return 4; }
}
extern "C" int af_timeline_health(AfContext* context, AfDocumentRef* document, uint64_t index, uint32_t* out, AfBytes sink, void* user) noexcept {
if (!out || !sink) return 1;
try {
Ptr<adsk::fusion::Design> design;
int status = af_design(context, document, design); if (status) return status;
auto timeline = design->timeline();
if (context->app->getLastError() != 0 || !timeline) return 7;
auto count = timeline->count();
if (context->app->getLastError() != 0) return 7;
if (index >= count || index > SIZE_MAX) return 6;
auto object = timeline->item(static_cast<size_t>(index));
if (context->app->getLastError() != 0 || !object) return 7;
auto health = object->healthState();
if (context->app->getLastError() != 0) return 7;
*out = static_cast<uint32_t>(health);
std::string message;
if (health == adsk::fusion::WarningFeatureHealthState || health == adsk::fusion::ErrorFeatureHealthState) {
message = object->errorOrWarningMessage();
if (context->app->getLastError() != 0) return 7;
}
return sink(user, 0, message.data(), message.size()) ? 0 : 5;
} catch (...) { return 4; }
}
extern "C" int af_parameter_evaluate(AfContext* context, AfDocumentRef* document, const char* expression, size_t expression_len, const char* unit, size_t unit_len, double* out) noexcept {
if (!out || !af_input(expression, expression_len) || !af_input(unit, unit_len)) return 1;
try {
Ptr<adsk::fusion::Design> design;
int status = af_design(context, document, design); if (status) return status;
auto units = design->unitsManager();
if (context->app->getLastError() != 0 || !units) return 7;
auto expr = af_string(expression, expression_len), unit_string = af_string(unit, unit_len);
auto valid_expression = units->isValidExpression(expr, unit_string);
if (context->app->getLastError() != 0) return 7;
if (!valid_expression) return 20;
*out = units->evaluateExpression(expr, unit_string);
if (context->app->getLastError() != 0 || !std::isfinite(*out)) return 7;
return 0;
} catch (...) { return 4; }
}
extern "C" int af_parameter_create(AfContext* context, AfDocumentRef* document, const char* name, size_t name_len, const char* expression, size_t expression_len, const char* unit, size_t unit_len, const char* comment, size_t comment_len) noexcept {
if (!af_input(name, name_len) || !af_input(expression, expression_len) || !af_input(unit, unit_len) || !af_input(comment, comment_len)) return 1;
try {
Ptr<adsk::fusion::Design> design;
int status = af_design(context, document, design); if (status) return status;
status = af_active_document(context, document); if (status) return status;
auto users = design->userParameters();
if (context->app->getLastError() != 0 || !users) return 7;
auto value = adsk::core::ValueInput::createByString(af_string(expression, expression_len));
if (context->app->getLastError() != 0 || !value) return 7;
auto parameter = users->add(af_string(name, name_len), value, af_string(unit, unit_len), af_string(comment, comment_len));
if (context->app->getLastError() != 0 || !parameter) return 7;
return parameter->isValid() && context->app->getLastError() == 0 ? 0 : 7;
} catch (...) { return 4; }
}
extern "C" int af_parameter_set(AfContext* context, AfDocumentRef* document, const char* name, size_t name_len, const char* expression, size_t expression_len) noexcept {
if (!af_input(name, name_len) || !af_input(expression, expression_len)) return 1;
try {
Ptr<adsk::fusion::Design> design;
int status = af_design(context, document, design); if (status) return status;
status = af_active_document(context, document); if (status) return status;
auto parameters = design->allParameters();
if (context->app->getLastError() != 0 || !parameters) return 7;
auto parameter = parameters->itemByName(af_string(name, name_len));
if (context->app->getLastError() != 0 || !parameter) return 7;
auto changed = parameter->expression(af_string(expression, expression_len));
return changed && context->app->getLastError() == 0 ? 0 : 7;
} catch (...) { return 4; }
}
extern "C" int af_design_compute(AfContext* context, AfDocumentRef* document) noexcept {
try {
Ptr<adsk::fusion::Design> design;
int status = af_design(context, document, design); if (status) return status;
status = af_active_document(context, document); if (status) return status;
auto computed = design->computeAll();
return computed && context->app->getLastError() == 0 ? 0 : 7;
} catch (...) { return 4; }
}