From 6e886af7ea7f5bad0c5100683018ecb942fd03a7 Mon Sep 17 00:00:00 2001 From: soypat Date: Thu, 12 May 2022 15:59:29 -0300 Subject: [PATCH] refactor Triangle3 data type --- go.mod | 1 + render/3mf.go | 2 +- render/internal_test.go | 6 +++--- render/kdrender.go | 40 +++++++++++++++++++--------------------- render/marchingcubes.go | 8 +++----- render/render.go | 14 ++++++-------- render/stl.go | 40 ++++++++++++++++++++-------------------- 7 files changed, 53 insertions(+), 58 deletions(-) diff --git a/go.mod b/go.mod index bb11fbc..c402d7b 100644 --- a/go.mod +++ b/go.mod @@ -23,3 +23,4 @@ require ( golang.org/x/image v0.0.0-20220302094943-723b81ca9867 // indirect rsc.io/pdf v0.1.1 // indirect ) + diff --git a/render/3mf.go b/render/3mf.go index 08524cb..670dd45 100644 --- a/render/3mf.go +++ b/render/3mf.go @@ -120,7 +120,7 @@ func (m *model) AddObject(name string, src []Triangle3) error { vertices := make([]mf3Vertex, 0, len(src)*3) for it, t := range src { for i := 0; i < 3; i++ { - vertex := t.V[i] + vertex := t[i] entry, ok := vertexMap[vertex] if !ok { entry = vertexEntry{ diff --git a/render/internal_test.go b/render/internal_test.go index 3200cc8..12f8ef0 100644 --- a/render/internal_test.go +++ b/render/internal_test.go @@ -60,10 +60,10 @@ func TestSTLWriteReadback(t *testing.T) { if got.Degenerate(1e-12) { t.Fatalf("triangle degenerate: %+v", got) } - for i := range expect.V { - if !d3.EqualWithin(got.V[i], expect.V[i], rtol) { + for i := range expect { + if !d3.EqualWithin(got[i], expect[i], rtol) { mismatches++ - t.Errorf("%dth triangle equality out of tolerance. got vertex %0.5g, want %0.5g", iface, got.V[i], expect.V[i]) + t.Errorf("%dth triangle equality out of tolerance. got vertex %0.5g, want %0.5g", iface, got[i], expect[i]) } } if mismatches > 10 { diff --git a/render/kdrender.go b/render/kdrender.go index fa7ef9b..c4a4ed6 100644 --- a/render/kdrender.go +++ b/render/kdrender.go @@ -48,9 +48,9 @@ func (s kdSDF) Evaluate(v r3.Vec) float64 { // Find closest vertex closest := r3.Vec{} for i := 0; i < 3; i++ { - vDist := r3.Norm(r3.Sub(v, triangle.V[i])) + vDist := r3.Norm(r3.Sub(v, triangle[i])) if vDist < minDist { - closest = triangle.V[i] + closest = triangle[i] minDist = vDist } } @@ -65,9 +65,7 @@ func (s kdSDF) Evaluate(v r3.Vec) float64 { // Get nearest triangle to point. func (s kdSDF) Nearest(v r3.Vec) kdTriangle { - got, _ := s.tree.Nearest(kdTriangle{ - V: [3]r3.Vec{v, v, v}, - }) + got, _ := s.tree.Nearest(kdTriangle{v, v, v}) // do some ad-hoc math with the triangle normal ???? return got.(kdTriangle) } @@ -80,8 +78,8 @@ func (s kdSDF) Bounds() r3.Box { tMin := bb.Min.(kdTriangle) tMax := bb.Max.(kdTriangle) return r3.Box{ - Min: d3.MinElem(tMin.V[2], d3.MinElem(tMin.V[0], tMin.V[1])), - Max: d3.MaxElem(tMax.V[2], d3.MaxElem(tMax.V[0], tMax.V[1])), + Min: d3.MinElem(tMin[2], d3.MinElem(tMin[0], tMin[1])), + Max: d3.MaxElem(tMax[2], d3.MaxElem(tMax[0], tMax[1])), } } @@ -116,12 +114,12 @@ func (k kdTriangles) Bounds() *kdtree.Bounding { tbounds := tri.Bounds() tmin := tbounds.Min.(kdTriangle) tmax := tbounds.Max.(kdTriangle) - min = d3.MinElem(min, tmin.V[0]) - max = d3.MaxElem(max, tmax.V[0]) + min = d3.MinElem(min, tmin[0]) + max = d3.MaxElem(max, tmax[0]) } return &kdtree.Bounding{ - Min: kdTriangle{V: [3]r3.Vec{min, min, min}}, - Max: kdTriangle{V: [3]r3.Vec{max, max, max}}, + Min: kdTriangle{min, min, min}, + Max: kdTriangle{max, max, max}, } } @@ -146,11 +144,11 @@ func (a kdTriangle) Distance(b kdtree.Comparable) float64 { } func (a kdTriangle) Bounds() *kdtree.Bounding { - min := d3.MinElem(a.V[2], d3.MinElem(a.V[0], a.V[1])) - max := d3.MaxElem(a.V[2], d3.MaxElem(a.V[0], a.V[1])) + min := d3.MinElem(a[2], d3.MinElem(a[0], a[1])) + max := d3.MaxElem(a[2], d3.MaxElem(a[0], a[1])) return &kdtree.Bounding{ - Min: kdTriangle{V: [3]r3.Vec{min, min, min}}, - Max: kdTriangle{V: [3]r3.Vec{max, max, max}}, + Min: kdTriangle{min, min, min}, + Max: kdTriangle{max, max, max}, } } @@ -163,11 +161,11 @@ func (a kdTriangle) Normal() r3.Vec { func kdComp(a, b kdTriangle, dim int) (c float64) { switch dim { case 0: - c = (a.V[0].X + a.V[1].X + a.V[2].X) - (b.V[0].X + b.V[1].X + b.V[2].X) + c = (a[0].X + a[1].X + a[2].X) - (b[0].X + b[1].X + b[2].X) case 1: - c = (a.V[0].Y + a.V[1].Y + a.V[2].Y) - (b.V[0].Y + b.V[1].Y + b.V[2].Y) + c = (a[0].Y + a[1].Y + a[2].Y) - (b[0].Y + b[1].Y + b[2].Y) case 2: - c = (a.V[0].Z + a.V[1].Z + a.V[2].Z) - (b.V[0].Z + b.V[1].Z + b.V[2].Z) + c = (a[0].Z + a[1].Z + a[2].Z) - (b[0].Z + b[1].Z + b[2].Z) } return c / 3 } @@ -181,9 +179,9 @@ func kdDist(a, b kdTriangle) (c float64) { func kdCentroid(a kdTriangle) r3.Vec { v := r3.Vec{ - X: a.V[0].X + a.V[1].X + a.V[2].X, - Y: a.V[0].Y + a.V[1].Y + a.V[2].Y, - Z: a.V[0].Z + a.V[1].Z + a.V[2].Z, + X: a[0].X + a[1].X + a[2].X, + Y: a[0].Y + a[1].Y + a[2].Y, + Z: a[0].Z + a[1].Z + a[2].Z, } return r3.Scale(1./3., v) } diff --git a/render/marchingcubes.go b/render/marchingcubes.go index 659c73e..83f657f 100644 --- a/render/marchingcubes.go +++ b/render/marchingcubes.go @@ -41,11 +41,9 @@ func mcToTriangles(dst []Triangle3, p [8]r3.Vec, v [8]float64, x float64) (n int count := len(table) / 3 // max count is 5, a.k.a marchingCubesMaxTriangles for i := 0; i < count; i++ { t := Triangle3{ - V: [3]r3.Vec{ - points[table[i*3+2]], - points[table[i*3+1]], - points[table[i*3+0]], - }, + points[table[i*3+2]], + points[table[i*3+1]], + points[table[i*3+0]], } if !t.Degenerate(1e-12) { dst[n] = t diff --git a/render/render.go b/render/render.go index fdd67c9..594ad54 100644 --- a/render/render.go +++ b/render/render.go @@ -14,14 +14,12 @@ type Renderer interface { type Triangle2 [3]r2.Vec // Triangle3 is a 3D triangle -type Triangle3 struct { - V [3]r3.Vec -} +type Triangle3 [3]r3.Vec // Normal returns the normal vector to the plane defined by the 3D triangle. func (t *Triangle3) Normal() r3.Vec { - e1 := t.V[1].Sub(t.V[0]) - e2 := t.V[2].Sub(t.V[0]) + e1 := t[1].Sub(t[0]) + e2 := t[2].Sub(t[0]) return r3.Unit(r3.Cross(e1, e2)) } @@ -30,7 +28,7 @@ func (t *Triangle3) Normal() r3.Vec { func (t *Triangle3) Degenerate(tolerance float64) bool { // check for identical vertices. // TODO more tests needed. - return d3.EqualWithin(t.V[0], t.V[1], tolerance) || - d3.EqualWithin(t.V[1], t.V[2], tolerance) || - d3.EqualWithin(t.V[2], t.V[0], tolerance) + return d3.EqualWithin(t[0], t[1], tolerance) || + d3.EqualWithin(t[1], t[2], tolerance) || + d3.EqualWithin(t[2], t[0], tolerance) } diff --git a/render/stl.go b/render/stl.go index b2e2fa8..c27816e 100644 --- a/render/stl.go +++ b/render/stl.go @@ -46,15 +46,15 @@ func WriteSTL(w io.Writer, model []Triangle3) error { d.Normal[0] = float32(n.X) d.Normal[1] = float32(n.Y) d.Normal[2] = float32(n.Z) - d.Vertex1[0] = float32(triangle.V[0].X) - d.Vertex1[1] = float32(triangle.V[0].Y) - d.Vertex1[2] = float32(triangle.V[0].Z) - d.Vertex2[0] = float32(triangle.V[1].X) - d.Vertex2[1] = float32(triangle.V[1].Y) - d.Vertex2[2] = float32(triangle.V[1].Z) - d.Vertex3[0] = float32(triangle.V[2].X) - d.Vertex3[1] = float32(triangle.V[2].Y) - d.Vertex3[2] = float32(triangle.V[2].Z) + d.Vertex1[0] = float32(triangle[0].X) + d.Vertex1[1] = float32(triangle[0].Y) + d.Vertex1[2] = float32(triangle[0].Z) + d.Vertex2[0] = float32(triangle[1].X) + d.Vertex2[1] = float32(triangle[1].Y) + d.Vertex2[2] = float32(triangle[1].Z) + d.Vertex3[0] = float32(triangle[2].X) + d.Vertex3[1] = float32(triangle[2].Y) + d.Vertex3[2] = float32(triangle[2].Z) d.put(b[:]) _, err := io.Copy(w, bytes.NewReader(b[:])) if err != nil { @@ -112,15 +112,15 @@ func (w *stlReader) Read(b []byte) (int, error) { d.Normal[0] = float32(n.X) d.Normal[1] = float32(n.Y) d.Normal[2] = float32(n.Z) - d.Vertex1[0] = float32(triangle.V[0].X) - d.Vertex1[1] = float32(triangle.V[0].Y) - d.Vertex1[2] = float32(triangle.V[0].Z) - d.Vertex2[0] = float32(triangle.V[1].X) - d.Vertex2[1] = float32(triangle.V[1].Y) - d.Vertex2[2] = float32(triangle.V[1].Z) - d.Vertex3[0] = float32(triangle.V[2].X) - d.Vertex3[1] = float32(triangle.V[2].Y) - d.Vertex3[2] = float32(triangle.V[2].Z) + d.Vertex1[0] = float32(triangle[0].X) + d.Vertex1[1] = float32(triangle[0].Y) + d.Vertex1[2] = float32(triangle[0].Z) + d.Vertex2[0] = float32(triangle[1].X) + d.Vertex2[1] = float32(triangle[1].Y) + d.Vertex2[2] = float32(triangle[1].Z) + d.Vertex3[0] = float32(triangle[2].X) + d.Vertex3[1] = float32(triangle[2].Y) + d.Vertex3[2] = float32(triangle[2].Z) d.put(b[it*stlTriangleSize:]) it++ } @@ -327,9 +327,9 @@ func equalWithin3F32(a, b [3]float32, tol float32) bool { } func (d stlTriangle) toTriangle3() Triangle3 { - return Triangle3{V: [3]r3.Vec{ + return Triangle3{ r3From3F32(d.Vertex1), r3From3F32(d.Vertex2), r3From3F32(d.Vertex3), - }} + } }