# HG changeset patch # User Teemu Piippo # Date 1583784770 -7200 # Node ID 7c4a63a0263284761a40a5c1b6866bb265636d95 # Parent 204dc77e56543f406c127546b6576d838bb2c582 finished splitQuadrilateral theoretically (untested) diff -r 204dc77e5654 -r 7c4a63a02632 src/model.cpp --- 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(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) diff -r 204dc77e5654 -r 7c4a63a02632 src/model.h --- 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 ldraw::Id checkType(ldraw::id_t id) const; template - const R* get(ldraw::Id id) const; + const R* get(ldraw::Id id, QModelIndex* index_out = nullptr) const; signals: void objectAdded(ldraw::id_t id, int position); private: @@ -58,7 +58,8 @@ ldraw::Id append(Args&&... args); void append(ModelObjectPointer&& object); template - ldraw::Id insert(int position, Args&&... args); + ldraw::Id 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 @@ -109,25 +110,30 @@ this->body.push_back(std::make_unique(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(this->body.size() - 1)); emit layoutChanged(); - return ldraw::Id{pointer->id}; + return ldraw::Id{pointer->id.value}; } template -ldraw::Id Model::insert(int position, Args&&... args) +ldraw::Id Model::insert(std::size_t position, Args&&... args) { emit layoutAboutToBeChanged(); - this->body.insert(position, std::make_unique(args...)); + this->body.insert(std::begin(this->body) + position, std::make_unique(args...)); ldraw::Object* pointer = this->body[position].get(); this->objectsById[pointer->id] = pointer; - emit objectAdded(pointer->id, position); + emit objectAdded(pointer->id, static_cast(position)); emit layoutChanged(); - return ldraw::Id{pointer->id}; + return ldraw::Id{pointer->id.value}; } template -const R* Model::get(ldraw::Id id) const +const R* Model::get(ldraw::Id id, QModelIndex* index_out) const { - return this->objectAt(id); + QModelIndex index = this->lookup(id); + if (index_out != nullptr) + { + *index_out = index; + } + return static_cast(this->objectAt(index)); } diff -r 204dc77e5654 -r 7c4a63a02632 src/modeleditcontext.cpp --- 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; +} + +static std::array diagonalToPointProperties(ldraw::Diagonal diagonal) +{ + std::array 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::optional> 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 triangles; + triangles.reserve(2); + const std::array split = diagonalToPointProperties(splitType); + for (const PropertyTriplet& properties : split) + { + const ldraw::triangleid_t triangle = editor.insert( + position, + quadrilateral->getProperty(std::get<0>(properties)).value(), + quadrilateral->getProperty(std::get<1>(properties)).value(), + quadrilateral->getProperty(std::get<2>(properties)).value(), + ldraw::Color{quadrilateral->getProperty(ldraw::Property::Color).toInt()}); + triangles.push_back(triangle); + position += 1; + } + result = {triangles[0], triangles[1]}; } return result; } diff -r 204dc77e5654 -r 7c4a63a02632 src/modeleditcontext.h --- 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 - ldraw::id_t append(Args&&... args); + ldraw::Id append(Args&&... args); ldraw::id_t append(std::unique_ptr&& object); template - ldraw::id_t insert(int position, Args&&... args); + ldraw::Id 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 -ldraw::id_t Model::EditContext::append(Args&&... args) +ldraw::Id Model::EditContext::append(Args&&... args) { return this->storedModel.append(args...); } template -ldraw::id_t Model::EditContext::insert(int position, Args&&... args) +ldraw::Id Model::EditContext::insert(int position, Args&&... args) { return this->storedModel.insert(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>; }