/
Team8
/
kittycad
Обзор
Документация
Войти
/
Team8
/
kittycad
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/data/assembly/assembly.cpp
245 строк
9 KB
levovix
add: BoltGost7796
09 янв 2026, 22:01
09 янв 2026, 22:01
751e6a7
Код
Авторство
О чём код?
#include "./assembly.h" #include <surf_plane.h> #include <vsn_scenecontent.h> #include <vsn_scenesegment.h> #include <gcm_types.h> #include <gcm_api.h> #include <gcm_reposition.h> #include "data/document.h" #include "data/assembly/solid_clone.h" #include "data/assembly/constraints.h" using namespace VSN; data::Assembly::~Assembly() { if (gcmSystem != nullptr) { GCM_RemoveSystem(gcmSystem); } } void data::Assembly::updateFromParams() { assert(m_dependencyChanged || m_propertyChanged); m_propertyChanged = false; m_dependencyChanged = false; if (gcmSolver == nullptr) { gcmSolver = GCM_CreateSolver(nullptr); // todo: use ItPositionManager gcmSystem = gcmSolver->System(); } currentlyUpdatingConstraints = true; struct Guard { Assembly& s; ~Guard() { s.currentlyUpdatingConstraints = false; } } guard{*this}; GCM_ClearSystem(gcmSystem); for (auto const& obj : objects) { obj->registerInGcm(gcmSystem); } for (auto const& cns : constraints) { cns->registerInGcm(gcmSystem); } for (auto obj : changedObjects) { if (obj.expired()) { continue; } if (auto ent = std::dynamic_pointer_cast<data::SolidClone>(obj.lock())) { disableAllReversedConstraintsStartingWith(ent); } } changedObjects.clear(); for (auto const& cns : constraints) { addBlackBoxes(cns, gcmSolver); } // todo: замораживать объект-источник перестраивания, чтобы не получалось так что двигаешь объект, а он возвращается обратно GCM_result res = GCM_Evaluate(gcmSystem); #ifdef DEBUG_GCM_EVALUATE_RESULT printf("gcm result: %s\n", toString(res)); #endif if (res == GCM_RESULT_Satisfied) { for (auto const& obj : objects) { obj->updateFromGcm(gcmSystem); } for (auto const& cns : constraints) { cns->updateFromGcm(gcmSystem); } } else { // for (auto const& obj : objects) { obj->updateFromGcm(gcmSystem); } // for (auto const& cns : constraints) { cns->updateFromGcm(gcmSystem); } // todo: отобразить ошибку } // некоторые ограничения могут читать систему в время отрисовки, так что пока не будем её чистить } void data::Assembly::updateFromDependencies() { updateFromParams(); } void data::Assembly::buildVisual() { assert(m_visualChanged); m_visualChanged = false; if (visual == nullptr) { visual = new SceneSegment(); document.lock()->sceneContent->GetRootSegment()->AddSegment(visual); document.lock()->sceneToData[visual] = weak_from_this(); visual->SetVisible(visible); } } void data::Assembly::markDependencyChanged(ref<C3dObject> cause) { C3dObject::markDependencyChanged(cause); changedObjects.emplace_back(cause); } std::string_view data::Assembly::iconName() const { return "tool_assembly"; } int data::Assembly::childCount() { return objects.size() + constraints.size() + C3dObject::childCount(); } ref<data::C3dObject> data::Assembly::childAt(int i) { if (i >= 0 && i < objects.size()) { return objects[i]; } i -= objects.size(); if (i >= 0 && i < constraints.size()) { return constraints[i]; } i -= constraints.size(); return C3dObject::childAt(i); } int data::Assembly::childIndex(ref<C3dObject> const& child) { int i = C3dObject::childIndex(child); if (i != -1) { return i; } i = C3dObject::childCount(); for (auto const& x : objects) { if (x.get() == child.get()) { return i; } ++i; } for (auto const& x : constraints) { if (x.get() == child.get()) { return i; } ++i; } return -1; } void data::Assembly::removeChild(ref<C3dObject> const& child) { if (generic_remove_child(this, objects, child)) { return; } if (generic_remove_child(this, constraints, child)) { return; } } void data::Assembly::addChild(ref<C3dObject> const& child) { auto thisRef = std::static_pointer_cast<Assembly>(this->shared_from_this()); removeTemporary(child); if (auto ent = std::dynamic_pointer_cast<data::SolidClone>(child)) { objects.push_back(ent); ent->m_parent = thisRef; ent->parentAssembly = thisRef; } if (auto ent = std::dynamic_pointer_cast<data::AssemblyConstraint>(child)) { constraints.push_back(ent); ent->m_parent = thisRef; ent->assembly = thisRef; } } void data::Assembly::addTemporary(ref<C3dObject> child) { auto thisRef = std::static_pointer_cast<Assembly>(this->shared_from_this()); if (auto ent = std::dynamic_pointer_cast<data::SolidClone>(child)) { temporaryObjects.push_back(ent); ent->m_parent = thisRef; ent->parentAssembly = thisRef; } if (auto ent = std::dynamic_pointer_cast<data::AssemblyConstraint>(child)) { temporaryConstraints.push_back(ent); ent->m_parent = thisRef; ent->assembly = thisRef; } if (!document.expired()) { document.lock()->updateRequested = true; } } void data::Assembly::removeTemporary(ref<C3dObject> child) { for (auto it = temporaryObjects.begin(); it < temporaryObjects.end();) { if ((*it).expired()) { it = temporaryObjects.erase(it); } else if ((*it).lock().get() == child.get()) { it = temporaryObjects.erase(it); } else { ++it; } } for (auto it = temporaryConstraints.begin(); it < temporaryConstraints.end();) { if ((*it).expired()) { it = temporaryConstraints.erase(it); } else if ((*it).lock().get() == child.get()) { it = temporaryConstraints.erase(it); } else { ++it; } } if (!document.expired()) { document.lock()->updateRequested = true; } } char const* toString(GCM_result res) { switch (res) { case GCM_RESULT_None: { return "GCM_RESULT_None"; } break; case GCM_RESULT_Ok: { return "GCM_RESULT_Ok"; } break; case GCM_RESULT_Overconstrained: { return "GCM_RESULT_Overconstrained"; } break; case GCM_RESULT_MatedFixation: { return "GCM_RESULT_MatedFixation"; } break; case GCM_RESULT_DraggingFailed: { return "GCM_RESULT_DraggingFailed"; } break; case GCM_RESULT_Not_Satisfied: { return "GCM_RESULT_Not_Satisfied"; } break; case GCM_RESULT_Unsolvable: { return "GCM_RESULT_Unsolvable"; } break; case GCM_RESULT_DependentConstraintUnsolved: { return "GCM_RESULT_DependentConstraintUnsolved"; } break; case GCM_RESULT_Error: { return "GCM_RESULT_Error"; } break; case GCM_RESULT_InappropriateAlignment: { return "GCM_RESULT_InappropriateAlignment"; } break; case GCM_RESULT_InappropriateArgument: { return "GCM_RESULT_InappropriateArgument"; } break; case GCM_RESULT_IncompatibleArguments: { return "GCM_RESULT_IncompatibleArguments"; } break; case GCM_RESULT_InconsistentAlignment: { return "GCM_RESULT_InconsistentAlignment"; } break; case GCM_RESULT_Duplicated: { return "GCM_RESULT_Duplicated"; } break; case GCM_RESULT_CyclicDependence: { return "GCM_RESULT_CyclicDependence"; } break; case GCM_RESULT_MultiDependedGeom: { return "GCM_RESULT_MultiDependedGeom"; } break; case GCM_RESULT_OverconstrainingDependedGeoms: { return "GCM_RESULT_OverconstrainingDependedGeoms"; } break; case GCM_RESULT_DependedGeomCantBeFixed: { return "GCM_RESULT_DependedGeomCantBeFixed"; } break; case GCM_RESULT_InvalidArguments: { return "GCM_RESULT_InvalidArguments"; } break; case GCM_RESULT_UnsupportedTangencyChoice: { return "GCM_RESULT_UnsupportedTangencyChoice"; } break; case GCM_RESULT_InconsistentTangencyChoice: { return "GCM_RESULT_InconsistentTangencyChoice"; } break; case GCM_RESULT_CoaxialGearTransmissionUnsupported: { return "GCM_RESULT_CoaxialGearTransmissionUnsupported"; } break; case GCM_RESULT_OverconstrainedCamMechanism: { return "GCM_RESULT_OverconstrainedCamMechanism"; } break; case GCM_RESULT_CamMechanismsInCyclicDependency: { return "GCM_RESULT_CamMechanismsInCyclicDependency"; } break; case GCM_RESULT_InconsistentFollowerAxis: { return "GCM_RESULT_InconsistentFollowerAxis"; } break; case GCM_RESULT_InconsistentPlanarAngle: { return "GCM_RESULT_InconsistentPlanarAngle"; } break; case GCM_RESULT_UnsupportedFollowerSurface: { return "GCM_RESULT_UnsupportedFollowerSurface"; } break; case GCM_RESULT_ItsNotDrivingDimension: { return "GCM_RESULT_ItsNotDrivingDimension"; } break; case GCM_RESULT_IncorrectDimensionInterval: { return "GCM_RESULT_IncorrectDimensionInterval"; } break; case GCM_RESULT_Unregistered: { return "GCM_RESULT_Unregistered"; } break; case GCM_RESULT_InternalError: { return "GCM_RESULT_InternalError"; } break; case GCM_RESULT_ImmutableData: { return "GCM_RESULT_ImmutableData"; } break; case GCM_RESULT_Aborted: { return "GCM_RESULT_Aborted"; } break; case GCM_RESULT_Last_: { return "GCM_RESULT_Last_"; } break; } return "invalid GCM_RESULT value"; }