Skip to content

Commit 91f536a

Browse files
authored
SDF fixes (#126)
* SDF bug fixes * minor perf improvements
1 parent 78fc3dd commit 91f536a

File tree

16 files changed

+693
-507
lines changed

16 files changed

+693
-507
lines changed

generator/edit/examples/shapurr.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

generator/edit/html/server.html

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,22 @@
8080
z-index: 1;
8181
}
8282

83+
#running-message {
84+
display: none;
85+
position: absolute;
86+
right: 20px;
87+
bottom: 20px;
88+
padding: 10px;
89+
box-sizing: border-box;
90+
text-align: center;
91+
-moz-user-select: none;
92+
-webkit-user-select: none;
93+
-ms-user-select: none;
94+
user-select: none;
95+
pointer-events: none;
96+
z-index: 1;
97+
}
98+
8399
#messageContainer {
84100
position: absolute;
85101
left: 0px;
@@ -433,6 +449,9 @@
433449
<div id="watermark">
434450
<a href="https://github.com/EliCDavis/polyform">Polyform</a>
435451
</div>
452+
<div id="running-message">
453+
Running...
454+
</div>
436455

437456
<div id="messageContainer">
438457
<div id="infoMessage"> </div>

math/sdf/art.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package sdf
2+
3+
import (
4+
"github.com/EliCDavis/polyform/math/sample"
5+
"github.com/EliCDavis/vector/vector3"
6+
)
7+
8+
// func displacementExample(p vector3.Float64) float64 {
9+
// return math.Sin(20*p.X()) * math.Sin(20*p.Y()) * math.Sin(20*p.Z())
10+
// }
11+
12+
func Displace(primitive, displacement sample.Vec3ToFloat, p vector3.Float64) float64 {
13+
d1 := primitive(p)
14+
d2 := displacement(p)
15+
return d1 + d2
16+
}
17+
18+
// func opTwist(primitive sample.Vec3ToFloat, p vector3.Float64) float64 {
19+
// const k = 10.0 // or some other amount
20+
// c := math.Cos(k * p.Y())
21+
// s := math.Sin(k * p.Y())
22+
// m := math.mat2(c, -s, s, c)
23+
// q := vector3.New(m*p.xz, p.Y())
24+
// return primitive(q)
25+
// }
26+
27+
// func opCheapBend(primitive sample.Vec3ToFloat, p vector3.Float64) float64 {
28+
// const k = 10.0 // or some other amount
29+
// c := math.Cos(k * p.X())
30+
// s := math.Sin(k * p.X())
31+
// m := math.mat2(c, -s, s, c)
32+
// q := vector3.New(m*p.xy, p.Z())
33+
// return primitive(q)
34+
// }

math/sdf/line.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package sdf
22

33
import (
4-
"math"
5-
64
"github.com/EliCDavis/polyform/math/geometry"
75
"github.com/EliCDavis/polyform/math/sample"
86
"github.com/EliCDavis/polyform/nodes"
@@ -25,9 +23,7 @@ func MultipointLine(points []vector3.Float64, radius float64) sample.Vec3ToFloat
2523

2624
switch len(points) {
2725
case 0:
28-
return func(f vector3.Float64) float64 {
29-
return math.Inf(1)
30-
}
26+
return nullField
3127

3228
case 1:
3329
return Sphere(points[0], radius)

math/sdf/nodes.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ func init() {
1111

1212
refutil.RegisterType[nodes.Struct[TranslateNode]](factory)
1313
refutil.RegisterType[nodes.Struct[TransformNode]](factory)
14+
refutil.RegisterType[nodes.Struct[RepeatNode]](factory)
1415

1516
refutil.RegisterType[nodes.Struct[UnionNode]](factory)
1617
refutil.RegisterType[nodes.Struct[IntersectionNode]](factory)

math/sdf/repeat.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package sdf
2+
3+
import (
4+
"github.com/EliCDavis/polyform/math/sample"
5+
"github.com/EliCDavis/polyform/math/trs"
6+
"github.com/EliCDavis/polyform/nodes"
7+
"github.com/EliCDavis/vector/vector3"
8+
)
9+
10+
func Repeat(field sample.Vec3ToFloat, transforms []trs.TRS) sample.Vec3ToFloat {
11+
if len(transforms) == 0 {
12+
return nullField
13+
}
14+
15+
invertedTRS := make([]trs.TRS, len(transforms))
16+
for i, v := range transforms {
17+
invertedTRS[i] = trs.FromMatrix(v.Matrix().Inverse())
18+
}
19+
20+
return func(v vector3.Float64) float64 {
21+
closestPoint := field(invertedTRS[0].Transform(v))
22+
for i := 1; i < len(invertedTRS); i++ {
23+
closestPoint = min(closestPoint, field(invertedTRS[i].Transform(v)))
24+
}
25+
return closestPoint
26+
}
27+
}
28+
29+
type RepeatNode struct {
30+
Transforms nodes.Output[[]trs.TRS]
31+
Field nodes.Output[sample.Vec3ToFloat]
32+
}
33+
34+
func (cn RepeatNode) Result(out *nodes.StructOutput[sample.Vec3ToFloat]) {
35+
if cn.Field == nil {
36+
return
37+
}
38+
39+
out.Set(Repeat(
40+
nodes.GetOutputValue(out, cn.Field),
41+
nodes.TryGetOutputValue(out, cn.Transforms, []trs.TRS{trs.Identity()}),
42+
))
43+
}

math/sdf/translate.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ func (cn TranslateNode) Result(out *nodes.StructOutput[sample.Vec3ToFloat]) {
3232
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
3333

3434
func Transform(field sample.Vec3ToFloat, transformation trs.TRS) sample.Vec3ToFloat {
35+
inverse := transformation.Inverse()
3536
return func(v vector3.Float64) float64 {
36-
return field(transformation.Transform(v))
37+
return field(inverse.Transform(v))
3738
}
3839
}
3940

math/sdf/util.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package sdf
2+
3+
import (
4+
"math"
5+
6+
"github.com/EliCDavis/vector/vector3"
7+
)
8+
9+
// Field meant to represent "nothing".
10+
func nullField(f vector3.Float64) float64 {
11+
return math.Inf(1)
12+
}

math/trs/trs.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ func (trs TRS) Multiply(other TRS) TRS {
117117
return FromMatrix(trs.Matrix().Multiply(other.Matrix()))
118118
}
119119

120+
func (trs TRS) Inverse() TRS {
121+
return FromMatrix(trs.Matrix().Inverse())
122+
}
123+
120124
// Transform an array of points by the TRS
121125
func (trs TRS) TransformArray(in []vector3.Float64) []vector3.Float64 {
122126
out := make([]vector3.Float64, len(in))

modeling/marching/canvas.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ func interpolateV1(v1, v2, t float64) float64 {
3131

3232
func interpolateVerts(v1, v2 vector3.Float64, v1v, v2v, cutoff float64) vector3.Float64 {
3333
t := interpolationValueFromCutoff(v1v, v2v, cutoff)
34-
return v2.Sub(v1).Scale(t).Add(v1)
34+
// return v2.Sub(v1).Scale(t).Add(v1)
35+
return v1.Scale(1 - t).Add(v2.Scale(t))
3536
}
3637

3738
func lookupOrAdd(data *workingData, vert vector3.Float64) int {
@@ -628,17 +629,18 @@ func (d *MarchingCanvas) marchFloat1BlockPosition(
628629
lookupIndex |= 128
629630
}
630631

631-
for i := 0; triangulation[lookupIndex][i] != -1; i += 3 {
632+
tris := triangulation[lookupIndex]
633+
for i := 0; tris[i] != -1; i += 3 {
632634
// Get indices of corner points A and B for each of the three edges
633635
// of the cube that need to be joined to form the triangle.
634-
a0 := cornerIndexAFromEdge[triangulation[lookupIndex][i]]
635-
b0 := cornerIndexBFromEdge[triangulation[lookupIndex][i]]
636+
a0 := cornerIndexAFromEdge[tris[i]]
637+
b0 := cornerIndexBFromEdge[tris[i]]
636638

637-
a1 := cornerIndexAFromEdge[triangulation[lookupIndex][i+1]]
638-
b1 := cornerIndexBFromEdge[triangulation[lookupIndex][i+1]]
639+
a1 := cornerIndexAFromEdge[tris[i+1]]
640+
b1 := cornerIndexBFromEdge[tris[i+1]]
639641

640-
a2 := cornerIndexAFromEdge[triangulation[lookupIndex][i+2]]
641-
b2 := cornerIndexBFromEdge[triangulation[lookupIndex][i+2]]
642+
a2 := cornerIndexAFromEdge[tris[i+2]]
643+
b2 := cornerIndexBFromEdge[tris[i+2]]
642644

643645
v1 := interpolateVerts(cubeCornerPositions[a0], cubeCornerPositions[b0], cubeCorners[a0], cubeCorners[b0], cutoff).Add(offset)
644646
v2 := interpolateVerts(cubeCornerPositions[a1], cubeCornerPositions[b1], cubeCorners[a1], cubeCorners[b1], cutoff).Add(offset)

0 commit comments

Comments
 (0)