diff --git a/examples/stl_to_sdf_evaluation/main.go b/examples/stl_to_sdf_evaluation/main.go new file mode 100644 index 000000000..87e0ad825 --- /dev/null +++ b/examples/stl_to_sdf_evaluation/main.go @@ -0,0 +1,26 @@ +package main + +import ( + "fmt" + "log" + + "github.com/deadsy/sdfx/obj" + v3 "github.com/deadsy/sdfx/vec/v3" +) + +func main() { + // create the SDF from the STL file mesh. + inSdf, err := obj.ImportSTL("../../files/teapot.stl", 20, 3, 5) + if err != nil { + log.Fatalf("error: %s", err) + } + + // This point is definitely inside the teapot model, + // so SDF value should be negative. + value := inSdf.Evaluate(v3.Vec{X: -0.8164382918936324, Y: 2.542909114087213, Z: 5.006102143191411}) + if value >= 0 { + fmt.Println("not expected") + } else { + fmt.Println("as expected") + } +} diff --git a/obj/stl.go b/obj/stl.go index 0dcc36e8a..e4d44718b 100644 --- a/obj/stl.go +++ b/obj/stl.go @@ -29,6 +29,7 @@ type triMeshSdf struct { rtree *rtreego.Rtree numNeighbors int bb sdf.Box3 + numTriangles int } const stlEpsilon = 1e-1 @@ -37,8 +38,13 @@ func (t *triMeshSdf) Evaluate(p v3.Vec) float64 { // Check all triangle distances signedDistanceResult := 1. closestTriangle := math.MaxFloat64 + + // The max possible neighbor count is number of triangles. + neighborCount := t.numTriangles + // Quickly skip checking most triangles by only checking the N closest neighbours (AABB based) - neighbors := t.rtree.NearestNeighbors(t.numNeighbors, v3ToPoint(p)) + neighbors := t.rtree.NearestNeighbors(neighborCount, v3ToPoint(p)) + for _, neighbor := range neighbors { triangle := neighbor.(*sdf.Triangle3) testPointToTriangle := p.Sub(triangle[0]) @@ -51,6 +57,11 @@ func (t *triMeshSdf) Evaluate(p v3.Vec) float64 { signedDistanceResult = signedDistanceToTriPlane } } + + // Does the approach of this paper make sense: + // https://www2.imm.dtu.dk/pubdb/edoc/imm1289.pdf + // TODO: If so, try to implement it in the future. + return signedDistanceResult } @@ -85,6 +96,7 @@ func ImportTriMesh(mesh []*sdf.Triangle3, numNeighbors, minChildren, maxChildren rtree: rtreego.NewTree(3, minChildren, maxChildren, bulkLoad...), numNeighbors: numNeighbors, bb: bb, + numTriangles: len(mesh), } }