/
Team8
/
kittycad
Обзор
Документация
Войти
/
Team8
/
kittycad
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/data/c3dobject.cpp
228 строк
5 KB
levovix
fix;
10 янв 2026, 21:53
10 янв 2026, 21:53
eb2e123
Код
Авторство
О чём код?
#include "c3dobject.h" #include <model_item.h> #include <vsn_scenecontent.h> #include "data/document.h" #include "gui/document_view.h" #include "gui/model_tree.h" #include "gui/tools/tool.h" data::C3dObject::~C3dObject() { deleteVisual(); deleteTool(); } void data::C3dObject::updateFromParams() { m_propertyChanged = false; m_dependencyChanged = false; } void data::C3dObject::updateFromDependencies() { m_propertyChanged = false; m_dependencyChanged = false; } void data::C3dObject::buildVisual() { m_visualChanged = false; } void data::C3dObject::draw(DrawContext& ctx) {} void data::C3dObject::drawTree(DrawContext& ctx) { if (visible) { draw(ctx); for (int i = 0; i < childCount(); ++i) { childAt(i)->drawTree(ctx); } } } void data::C3dObject::deleteVisual() { if (visual != nullptr) { if (!document.expired()) { document.lock()->sceneToData.erase(visual); } visual->GetParentSegment()->RemoveSegment(visual); visual->DeferredDelete(); visual = nullptr; } } std::string_view data::C3dObject::iconName() const { return "entity"; } Tool* data::C3dObject::newTool(QWidget* parent) { return nullptr; } Tool* data::C3dObject::getOrCreateTool(QWidget* parent) { if (tool != nullptr) { return tool; } tool = newTool(parent); return tool; } void data::C3dObject::deleteTool() { if (tool == nullptr) { return; } auto tool = this->tool; tool->deactivated(); this->tool = nullptr; } ref<data::C3dObject> data::C3dObject::parent() { return m_parent.expired() ? nullptr : m_parent.lock(); } int data::C3dObject::childCount() { return 0; } ref<data::C3dObject> data::C3dObject::childAt(int i) { throw std::out_of_range( std::string("child index out of bounds: ") + std::to_string(i) + " not in 0..<" + std::to_string(childCount()) ); } int data::C3dObject::childIndex(ref<C3dObject> const& child) { return -1; } void data::C3dObject::setParent(ref<C3dObject> const& parent) { if (this->parent().get() == parent.get()) { return; } if (auto old_parent = this->parent()) { old_parent->removeChild(std::static_pointer_cast<C3dObject>(this->shared_from_this())); } m_parent.reset(); // на всякий случай if (parent != nullptr) { parent->addChild(std::static_pointer_cast<C3dObject>(this->shared_from_this())); // если parent принимает детей, должен сам заменить наш m_parent на себя } } void data::C3dObject::removeChild(ref<C3dObject> const& child) { markDependencyChanged(child); } void data::C3dObject::addChild(ref<C3dObject> const& child) { markDependencyChanged(child); } bool data::C3dObject::removeUsageFrom(ref<C3dObject> const& usedObj) { std::erase_if( usedObj->usedBy, [this](ptr<C3dObject> const& x) -> bool { return x.expired() || x.lock().get() == this; } ); return true; } void data::C3dObject::destroy(ref<C3dObject> const& obj, int maxLeftRefcount) { for (auto const& x : std::vector(obj->usedBy)) { // итерируемся по копии if (!x.expired()) { if (x.lock()->removeUsageFrom(obj)) { destroy(x.lock()); } } } for (auto const& x : std::vector(obj->usedBy)) { if (!x.expired()) { destroy(x.lock()); // форсируем удаление зависимого объекта } } obj->setParent(nullptr); if (!obj->document.expired()) { std::erase_if( obj->document.lock()->objects, [&obj](auto const& x) { return x.get() == obj.get(); } ); } if (obj.use_count() > maxLeftRefcount) { throw std::runtime_error("leak or cyclic reference detected: unable to destroy object by removing it from parent and destroying all of the object that is using it"); } } void data::C3dObject::setVisible(bool v) { if (visible == v) { return; } visible = v; onVisibleChanged(); if (!document.expired()) { // todo: оно тут нужно вообще? auto doc = document.lock(); doc->updateRequested = true; if (doc->modelTree != nullptr) { doc->modelTree->on_objectChanged(this); } } } void data::C3dObject::onVisibleChanged() { if (visual != nullptr) { visual->SetVisible(visible); } } std::string data::C3dObject::name() const { if (m_name.empty()) { return typeNameHumanReadable(); } return m_name; } void data::C3dObject::setName(std::string&& v) { m_name = v; if (!document.expired()) { document.lock()->updateRequested = true; } } void data::C3dObject::markPropertyChanged() { m_propertyChanged = true; if (!document.expired()) { document.lock()->updateRequested = true; } } void data::C3dObject::markDependencyChanged(ref<data::C3dObject> cause) { m_dependencyChanged = true; if (!document.expired()) { document.lock()->updateRequested = true; } } void data::C3dObject::markVisualChanged() { m_visualChanged = true; if (!document.expired()) { document.lock()->updateRequested = true; } } void addTemporary(ptr<data::Document> document, ptr<data::C3dObject> child) { document.lock()->addTemporary(child.lock()); }