Skip to content

Commit 6d8c361

Browse files
committed
gsdfaux: new package to facilitate rendering for users
1 parent 39445ba commit 6d8c361

File tree

6 files changed

+304
-282
lines changed

6 files changed

+304
-282
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ local
4242
*.zip
4343
*.gz
4444
*.tar
45+
*.prof
46+
*.pprof
47+
*.cpuprof
48+
*.heapprof
4549

4650
# image outputs
4751
*.png

examples/bolt/main.go

+26-90
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,26 @@
11
package main
22

33
import (
4-
"bufio"
5-
"bytes"
64
"flag"
75
"fmt"
86
"log"
97
"os"
108
"runtime"
11-
"time"
129

13-
"github.com/soypat/gsdf"
1410
"github.com/soypat/gsdf/forge/threads"
1511
"github.com/soypat/gsdf/glbuild"
16-
"github.com/soypat/gsdf/gleval"
17-
"github.com/soypat/gsdf/glrender"
12+
"github.com/soypat/gsdf/gsdfaux"
1813
)
1914

2015
const visualization = "bolt.glsl"
2116
const stl = "bolt.stl"
2217

23-
var useGPU = false
24-
2518
func init() {
26-
flag.BoolVar(&useGPU, "gpu", useGPU, "Enable GPU usage")
27-
flag.Parse()
28-
if useGPU {
29-
fmt.Println("enabled GPU usage")
30-
runtime.LockOSThread() // For when using GPU this is required.
31-
}
19+
runtime.LockOSThread() // For when using GPU this is required.
3220
}
3321

3422
// scene generates the 3D object for rendering.
35-
func scene() (gleval.SDF3, error) {
23+
func scene() (glbuild.Shader3D, error) {
3624
const L, shank = 5, 3
3725
threader := threads.ISO{D: 3, P: 0.5, Ext: true}
3826
M3, err := threads.Bolt(threads.BoltParams{
@@ -44,93 +32,41 @@ func scene() (gleval.SDF3, error) {
4432
if err != nil {
4533
return nil, err
4634
}
47-
return makeSDF(M3)
35+
return M3, nil
4836
}
4937

50-
func main() {
51-
if useGPU {
52-
terminate, err := gleval.Init1x1GLFW()
53-
if err != nil {
54-
log.Fatal("failed to start GLFW", err.Error())
55-
}
56-
defer terminate()
57-
}
58-
sceneStart := time.Now()
38+
func run() error {
39+
useGPU := flag.Bool("gpu", false, "Enable GPU usage")
40+
flag.Parse()
5941
sdf, err := scene()
6042
if err != nil {
61-
fmt.Println("error making scene:", err)
62-
os.Exit(1)
43+
return err
6344
}
64-
elapsedScene := time.Since(sceneStart)
65-
const resDiv = 200
66-
const evaluationBufferSize = 1024 * 8
67-
resolution := sdf.Bounds().Size().Max() / resDiv
68-
renderer, err := glrender.NewOctreeRenderer(sdf, resolution, evaluationBufferSize)
45+
fpstl, err := os.Create(stl)
6946
if err != nil {
70-
fmt.Println("error creating renderer:", err)
71-
os.Exit(1)
47+
return err
7248
}
73-
start := time.Now()
74-
triangles, err := glrender.RenderAll(renderer)
49+
defer fpstl.Close()
50+
fpvis, err := os.Create(visualization)
7551
if err != nil {
76-
fmt.Println("error rendering triangles:", err)
77-
os.Exit(1)
52+
return err
7853
}
79-
elapsed := time.Since(start)
80-
evals := sdf.(interface{ Evaluations() uint64 }).Evaluations()
54+
defer fpvis.Close()
8155

82-
fp, err := os.Create(stl)
83-
if err != nil {
84-
fmt.Println("error creating file:", err)
85-
os.Exit(1)
86-
}
87-
defer fp.Close()
88-
start = time.Now()
89-
w := bufio.NewWriter(fp)
90-
_, err = glrender.WriteBinarySTL(w, triangles)
91-
if err != nil {
92-
fmt.Println("error writing triangles to file:", err)
93-
os.Exit(1)
94-
}
95-
w.Flush()
96-
fmt.Println("SDF created in ", elapsedScene, "evaluated sdf", evals, "times, rendered", len(triangles), "triangles in", elapsed, "wrote file in", time.Since(start))
56+
err = gsdfaux.Render(sdf, gsdfaux.RenderConfig{
57+
STLOutput: fpstl,
58+
VisualOutput: fpvis,
59+
Resolution: sdf.Bounds().Diagonal() / 200,
60+
UseGPU: *useGPU,
61+
})
62+
63+
return err
9764
}
9865

99-
func makeSDF(s glbuild.Shader3D) (gleval.SDF3, error) {
100-
err := glbuild.ShortenNames3D(&s, 32) // Shorten names to not crash GL tokenizer.
66+
func main() {
67+
err := run()
10168
if err != nil {
102-
return nil, err
103-
}
104-
if visualization != "" {
105-
const sceneSize = 0.5
106-
// We include the bounding box in the visualization.
107-
bb := s.Bounds()
108-
envelope, err := gsdf.NewBoundsBoxFrame(bb)
109-
if err != nil {
110-
return nil, err
111-
}
112-
visual := gsdf.Union(s, envelope)
113-
// Scale size and translate to center so visualization is in camera range.
114-
center := bb.Center()
115-
visual = gsdf.Translate(visual, center.X, center.Y, center.Z)
116-
visual = gsdf.Scale(visual, sceneSize/bb.Size().Max())
117-
source := new(bytes.Buffer)
118-
_, err = glbuild.NewDefaultProgrammer().WriteFragVisualizerSDF3(source, visual)
119-
if err != nil {
120-
return nil, err
121-
}
122-
err = os.WriteFile(visualization, source.Bytes(), 0666)
123-
if err != nil {
124-
return nil, err
125-
}
126-
}
127-
if useGPU {
128-
source := new(bytes.Buffer)
129-
_, err := glbuild.NewDefaultProgrammer().WriteComputeSDF3(source, s)
130-
if err != nil {
131-
return nil, err
132-
}
133-
return gleval.NewComputeGPUSDF3(source, s.Bounds())
69+
log.Fatal(err)
13470
}
135-
return gleval.NewCPUSDF3(s)
71+
fmt.Println("bolt example done")
13672
}

examples/fibonacci-showerhead/main.go

+54-94
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
package main
22

33
import (
4-
"bytes"
4+
"flag"
55
"fmt"
66
"log"
77
"runtime"
8-
"time"
98

109
"os"
1110

@@ -14,52 +13,78 @@ import (
1413
"github.com/soypat/gsdf"
1514
"github.com/soypat/gsdf/forge/threads"
1615
"github.com/soypat/gsdf/glbuild"
17-
"github.com/soypat/gsdf/gleval"
18-
"github.com/soypat/gsdf/glrender"
16+
"github.com/soypat/gsdf/gsdfaux"
1917
)
2018

21-
// Showerhead parameters as defined by showerhead design.
2219
const (
23-
threadExtDiameter = 65.
24-
threadedLength = 5.
25-
threadTurns = 3.
26-
threadPitch = threadedLength / threadTurns
27-
)
28-
29-
// Constructuive parameters defined by our design.
30-
const (
31-
showerheadBaseThick = 2.5
32-
showerheadWall = 4.
33-
threadheight = 5.
34-
)
35-
36-
var (
37-
showerThread = threads.PlasticButtress{
38-
D: threadExtDiameter,
39-
P: threadPitch,
40-
}
20+
stl = "showerhead.stl"
21+
visualization = "showerhead.glsl"
4122
)
4223

4324
func init() {
4425
runtime.LockOSThread() // In case we wish to use OpenGL.
4526
}
4627

47-
func main() {
48-
watch := stopwatch()
28+
func run() error {
29+
useGPU := flag.Bool("gpu", false, "Enable GPU usage")
30+
flag.Parse()
4931
object, err := scene()
5032
if err != nil {
51-
log.Fatalf("creating 3D object: %s", err)
33+
return err
34+
}
35+
fpstl, err := os.Create(stl)
36+
if err != nil {
37+
return err
38+
}
39+
defer fpstl.Close()
40+
fpvis, err := os.Create(visualization)
41+
if err != nil {
42+
return err
5243
}
53-
fmt.Println("created object in", watch())
54-
useGPU := true
55-
err = render(object, useGPU)
44+
defer fpvis.Close()
45+
46+
err = gsdfaux.Render(object, gsdfaux.RenderConfig{
47+
STLOutput: fpstl,
48+
VisualOutput: fpvis,
49+
Resolution: object.Bounds().Diagonal() / 200,
50+
UseGPU: *useGPU,
51+
})
52+
53+
return err
54+
}
55+
56+
func main() {
57+
err := run()
5658
if err != nil {
5759
log.Fatal(err)
5860
}
61+
fmt.Println("showerhead example done")
5962
}
6063

6164
// scene returns the showerhead object.
6265
func scene() (glbuild.Shader3D, error) {
66+
67+
// Showerhead parameters as defined by showerhead geometry.
68+
const (
69+
threadExtDiameter = 65.
70+
threadedLength = 5.
71+
threadTurns = 3.
72+
threadPitch = threadedLength / threadTurns
73+
)
74+
75+
// Constructuive parameters defined by our design.
76+
const (
77+
showerheadBaseThick = 2.5
78+
showerheadWall = 4.
79+
threadheight = 5.
80+
)
81+
82+
var (
83+
showerThread = threads.PlasticButtress{
84+
D: threadExtDiameter,
85+
P: threadPitch,
86+
}
87+
)
6388
// Object accumulates the showerhead sdf.
6489
var object glbuild.Shader3D
6590

@@ -94,64 +119,6 @@ func scene() (glbuild.Shader3D, error) {
94119
return object, nil
95120
}
96121

97-
func render(s glbuild.Shader3D, useGPU bool) (err error) {
98-
err = glbuild.ShortenNames3D(&s, 6)
99-
if err != nil {
100-
return fmt.Errorf("shortening shader names: %s", err)
101-
}
102-
bb := s.Bounds()
103-
var sdf gleval.SDF3
104-
watch := stopwatch()
105-
if useGPU {
106-
fmt.Println("using GPU")
107-
{
108-
terminate, err := gleval.Init1x1GLFW()
109-
if err != nil {
110-
return err
111-
}
112-
defer terminate()
113-
}
114-
source := new(bytes.Buffer)
115-
_, err = glbuild.NewDefaultProgrammer().WriteComputeSDF3(source, s)
116-
if err != nil {
117-
return err
118-
}
119-
sdf, err = gleval.NewComputeGPUSDF3(source, bb)
120-
} else {
121-
sdf, err = gleval.NewCPUSDF3(s)
122-
}
123-
124-
if err != nil || sdf == nil {
125-
return fmt.Errorf("instantiating SDF: %s", err)
126-
}
127-
128-
fmt.Println("instantiating evaluation SDF took", watch())
129-
const size = 1 << 12
130-
renderer, err := glrender.NewOctreeRenderer(sdf, bb.Size().Max()/350, size)
131-
if err != nil {
132-
return err
133-
}
134-
135-
fp, err := os.Create("showerhead.stl")
136-
if err != nil {
137-
return fmt.Errorf("creating file: %s", err)
138-
}
139-
watch = stopwatch()
140-
triangles, err := glrender.RenderAll(renderer)
141-
if err != nil {
142-
return fmt.Errorf("rendering triangles: %s", err)
143-
}
144-
e := sdf.(interface{ Evaluations() uint64 })
145-
fmt.Println("evaluated SDF", e.Evaluations(), "times and rendered", len(triangles), "triangles in", watch())
146-
watch = stopwatch()
147-
_, err = glrender.WriteBinarySTL(fp, triangles)
148-
if err != nil {
149-
return fmt.Errorf("writing STL file: %s", err)
150-
}
151-
fmt.Println("wrote STL file in", watch())
152-
return nil
153-
}
154-
155122
func fibonacci(n int) ms2.Vec {
156123
// Angle of divergence is very sensitive- 137.3 to 137.5 varies pattern greatly.
157124
const angleOfDivergence = 137.3
@@ -162,10 +129,3 @@ func fibonacci(n int) ms2.Vec {
162129
sa, ca := math.Sincos(a)
163130
return ms2.Vec{X: r * ca, Y: r * sa}
164131
}
165-
166-
func stopwatch() func() time.Duration {
167-
start := time.Now()
168-
return func() time.Duration {
169-
return time.Since(start)
170-
}
171-
}

0 commit comments

Comments
 (0)