finished splitQuadrilateral theoretically (untested)

Mon, 09 Mar 2020 22:12:50 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Mon, 09 Mar 2020 22:12:50 +0200
changeset 76
7c4a63a02632
parent 75
204dc77e5654
child 77
028798a72591

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>>;
 }

mercurial