Mon, 19 Mar 2018 12:24:59 +0200
Bfc red/green view almost completely fixed
--- a/src/algorithms/invert.cpp Mon Mar 19 11:04:18 2018 +0200 +++ b/src/algorithms/invert.cpp Mon Mar 19 12:24:59 2018 +0200 @@ -128,3 +128,18 @@ } } } + +void invertPolygon(LDPolygon& polygon) +{ + switch (polygon.numPolygonVertices()) + { + case 2: + case 3: + std::swap(polygon.vertices[0], polygon.vertices[1]); + break; + + case 4: + std::swap(polygon.vertices[1], polygon.vertices[3]); + break; + } +}
--- a/src/algorithms/invert.h Mon Mar 19 11:04:18 2018 +0200 +++ b/src/algorithms/invert.h Mon Mar 19 12:24:59 2018 +0200 @@ -22,3 +22,4 @@ bool isflat(class Model* model, Axis* axis); Matrix flipmatrix(Axis axis); void invert(LDObject* obj, class DocumentManager* context); +void invertPolygon(LDPolygon& polygon);
--- a/src/basics.cpp Mon Mar 19 11:04:18 2018 +0200 +++ b/src/basics.cpp Mon Mar 19 12:24:59 2018 +0200 @@ -360,3 +360,21 @@ return 0; } } + +/* + * Special operator definition that implements the XOR operator for windings. + * However, if either winding is NoWinding, then this function returns NoWinding. + */ +Winding operator^(Winding one, Winding other) +{ + if (one == NoWinding or other == NoWinding) + return NoWinding; + else + return static_cast<Winding>(static_cast<int>(one) ^ static_cast<int>(other)); +} + +Winding& operator^=(Winding& one, Winding other) +{ + one = one ^ other; + return one; +}
--- a/src/basics.h Mon Mar 19 11:04:18 2018 +0200 +++ b/src/basics.h Mon Mar 19 12:24:59 2018 +0200 @@ -44,6 +44,16 @@ Z }; +enum Winding +{ + NoWinding, + CounterClockwise, + Clockwise, +}; + +Winding operator^(Winding one, Winding other); +Winding& operator^=(Winding& one, Winding other); + // // Derivative of QVector3D: this class is used for the vertices. //
--- a/src/glShared.h Mon Mar 19 11:04:18 2018 +0200 +++ b/src/glShared.h Mon Mar 19 12:24:59 2018 +0200 @@ -40,6 +40,11 @@ Vertex vertices[4]; int color; + inline int numPolygonVertices() const + { + return (num == 5) ? 2 : num; + } + inline int numVertices() const { return (num == 5) ? 4 : num;
--- a/src/glcompiler.cpp Mon Mar 19 11:04:18 2018 +0200 +++ b/src/glcompiler.cpp Mon Mar 19 12:24:59 2018 +0200 @@ -375,7 +375,8 @@ case LDObjectType::SubfileReference: { LDSubfileReference* subfileReference = static_cast<LDSubfileReference*>(object); - auto data = subfileReference->inlinePolygons(m_documents); + // TODO: move winding to Model and use it here + auto data = subfileReference->inlinePolygons(m_documents, CounterClockwise); for (LDPolygon& poly : data) compilePolygon (poly, index, info);
--- a/src/lddocument.cpp Mon Mar 19 11:04:18 2018 +0200 +++ b/src/lddocument.cpp Mon Mar 19 12:24:59 2018 +0200 @@ -529,7 +529,13 @@ if (deep and object->type() == LDObjectType::SubfileReference) { LDSubfileReference* reference = static_cast<LDSubfileReference*>(object); - reference->inlineContents(documentManager(), model, deep, renderinline); + reference->inlineContents( + documentManager(), + this->header.winding, + model, + deep, + renderinline + ); } else { @@ -568,15 +574,3 @@ { m_verticesOutdated = true; } - -/* - * Special operator definition that implements the XOR operator for windings. - * However, if either winding is NoWinding, then this function returns NoWinding. - */ -Winding operator^(Winding one, Winding other) -{ - if (one == NoWinding or other == NoWinding) - return NoWinding; - else - return static_cast<Winding>(static_cast<int>(one) ^ static_cast<int>(other)); -}
--- a/src/lddocument.h Mon Mar 19 11:04:18 2018 +0200 +++ b/src/lddocument.h Mon Mar 19 12:24:59 2018 +0200 @@ -28,13 +28,6 @@ struct LDGLData; class DocumentManager; -enum Winding -{ - NoWinding, - CounterClockwise, - Clockwise, -}; - struct LDHeader { struct HistoryEntry @@ -79,7 +72,6 @@ }; Q_DECLARE_OPERATORS_FOR_FLAGS(QFlags<LDHeader::Qualifier>) -Winding operator^(Winding one, Winding other); // // This class stores a document either as a editable file for the user or for
--- a/src/linetypes/modelobject.cpp Mon Mar 19 11:04:18 2018 +0200 +++ b/src/linetypes/modelobject.cpp Mon Mar 19 12:24:59 2018 +0200 @@ -26,6 +26,7 @@ #include "../canvas.h" #include "../colors.h" #include "../glcompiler.h" +#include "../algorithms/invert.h" #include "edgeline.h" #include "triangle.h" #include "quadrilateral.h" @@ -154,16 +155,35 @@ obj->setColor (parentcolor); } +bool shouldInvert(LDSubfileReference* reference, Winding winding, DocumentManager* context) +{ + bool result = false; + result ^= (reference->isInverted()); + result ^= (reference->transformationMatrix().determinant() < 0); + result ^= (reference->fileInfo(context)->header.winding != winding); + return result; +} + // ============================================================================= // ----------------------------------------------------------------------------- -void LDSubfileReference::inlineContents(DocumentManager* context, Model& model, bool deep, bool render) -{ +void LDSubfileReference::inlineContents( + DocumentManager* context, + Winding parentWinding, + Model& model, + bool deep, + bool render +) { Model inlined {context}; fileInfo(context)->inlineContents(inlined, deep, render); // Transform the objects for (LDObject* object : inlined) + { + if (::shouldInvert(this, parentWinding, context)) + ::invert(object, context); + TransformObject(object, transformationMatrix(), position(), color()); + } model.merge(inlined); } @@ -214,7 +234,7 @@ // ============================================================================= // -QList<LDPolygon> LDSubfileReference::inlinePolygons(DocumentManager* context) +QList<LDPolygon> LDSubfileReference::inlinePolygons(DocumentManager* context, Winding parentWinding) { LDDocument* file = fileInfo(context); @@ -226,6 +246,9 @@ { for (int i = 0; i < entry.numVertices(); ++i) entry.vertices[i].transform (transformationMatrix(), position()); + + if (::shouldInvert(this, parentWinding, context)) + ::invertPolygon(entry); } return data;
--- a/src/linetypes/modelobject.h Mon Mar 19 11:04:18 2018 +0200 +++ b/src/linetypes/modelobject.h Mon Mar 19 12:24:59 2018 +0200 @@ -222,8 +222,14 @@ virtual QString asText() const override; LDDocument* fileInfo(DocumentManager *context) const; virtual void getVertices(DocumentManager *context, QSet<Vertex>& verts) const override; - void inlineContents(DocumentManager* context, Model& model, bool deep, bool render); - QList<LDPolygon> inlinePolygons(DocumentManager* context); + void inlineContents( + DocumentManager* context, + Winding parentWinding, + Model& model, + bool deep, + bool render + ); + QList<LDPolygon> inlinePolygons(DocumentManager* context, Winding parentWinding); QString objectListText() const override; QString referenceName() const; int triangleCount(DocumentManager *context) const override;
--- a/src/toolsets/basictoolset.cpp Mon Mar 19 11:04:18 2018 +0200 +++ b/src/toolsets/basictoolset.cpp Mon Mar 19 12:24:59 2018 +0200 @@ -114,7 +114,13 @@ if (referenceIndex.isValid()) { Model inlined {m_documents}; - reference->inlineContents(m_documents, inlined, deep, false); + reference->inlineContents( + m_documents, + currentDocument()->header.winding, + inlined, + deep, + false + ); // Merge in the inlined objects for (LDObject* inlinedObject : inlined.objects())
--- a/src/toolsets/extprogramtoolset.cpp Mon Mar 19 11:04:18 2018 +0200 +++ b/src/toolsets/extprogramtoolset.cpp Mon Mar 19 12:24:59 2018 +0200 @@ -157,7 +157,7 @@ { LDSubfileReference* ref = static_cast<LDSubfileReference*> (obj); Model model {m_documents}; - ref->inlineContents(m_documents, model, true, false); + ref->inlineContents(m_documents, CounterClockwise, model, true, false); writeObjects(model.objects(), f); } else if (obj->type() == LDObjectType::BezierCurve)