work on circle tool

Thu, 14 Apr 2022 11:08:20 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Thu, 14 Apr 2022 11:08:20 +0300
changeset 186
922662adb72a
parent 185
a38a0eb007b0
child 187
30204975694a

work on circle tool

CMakeLists.txt file | annotate | diff | comparison | revisions
icons/linetype-circularprimitive.png file | annotate | diff | comparison | revisions
ldforge.qrc file | annotate | diff | comparison | revisions
src/ldrawalgorithm.h file | annotate | diff | comparison | revisions
src/linetypes/circularprimitive.cpp file | annotate | diff | comparison | revisions
src/linetypes/circularprimitive.h file | annotate | diff | comparison | revisions
src/linetypes/compoundobject.cpp file | annotate | diff | comparison | revisions
src/linetypes/compoundobject.h file | annotate | diff | comparison | revisions
src/linetypes/object.h file | annotate | diff | comparison | revisions
src/linetypes/propertygenerics.h file | annotate | diff | comparison | revisions
src/linetypes/subfilereference.cpp file | annotate | diff | comparison | revisions
src/tools/circletool.cpp file | annotate | diff | comparison | revisions
src/tools/circletool.h file | annotate | diff | comparison | revisions
--- a/CMakeLists.txt	Tue Mar 15 19:48:07 2022 +0200
+++ b/CMakeLists.txt	Thu Apr 14 11:08:20 2022 +0300
@@ -54,6 +54,7 @@
 	src/gl/gridprogram.cpp
 	src/gl/partrenderer.cpp
 	src/gl/vertexprogram.cpp
+	src/linetypes/circularprimitive.cpp
 	src/linetypes/compoundobject.cpp
 	src/linetypes/conditionaledge.cpp
 	src/linetypes/edge.cpp
@@ -77,6 +78,7 @@
 	src/widgets/matrixeditor.cpp
 	src/widgets/vec3editor.cpp
 	src/tools/basetool.cpp
+	src/tools/circletool.cpp
 	src/tools/selecttool.cpp
 	src/tools/drawtool.cpp
 	src/tools/pathtool.cpp
@@ -113,6 +115,7 @@
 	src/gl/gridprogram.h
 	src/gl/partrenderer.h
 	src/gl/vertexprogram.h
+	src/linetypes/circularprimitive.h
 	src/linetypes/compoundobject.h
 	src/linetypes/conditionaledge.h
 	src/linetypes/edge.h
@@ -139,6 +142,7 @@
 	src/widgets/vec3editor.h
 	src/tools/selecttool.h
 	src/tools/basetool.h
+	src/tools/circletool.h
 	src/tools/drawtool.h
 	src/tools/pathtool.h
 	src/tools/transformtool.h
Binary file icons/linetype-circularprimitive.png has changed
--- a/ldforge.qrc	Tue Mar 15 19:48:07 2022 +0200
+++ b/ldforge.qrc	Thu Apr 14 11:08:20 2022 +0300
@@ -31,5 +31,6 @@
         <file>icons/axes.png</file>
         <file>icons/invert.png</file>
         <file>icons/polyline.png</file>
+        <file>icons/linetype-circularprimitive.png</file>
     </qresource>
 </RCC>
--- a/src/ldrawalgorithm.h	Tue Mar 15 19:48:07 2022 +0200
+++ b/src/ldrawalgorithm.h	Thu Apr 14 11:08:20 2022 +0300
@@ -19,4 +19,18 @@
 
 	void invert(ModelEditor& editor, ldraw::id_t id, GetPolygonsContext *context);
 	void makeUnofficial(ModelEditor &editor);
+
+	template<typename Fn>
+	void circle(int segments, int divisions, Fn&& fn)
+	{
+		float factor = 2.0f * math::pi / divisions;
+		for (int i = 0; i < segments; i += 1)
+		{
+			fn(
+				glm::vec2{std::sin((i - 1) * factor), std::cos((i - 1) * factor)},
+				glm::vec2{std::sin(i * factor), std::cos(i * factor)},
+				glm::vec2{std::sin((i + 1) * factor), std::cos((i - 1) * factor)}
+			);
+		}
+	}
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/linetypes/circularprimitive.cpp	Thu Apr 14 11:08:20 2022 +0300
@@ -0,0 +1,108 @@
+#include "circularprimitive.h"
+
+ldraw::CircularPrimitive::CircularPrimitive(CircularPrimitiveType type, int segments, int divisions) :
+	type{type},
+	segments{segments},
+	divisions{divisions}
+{
+}
+
+QVariant ldraw::CircularPrimitive::getProperty(Property property) const
+{
+	switch (property)
+	{
+	case Property::Segments:
+		return this->segments;
+	case Property::Divisions:
+		return this->divisions;
+	case Property::CircularPrimitiveType:
+		return this->type;
+	default:
+		return BaseClass::getProperty(property);
+	}
+}
+
+QString ldraw::CircularPrimitive::textRepresentation() const
+{
+	return circularPrimitiveTypeName(this->type) + " " + QString::number(this->fraction());
+}
+
+QString ldraw::CircularPrimitive::circularPrimitiveTypeName(CircularPrimitiveType type)
+{
+	switch (type)
+	{
+	case Circle:
+		return QObject::tr("Circle");
+	case Disc:
+		return QObject::tr("Disc");
+	}
+}
+
+ldraw::Object::Type ldraw::CircularPrimitive::typeIdentifier() const
+{
+	return ldraw::Object::Type::CircularPrimitive;
+}
+
+QDataStream &ldraw::CircularPrimitive::serialize(QDataStream &stream) const
+{
+	return BaseClass::serialize(stream) << this->type << this->segments << this->divisions;
+}
+
+QDataStream &ldraw::CircularPrimitive::deserialize(QDataStream &stream)
+{
+	return BaseClass::deserialize(stream) >> this->type >> this->segments >> this->divisions;
+}
+
+QString ldraw::CircularPrimitive::toLDrawCode() const
+{
+	return utility::format(
+		"0 !LDFORGE CIRCULAR_PRIMITIVE %1 %2 %3 %4",
+		static_cast<int>(this->type),
+		this->segments,
+		this->divisions,
+		this->transformToBareString());
+}
+
+QString ldraw::CircularPrimitive::iconName() const
+{
+	return ":/icons/linetype-circularprimitive.png";
+}
+
+QString ldraw::CircularPrimitive::typeName() const
+{
+	return QObject::tr("circular primitive");
+}
+
+void ldraw::CircularPrimitive::getPolygons(std::vector<gl::Polygon> &polygons, GetPolygonsContext *) const
+{
+	for (int i = 0; i < this->segments; i += 1)
+	{
+		const float ang_1 = (2 * math::pi * i) / this->divisions;
+		const float ang_2 = (2 * math::pi * (i + 1)) / this->divisions;
+		const glm::vec3 p_1 = {std::sin(ang_1), 0, std::cos(ang_1)};
+		const glm::vec3 p_2 = {std::sin(ang_2), 0, std::cos(ang_2)};
+		switch (this->type)
+		{
+		case Circle:
+			polygons.push_back(gl::edgeLine(
+				p_1,
+				p_2,
+				this->colorIndex,
+				this->id));
+			break;
+		case Disc:
+			polygons.push_back(gl::triangle(
+				{0, 0, 0},
+				p_1,
+				p_2,
+				this->colorIndex,
+				this->id));
+			break;
+		}
+	}
+}
+
+float ldraw::CircularPrimitive::fraction() const
+{
+	return static_cast<float>(this->segments) / static_cast<float>(this->divisions);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/linetypes/circularprimitive.h	Thu Apr 14 11:08:20 2022 +0300
@@ -0,0 +1,31 @@
+#pragma once
+#include "compoundobject.h"
+#include "propertygenerics.h"
+
+namespace ldraw
+{
+	class CircularPrimitive;
+}
+
+class ldraw::CircularPrimitive : public CompoundObject
+{
+public:
+	using BaseClass = CompoundObject;
+	CircularPrimitive() = default;
+	CircularPrimitive(CircularPrimitiveType type, int segments, int divisions);
+	QVariant getProperty(Property property) const override;
+	QString textRepresentation() const override;
+	static QString circularPrimitiveTypeName(CircularPrimitiveType type);
+	Type typeIdentifier() const override;
+	QDataStream& serialize(QDataStream& stream) const override;
+	QDataStream& deserialize(QDataStream& stream) override;
+	QString toLDrawCode() const override;
+	QString iconName() const override;
+	QString typeName() const override;
+	void getPolygons(std::vector<gl::Polygon>& polygons, GetPolygonsContext*) const override;
+	float fraction() const;
+	CircularPrimitiveType type = Circle;
+	int segments = 16;
+	int divisions = 16;
+};
+
--- a/src/linetypes/compoundobject.cpp	Tue Mar 15 19:48:07 2022 +0200
+++ b/src/linetypes/compoundobject.cpp	Thu Apr 14 11:08:20 2022 +0300
@@ -113,3 +113,21 @@
 		return {};
 	}
 }
+
+QString ldraw::CompoundObject::transformToBareString() const
+{
+	return utility::format(
+		"%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12",
+		this->transformation[3][0],
+		this->transformation[3][1],
+		this->transformation[3][2],
+		this->transformation[0][0],
+		this->transformation[1][0],
+		this->transformation[2][0],
+		this->transformation[0][1],
+		this->transformation[1][1],
+		this->transformation[2][1],
+		this->transformation[0][2],
+		this->transformation[1][2],
+		this->transformation[2][2]);
+}
--- a/src/linetypes/compoundobject.h	Tue Mar 15 19:48:07 2022 +0200
+++ b/src/linetypes/compoundobject.h	Thu Apr 14 11:08:20 2022 +0300
@@ -27,6 +27,7 @@
 	QDataStream& deserialize(QDataStream& stream) override;
 	std::optional<Axis> flatDimension(GetPolygonsContext *context) const;
 	glm::mat4 transformation;
+	QString transformToBareString() const;
 	bool isInverted = false;
 protected:
 	void setProperty(SetPropertyResult* result, const PropertyKeyValue& pair) override;
--- a/src/linetypes/object.h	Tue Mar 15 19:48:07 2022 +0200
+++ b/src/linetypes/object.h	Thu Apr 14 11:08:20 2022 +0300
@@ -48,6 +48,7 @@
 		ConditionalEdge,
 		Triangle,
 		Quadrilateral,
+		CircularPrimitive,
 	};
 	friend bool handled(SetPropertyResult result)
 	{
--- a/src/linetypes/propertygenerics.h	Tue Mar 15 19:48:07 2022 +0200
+++ b/src/linetypes/propertygenerics.h	Thu Apr 14 11:08:20 2022 +0300
@@ -7,6 +7,11 @@
 
 namespace ldraw
 {
+	enum CircularPrimitiveType
+	{
+		Circle,
+		Disc
+	};
 	enum class Property;
 	struct PropertyKeyValue;
 	template<Property property>
@@ -16,6 +21,8 @@
 	};
 }
 
+Q_DECLARE_METATYPE(ldraw::CircularPrimitiveType)
+
 /**
  * Different properties
  */
@@ -30,7 +37,10 @@
 	Transformation, // 4x4 transformation matrix of a subfile reference
 	ReferenceName, // Subfile reference name
 	IsInverted, // Whether or not the object has been inverted with BFC INVERTNEXT
-	ErrorMessage // For error lines, why parsing failed
+	ErrorMessage, // For error lines, why parsing failed
+	CircularPrimitiveType, // Type of circular primitive (circle, disc, ...)
+	Segments, // Amount of circular segments this primitive covers (numerator)
+	Divisions, // Amount of segments in the circle this primitive fits in (8, 16, 48, ...)
 };
 
 Q_DECLARE_METATYPE(ldraw::Property)
@@ -57,6 +67,9 @@
 LDFORGE_DEFINE_PROPERTY_TYPE(ReferenceName, QString)
 LDFORGE_DEFINE_PROPERTY_TYPE(IsInverted, bool)
 LDFORGE_DEFINE_PROPERTY_TYPE(ErrorMessage, QString)
+LDFORGE_DEFINE_PROPERTY_TYPE(CircularPrimitiveType, ldraw::CircularPrimitiveType)
+LDFORGE_DEFINE_PROPERTY_TYPE(Segments, int)
+LDFORGE_DEFINE_PROPERTY_TYPE(Divisions, int)
 
 #define LDRAW_OBJECT_HANDLE_SET_PROPERTY(PROPERTY, HANDLER) \
 	{this->handle<ldraw::Property::PROPERTY>(result, pair, \
--- a/src/linetypes/subfilereference.cpp	Tue Mar 15 19:48:07 2022 +0200
+++ b/src/linetypes/subfilereference.cpp	Thu Apr 14 11:08:20 2022 +0300
@@ -107,20 +107,9 @@
 		result += "0 BFC INVERTNEXT\r\n";
 	}
 	result += utility::format(
-		"1 %1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14",
+		"1 %1 %2 %3",
 		this->colorIndex.index,
-		this->transformation[3][0],
-		this->transformation[3][1],
-		this->transformation[3][2],
-		this->transformation[0][0],
-		this->transformation[1][0],
-		this->transformation[2][0],
-		this->transformation[0][1],
-		this->transformation[1][1],
-		this->transformation[2][1],
-		this->transformation[0][2],
-		this->transformation[1][2],
-		this->transformation[2][2],
+		this->transformToBareString(),
 		this->referenceName);
 	return result;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tools/circletool.cpp	Thu Apr 14 11:08:20 2022 +0300
@@ -0,0 +1,34 @@
+#include "circletool.h"
+
+CircleTool::CircleTool(Document *document) :
+	AbstractDrawTool{document}
+{
+}
+
+QString CircleTool::name() const
+{
+	return tr("Circle");
+}
+
+QString CircleTool::toolTip() const
+{
+	return tr("Draw circular primitives like circles or discs");
+}
+
+void CircleTool::overpaint(Canvas *canvas, QPainter *painter) const
+{
+	if (this->previewPolygon.size() >= 2)
+	{
+		canvas->drawWorldPolyline()
+	}
+}
+
+QString CircleTool::iconName() const
+{
+	return ":/icons/linetype-circularprimitive.png";
+}
+
+void CircleTool::closeShape()
+{
+	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tools/circletool.h	Thu Apr 14 11:08:20 2022 +0300
@@ -0,0 +1,14 @@
+#pragma once
+#include "drawtool.h"
+
+class CircleTool : public AbstractDrawTool
+{
+	Q_OBJECT
+public:
+	Q_INVOKABLE CircleTool(Document* document);
+	QString name() const override;
+	QString toolTip() const override;
+	void overpaint(Canvas *canvas, QPainter *painter) const override;
+	QString iconName() const override;
+	void closeShape() override;
+};

mercurial