src/linetypes/modelobject.h

changeset 1147
a26568aa3cce
parent 1141
7dc2c981937e
child 1148
96cb15a7611f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/linetypes/modelobject.h	Tue Feb 14 14:59:26 2017 +0200
@@ -0,0 +1,351 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013 - 2017 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/>.
+ */
+
+#pragma once
+#include <type_traits>
+#include "../main.h"
+#include "../basics.h"
+#include "../glShared.h"
+#include "../colors.h"
+
+class Model;
+class LDDocument;
+
+/*
+ * Object type codes.
+ */
+enum LDObjectType
+{
+	SubfileReference,	//	Object represents a	sub-file reference
+	Quadrilateral,		//	Object represents a	quadrilateral
+	Triangle,			//	Object represents a	triangle
+	EdgeLine,			//	Object represents a	line
+	ConditionalEdge,	//	Object represents a	conditional line
+	Bfc,				//	Object represents a	BFC statement
+	Comment,			//	Object represents a	comment
+	Error,				//	Object is the result of failed parsing
+	Empty,				//	Object represents an empty line
+	BezierCurve,		//	Object represents a Bézier curve
+	_End
+};
+
+MAKE_ITERABLE_ENUM(LDObjectType)
+
+/*
+ * Represents one line of code in an LDraw model file.
+ */
+class LDObject : public QObject
+{
+	Q_OBJECT
+
+public:
+	virtual QString asText() const = 0; // This object as LDraw code
+	LDColor color() const;
+	virtual LDColor defaultColor() const; // What color does the object default to?
+	Model* model() const;
+	LDPolygon* getPolygon();
+	virtual void getVertices (QSet<Vertex>& verts) const;
+	virtual bool hasMatrix() const; // Does this object have a matrix and position? (see LDMatrixObject)
+	qint32 id() const;
+	virtual void invert(); // Inverts this object (winding is reversed)
+	virtual bool isColored() const;
+	bool isHidden() const;
+	virtual bool isScemantic() const; // Does this object have meaning in the part model?
+	bool isSelected() const;
+	int lineNumber() const;
+	void move (Vertex vect);
+	LDObject* next() const;
+	virtual int numVertices() const;
+	virtual QString objectListText() const;
+	LDObject* previous() const;
+	bool previousIsInvertnext(class LDBfc*& ptr);
+	QColor randomColor() const;
+	void setColor (LDColor color);
+	void setHidden (bool value);
+	void setVertex (int i, const Vertex& vert);
+	void swap (LDObject* other);
+	virtual int triangleCount() const;
+	virtual LDObjectType type() const = 0;
+	virtual QString typeName() const = 0;
+	const Vertex& vertex (int i) const;
+
+	static LDObject* fromID(qint32 id);
+
+signals:
+	void codeChanged(QString before, QString after);
+
+protected:
+	friend class Model;
+	LDObject (Model* model = nullptr);
+	virtual ~LDObject();
+	void setDocument(Model* model);
+
+	template<typename T>
+	void changeProperty(T* property, const T& value);
+
+private:
+	bool m_isHidden;
+	bool m_isSelected;
+	Model* _model;
+	qint32 m_id;
+	LDColor m_color;
+	QColor m_randomColor;
+	Vertex m_coords[4];
+};
+
+/*
+ * Base class for objects with matrices.
+ */
+class LDMatrixObject : public LDObject
+{
+	Vertex m_position;
+
+public:
+	const Vertex& position() const;
+	void setCoordinate (const Axis ax, double value);
+	void setPosition (const Vertex& a);
+	void setTransformationMatrix (const Matrix& value);
+	const Matrix& transformationMatrix() const;
+
+protected:
+	LDMatrixObject (Model* model = nullptr);
+	LDMatrixObject (const Matrix& transformationMatrix, const Vertex& pos, Model* model = nullptr);
+
+private:
+	Matrix m_transformationMatrix;
+};
+
+/*
+ * Represents a line in the LDraw file that could not be properly parsed.
+ */
+class LDError : public LDObject
+{
+public:
+	static constexpr LDObjectType SubclassType = LDObjectType::Error;
+
+	virtual LDObjectType type() const override
+	{
+		return SubclassType;
+	}
+
+	virtual QString asText() const override;
+	virtual void invert() override;
+	QString reason() const;
+	QString contents() const;
+	QString fileReferenced() const;
+	void setFileReferenced (QString value);
+	QString objectListText() const override;
+	bool isColored() const override { return false; }
+	QString typeName() const override { return "error"; }
+
+protected:
+	friend class Model;
+	LDError (Model* model);
+	LDError (QString contents, QString reason, Model* model = nullptr);
+
+private:
+	QString m_fileReferenced; // If this error was caused by inability to open a file, what file was that?
+	QString m_contents; // The LDraw code that was being parsed
+	QString m_reason;
+};
+
+/*
+ * Represents a 0 BFC statement in the LDraw code.
+ */
+enum class BfcStatement
+{
+	CertifyCCW,
+	CCW,
+	CertifyCW,
+	CW,
+	NoCertify,
+	InvertNext,
+	Clip,
+	ClipCCW,
+	ClipCW,
+	NoClip,
+	_End
+};
+
+MAKE_ITERABLE_ENUM(BfcStatement)
+
+class LDBfc : public LDObject
+{
+	public:
+	static constexpr LDObjectType SubclassType = LDObjectType::Bfc;
+
+	virtual LDObjectType type() const override
+	{
+		return SubclassType;
+	}
+
+	virtual QString asText() const override;
+	virtual void invert() override;
+protected:
+	friend class Model;
+	LDBfc (Model* model);
+
+public:
+	bool isScemantic() const override { return statement() == BfcStatement::InvertNext; }
+    QString objectListText() const override;
+	BfcStatement statement() const;
+	void setStatement (BfcStatement value);
+	QString statementToString() const;
+	bool isColored() const override { return false; }
+	QString typeName() const override { return "bfc"; }
+
+	static QString statementToString (BfcStatement statement);
+
+protected:
+	LDBfc (const BfcStatement type, Model* model = nullptr);
+
+private:
+	BfcStatement m_statement;
+};
+
+/*
+ * Represents a single code-1 subfile reference.
+ */
+class LDSubfileReference : public LDMatrixObject
+{
+public:
+	static constexpr LDObjectType SubclassType = LDObjectType::SubfileReference;
+
+	virtual LDObjectType type() const override
+	{
+		return SubclassType;
+	}
+
+	virtual QString asText() const override;
+	virtual void invert() override;
+	LDDocument* fileInfo() const;
+	virtual void getVertices (QSet<Vertex>& verts) const override;
+	void inlineContents(Model& model, bool deep, bool render);
+	QList<LDPolygon> inlinePolygons();
+	QString objectListText() const override;
+	void setFileInfo (LDDocument* fileInfo);
+	int triangleCount() const override;
+	bool hasMatrix() const override { return true; }
+	QString typeName() const override { return "subfilereference"; }
+
+protected:
+	friend class Model;
+	LDSubfileReference (Model* model);
+	LDSubfileReference(LDDocument* reference, const Matrix& transformationMatrix, const Vertex& position, Model* model = nullptr);
+
+private:
+	LDDocument* m_fileInfo;
+};
+
+/*
+ * Represents a single code-3 triangle in the LDraw code file.
+ */
+class LDTriangle : public LDObject
+{
+public:
+	static constexpr LDObjectType SubclassType = LDObjectType::Triangle;
+
+	virtual LDObjectType type() const override
+	{
+		return SubclassType;
+	}
+
+	virtual QString asText() const override;
+	virtual void invert() override;
+	int triangleCount() const override;
+	int numVertices() const override { return 3; }
+	QString typeName() const override { return "triangle"; }
+
+protected:
+	friend class Model;
+	LDTriangle (Model* model);
+	LDTriangle (Vertex const& v1, Vertex const& v2, Vertex const& v3, Model* model = nullptr);
+};
+
+/*
+ * Represents a single code-4 quadrilateral.
+ */
+class LDQuadrilateral : public LDObject
+{
+public:
+	static constexpr LDObjectType SubclassType = LDObjectType::Quadrilateral;
+
+	virtual LDObjectType type() const override
+	{
+		return SubclassType;
+	}
+
+	QString asText() const override;
+	void invert() override;
+	int triangleCount() const override;
+	int numVertices() const override { return 4; }
+	QString typeName() const override { return "quad"; }
+
+protected:
+	friend class Model;
+	LDQuadrilateral (Model* model);
+	LDQuadrilateral (const Vertex& v1, const Vertex& v2, const Vertex& v3, const Vertex& v4, Model* model = nullptr);
+};
+
+/*
+ * Models a Bézier curve. It is stored as a special comment in the LDraw code file and can be inlined down into line segments.
+ */
+class LDBezierCurve : public LDObject
+{
+public:
+	static constexpr LDObjectType SubclassType = LDObjectType::BezierCurve;
+
+	virtual LDObjectType type() const override
+	{
+		return SubclassType;
+	}
+
+	virtual QString asText() const override;
+	virtual void invert() override;
+	Vertex pointAt (qreal t) const;
+	void rasterize(Model& model, int segments);
+	QVector<LDPolygon> rasterizePolygons (int segments);
+	int numVertices() const override { return 4; }
+	LDColor defaultColor() const override { return EdgeColor; }
+	QString typeName() const override { return "beziercurve"; }
+
+protected:
+	friend class Model;
+	LDBezierCurve (Model* model);
+	LDBezierCurve (const Vertex& v0, const Vertex& v1, const Vertex& v2, const Vertex& v3, Model* model = nullptr);
+};
+
+enum
+{
+	LowResolution = 16,
+	HighResolution = 48
+};
+
+/*
+ * Changes a property in a manner that emits the appropriate signal to notify that the object changed.
+ */
+template<typename T>
+void LDObject::changeProperty(T* property, const T& value)
+{
+	if (*property != value)
+	{
+		QString before = asText();
+		*property = value;
+		emit codeChanged(before, asText());
+	}
+}

mercurial