Mon, 09 Mar 2020 22:12:50 +0200
finished splitQuadrilateral theoretically (untested)
src/model.cpp | file | annotate | diff | comparison | revisions | |
src/model.h | file | annotate | diff | comparison | revisions | |
src/modeleditcontext.cpp | file | annotate | diff | comparison | revisions | |
src/modeleditcontext.h | file | annotate | diff | comparison | revisions |
--- a/src/model.cpp Sat Mar 07 01:25:37 2020 +0200 +++ b/src/model.cpp Mon Mar 09 22:12:50 2020 +0200 @@ -117,7 +117,20 @@ void Model::append(ModelObjectPointer&& object) { + const int position = static_cast<int>(this->body.size()); + emit beginInsertRows({}, position, position); this->body.push_back(std::move(object)); + emit endInsertRows(); +} + +void Model::remove(int position) +{ + if (position >= 0 and position < signed_cast(this->body.size())) + { + emit beginRemoveRows({}, position, position); + this->body.erase(std::begin(this->body) + position); + emit endRemoveRows(); + } } ldraw::Object* Model::objectAt(const QModelIndex& index)
--- a/src/model.h Sat Mar 07 01:25:37 2020 +0200 +++ b/src/model.h Mon Mar 09 22:12:50 2020 +0200 @@ -49,7 +49,7 @@ template<typename R> ldraw::Id<R> checkType(ldraw::id_t id) const; template<typename R> - const R* get(ldraw::Id<R> id) const; + const R* get(ldraw::Id<R> id, QModelIndex* index_out = nullptr) const; signals: void objectAdded(ldraw::id_t id, int position); private: @@ -58,7 +58,8 @@ ldraw::Id<T> append(Args&&... args); void append(ModelObjectPointer&& object); template<typename T, typename... Args> - ldraw::Id<T> insert(int position, Args&&... args); + ldraw::Id<T> insert(std::size_t position, Args&&... args); + void remove(int position); ldraw::Object* objectAt(const QModelIndex& index); const ldraw::Object* objectAt(const QModelIndex& index) const; template<typename T> @@ -109,25 +110,30 @@ this->body.push_back(std::make_unique<T>(args...)); ldraw::Object* pointer = this->body.back().get(); this->objectsById[pointer->id] = pointer; - emit objectAdded(pointer->id, this->body.size() - 1); + emit objectAdded(pointer->id, static_cast<int>(this->body.size() - 1)); emit layoutChanged(); - return ldraw::Id<T>{pointer->id}; + return ldraw::Id<T>{pointer->id.value}; } template<typename T, typename... Args> -ldraw::Id<T> Model::insert(int position, Args&&... args) +ldraw::Id<T> Model::insert(std::size_t position, Args&&... args) { emit layoutAboutToBeChanged(); - this->body.insert(position, std::make_unique<T>(args...)); + this->body.insert(std::begin(this->body) + position, std::make_unique<T>(args...)); ldraw::Object* pointer = this->body[position].get(); this->objectsById[pointer->id] = pointer; - emit objectAdded(pointer->id, position); + emit objectAdded(pointer->id, static_cast<int>(position)); emit layoutChanged(); - return ldraw::Id<T>{pointer->id}; + return ldraw::Id<T>{pointer->id.value}; } template<typename R> -const R* Model::get(ldraw::Id<R> id) const +const R* Model::get(ldraw::Id<R> id, QModelIndex* index_out) const { - return this->objectAt(id); + QModelIndex index = this->lookup(id); + if (index_out != nullptr) + { + *index_out = index; + } + return static_cast<const R*>(this->objectAt(index)); }
--- a/src/modeleditcontext.cpp Sat Mar 07 01:25:37 2020 +0200 +++ b/src/modeleditcontext.cpp Mon Mar 09 22:12:50 2020 +0200 @@ -31,12 +31,21 @@ return id; } +void Model::EditContext::remove(int position) +{ + this->model().remove(position); +} + void Model::EditContext::setObjectProperty( - ldraw::Object* object, + ldraw::id_t id, ldraw::Property property, const QVariant& value) { - object->setProperty(property, value); + ldraw::Object* object = this->model().objectAt(id); + if (object != nullptr) + { + object->setProperty(property, value); + } } void Model::EditContext::invertObject(ldraw::id_t id) @@ -54,17 +63,61 @@ return this->storedModel; } +namespace +{ + using PropertyTriplet = std::tuple<ldraw::Property, ldraw::Property, ldraw::Property>; +} + +static std::array<PropertyTriplet, 2> diagonalToPointProperties(ldraw::Diagonal diagonal) +{ + std::array<PropertyTriplet, 2> result; + switch (diagonal) + { + case ldraw::Diagonal::Diagonal_13: + result = { + std::make_tuple(ldraw::Property::Point1, ldraw::Property::Point2, ldraw::Property::Point3), + std::make_tuple(ldraw::Property::Point1, ldraw::Property::Point3, ldraw::Property::Point4) + }; + break; + case ldraw::Diagonal::Diagonal_24: + result = { + std::make_tuple(ldraw::Property::Point1, ldraw::Property::Point2, ldraw::Property::Point4), + std::make_tuple(ldraw::Property::Point2, ldraw::Property::Point3, ldraw::Property::Point4) + }; + break; + } + return result; +} + auto ldraw::splitQuadrilateral( Model::EditContext& editor, ldraw::quadrilateralid_t quadrilateral_id, - ldraw::QuadrilateralSplit splitType + 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 ldraw::Quadrilateral* quadrilateral = editor.model().get(quadrilateral_id); + QModelIndex index; + const ldraw::Quadrilateral* quadrilateral = editor.model().get(quadrilateral_id, &index); if (quadrilateral != nullptr) { - + Q_ASSERT(index.isValid()); + int position = index.row(); + editor.remove(position); + std::vector<ldraw::triangleid_t> triangles; + triangles.reserve(2); + const std::array<PropertyTriplet, 2> split = diagonalToPointProperties(splitType); + for (const PropertyTriplet& properties : split) + { + const ldraw::triangleid_t triangle = editor.insert<ldraw::Triangle>( + position, + quadrilateral->getProperty(std::get<0>(properties)).value<glm::vec3>(), + quadrilateral->getProperty(std::get<1>(properties)).value<glm::vec3>(), + quadrilateral->getProperty(std::get<2>(properties)).value<glm::vec3>(), + ldraw::Color{quadrilateral->getProperty(ldraw::Property::Color).toInt()}); + triangles.push_back(triangle); + position += 1; + } + result = {triangles[0], triangles[1]}; } return result; }
--- a/src/modeleditcontext.h Sat Mar 07 01:25:37 2020 +0200 +++ b/src/modeleditcontext.h Mon Mar 09 22:12:50 2020 +0200 @@ -26,12 +26,13 @@ { public: template<typename T, typename... Args> - ldraw::id_t append(Args&&... args); + ldraw::Id<T> append(Args&&... args); ldraw::id_t append(std::unique_ptr<ldraw::Object>&& object); template<typename T, typename... Args> - ldraw::id_t insert(int position, Args&&... args); + ldraw::Id<T> insert(int position, Args&&... args); + void remove(int position); void setObjectProperty( - ldraw::Object* object, + ldraw::id_t object, ldraw::Property property, const QVariant &value); void invertObject(ldraw::id_t id); @@ -43,13 +44,13 @@ }; template<typename T, typename... Args> -ldraw::id_t Model::EditContext::append(Args&&... args) +ldraw::Id<T> Model::EditContext::append(Args&&... args) { return this->storedModel.append<T>(args...); } template<typename T, typename... Args> -ldraw::id_t Model::EditContext::insert(int position, Args&&... args) +ldraw::Id<T> Model::EditContext::insert(int position, Args&&... args) { return this->storedModel.insert<T>(position, args...); } @@ -57,16 +58,16 @@ namespace ldraw { /// Determines how quadrilaterals are split into triangles - enum class QuadrilateralSplit + enum class Diagonal { - Split123_134, - Split124_234 + Diagonal_13, + Diagonal_24 }; // Splits the specified quadrilateral into triangles. // If it is not a quadrilateral then no action is performed auto splitQuadrilateral(Model::EditContext& editor, quadrilateralid_t quadrilateral_id, - QuadrilateralSplit splitType = QuadrilateralSplit::Split123_134 + Diagonal splitType = Diagonal::Diagonal_13 ) -> std::optional<std::pair<triangleid_t, triangleid_t>>; }