Wed, 22 Sep 2021 13:28:53 +0300
Document model.h
/* * LDForge: LDraw parts authoring CAD * Copyright (C) 2013 - 2020 Teemu Piippo * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "modeleditcontext.h" #include "linetypes/triangle.h" #include "linetypes/quadrilateral.h" Model::EditContext::EditContext(Model& model) : storedModel{model} { } Model::EditContext::~EditContext() { for (ldraw::id_t id : this->modifiedObjects) { this->model().objectModified(id); } this->model().editFinished(); } ldraw::id_t Model::EditContext::append(std::unique_ptr<ldraw::Object>&& object) { const ldraw::id_t id = object->id; this->model().objectsById[id] = object.get(); this->model().append(std::move(object)); return id; } void Model::EditContext::remove(int position) { this->model().remove(position); } auto Model::EditContext::setObjectProperty( const ldraw::id_t id, const ldraw::Property property, const QVariant& value) -> ldraw::Object::SetPropertyResult { ldraw::Object* const object = this->model().objectAt(id); if (object != nullptr) { const ldraw::Object::SetPropertyResult result = object->setProperty(ldraw::PropertyKeyValue{property, value}); modifiedObjects.insert(id); return result; } else { return ldraw::Object::SetPropertyResult::PropertyNotHandled; } } void Model::EditContext::setObjectPoint(ldraw::id_t id, int pointId, const glm::vec3& value) { ldraw::Object* object = this->model().objectAt(id); if (object != nullptr) { object->setProperty(ldraw::PropertyKeyValue{ldraw::pointProperty(pointId), QVariant::fromValue(value)}); modifiedObjects.insert(id); } } void Model::EditContext::invertObject(ldraw::id_t id) { auto it = this->model().objectsById.find(id); if (it != this->model().objectsById.end()) { ldraw::Object* object = it->second; object->invert(); } } Model& Model::EditContext::model() { return this->storedModel; } static std::array<geom::Triangle, 2> splitTriangles(ldraw::Diagonal diagonal, const std::array<glm::vec3, 4>& points) { std::array<geom::Triangle, 2> result; switch (diagonal) { case ldraw::Diagonal::Diagonal_13: result = {geom::Triangle{points[0], points[1], points[2]}, {points[0], points[2], points[3]}}; break; case ldraw::Diagonal::Diagonal_24: result = {geom::Triangle{points[0], points[1], points[3]}, {points[1], points[2], points[3]}}; break; } return result; } auto ldraw::splitQuadrilateral( Model::EditContext& editor, ldraw::quadrilateralid_t quadrilateral_id, ldraw::Diagonal splitType ) -> std::optional<std::pair<ldraw::triangleid_t, ldraw::triangleid_t>> { std::optional<std::pair<ldraw::triangleid_t, ldraw::triangleid_t>> result; const auto resolved = editor.model().get2(quadrilateral_id); if (resolved.object != nullptr) { const ldraw::Color color = resolved.object->colorIndex; const std::array<geom::Triangle, 2> split = splitTriangles(splitType, resolved.object->points); const int position = resolved.index.row(); editor.remove(position); result = std::make_pair( editor.insert<ldraw::Triangle>(position, split[0].points, color), editor.insert<ldraw::Triangle>(position, split[1].points, color)); } return result; }