diff --git a/src/polygon.cpp b/src/polygon.cpp index 59bca0b..3712627 100644 --- a/src/polygon.cpp +++ b/src/polygon.cpp @@ -47,6 +47,17 @@ void STriangle::FlipNormal() { swap(an, bn); } +STriangle STriangle::Transform(Vector u, Vector v, Vector n) const { + STriangle tr = *this; + tr.a = tr.a.ScaleOutOfCsys(u, v, n); + tr.an = tr.an.ScaleOutOfCsys(u, v, n); + tr.b = tr.b.ScaleOutOfCsys(u, v, n); + tr.bn = tr.bn.ScaleOutOfCsys(u, v, n); + tr.c = tr.c.ScaleOutOfCsys(u, v, n); + tr.cn = tr.cn.ScaleOutOfCsys(u, v, n); + return tr; +} + STriangle STriangle::From(STriMeta meta, Vector a, Vector b, Vector c) { STriangle tr = {}; tr.meta = meta; @@ -620,7 +631,7 @@ void SPolygon::MakeEdgesInto(SEdgeList *el) const { } } -Vector SPolygon::ComputeNormal() { +Vector SPolygon::ComputeNormal() const { if(l.n < 1) return Vector::From(0, 0, 0); return (l.elem[0]).ComputeNormal(); } @@ -717,6 +728,17 @@ bool SPolygon::SelfIntersecting(Vector *intersectsAt) const { return ret; } +void SPolygon::InverseTransformInto(SPolygon *sp, Vector u, Vector v, Vector n) const { + for(const SContour &sc : l) { + SContour tsc = {}; + tsc.timesEnclosed = sc.timesEnclosed; + for(const SPoint &sp : sc.l) { + tsc.AddPoint(sp.p.DotInToCsys(u, v, n)); + } + sp->l.Add(&tsc); + } +} + //----------------------------------------------------------------------------- // Low-quality routines to cutter radius compensate a polygon. Assumes the // polygon is in the xy plane, and the contours all go in the right direction diff --git a/src/polygon.h b/src/polygon.h index 9b58ff6..c02d643 100644 --- a/src/polygon.h +++ b/src/polygon.h @@ -147,7 +147,7 @@ public: List l; Vector normal; - Vector ComputeNormal(); + Vector ComputeNormal() const; void AddEmptyContour(); int WindingNumberForPoint(Vector p) const; double SignedArea() const; @@ -161,6 +161,8 @@ public: void OffsetInto(SPolygon *dest, double r) const; void UvTriangulateInto(SMesh *m, SSurface *srf); void UvGridTriangulateInto(SMesh *m, SSurface *srf); + void TriangulateInto(SMesh *m) const; + void InverseTransformInto(SPolygon *sp, Vector u, Vector v, Vector n) const; }; class STriangle { @@ -185,6 +187,7 @@ public: int WindingNumberForPoint(Vector p) const; bool ContainsPoint(Vector p) const; bool ContainsPointProjd(Vector n, Vector p) const; + STriangle Transform(Vector o, Vector u, Vector v) const; }; class SBsp2 { diff --git a/src/srf/triangulate.cpp b/src/srf/triangulate.cpp index 316dd3f..c5faa5e 100644 --- a/src/srf/triangulate.cpp +++ b/src/srf/triangulate.cpp @@ -502,4 +502,27 @@ void SPolygon::UvGridTriangulateInto(SMesh *mesh, SSurface *srf) { UvTriangulateInto(mesh, srf); } +void SPolygon::TriangulateInto(SMesh *m) const { + Vector n = normal; + if(n.Equals(Vector::From(0.0, 0.0, 0.0))) { + n = ComputeNormal(); + } + Vector u = n.Normal(0); + Vector v = n.Normal(1); + SPolygon p = {}; + this->InverseTransformInto(&p, u, v, n); + + SSurface srf = SSurface::FromPlane(Vector::From(0.0, 0.0, 0.0), + Vector::From(1.0, 0.0, 0.0), + Vector::From(0.0, 1.0, 0.0)); + SMesh pm = {}; + p.UvTriangulateInto(&pm, &srf); + for(STriangle st : pm.l) { + st = st.Transform(u, v, n); + m->AddTriangle(&st); + } + + p.Clear(); + pm.Clear(); +}