A Go library for signed distance function shape generation. Read as 3D printing shape design.
A rewrite of the original Signed Distance Function CAD package sdfx
for generating 2D and 3D geometry using Go.
must
and form
packages provide panicking and normal error handling basic shape generation APIs for different scenarios.Renderer
interface.sdfexp.ImportModel
sdfexp.UniformTetrahedronMesh
. Experimental feature. Example result image.
For real-world examples with images see examples directory README.
See images of rendered shapes in render/testdata
.
Here is a rendered bolt from one of the unit tests under form3_test.go
Renderer2
interface.Advantages of deadsy/sdfx:
Advantages of soypat/sdf:
deadsy/sdfx
is over 2 times slower and has ~5 times more allocations.Renderer
interface is dead-simple, idiomatic Go and not limited to SDFs
Renderer3
interface has filled render
package with technical debt.SDFUnion
and SDFDiff
interfaces for blending shapes easily
MinPoly
redesign to allow for n-degree polynomials. Also returns a sensible "undefined output" MinFunc
before dividing by zero.nil
valued SDFs
nil
SDFs as "empty" objects. This can later cause panics during rendering well after the point of failure causing hard to debug issues.sdf
must3
and must2
packages for makers.
panic
instead of returned errors.form3
and form2
packages.math
package for best precision and overflow prevention.
math.Hypot
used for all length calculations. deadsy/sdfx
does not use math.Hypot
.spatial
package
sdfx
has own vector types with methods which hurt code legibility
spatial
types from gonum library with correct Triangle degeneracy calculation. deadsy/sdfx
's Degenerate calculation is incorrect.thread
package. Define arbitrary threads with ease using Threader
interface.
deadsy/sdfx
defines threads with strings i.e. "M16x2"
. sdf
Defines threads with types corresponding to standards. i.e: thread.ISO{D:16, P:2}
, which defines an M16x2 ISO thread.See CONTRIBUTING.
The original sdfx
package is amazing. I thank deadsy for putting all that great work into making an amazing tool I use daily. That said, there are some things that were not compatible with my needs:
Here is a benchmark rendering a threaded bolt:
$ go test -benchmem -run=^$ -bench ^(BenchmarkSDFXBolt|BenchmarkBolt)$ ./render
goos: linux
goarch: amd64
pkg: github.com/soypat/sdf/render
cpu: AMD Ryzen 5 3400G with Radeon Vega Graphics
BenchmarkSDFXBolt-8 6 196941244 ns/op 14700786 B/op 98261 allocs/op
BenchmarkBolt-8 13 87547265 ns/op 18136785 B/op 20754 allocs/op
PASS
ok github.com/soypat/sdf/render 4.390s
BenchmarkBolt-8
is this implementation of Octree. BenchmarkSDFXBolt-8
is the sdfx
implementation of said algorithm.
The vector math functions are methods which yield hard to follow operations. i.e:
return bb.Min.Add(bb.Size().Mul(i.ToV3().DivScalar(float64(node.meshSize)).
Div(node.cellCounts.ToV3().DivScalar(float64(node.meshSize))))) // actual code from original sdfx.
A more pressing issue was the Renderer3
interface definition method, Render
type Renderer3 interface {
// ...
Render(s sdf.SDF3, meshCells int, output chan<- *Triangle3)
}
This presented a few problems:
Raises many questions about usage of the function Render- who closes the channel? Does this function block? Do I have to call it as a goroutine?
To implement a renderer one needs to bake in concurrency which is a hard thing to get right from the start. This also means all rendering code besides having the responsibility of computing geometry, it also has to handle concurrency features of the language. This leads to rendering functions with dual responsibility- compute geometry and also handle the multi-core aspect of the computation making code harder to maintain in the long run
Using a channel to send individual triangles is probably a bottleneck.
I would liken meshCells
to an implementation detail of the renderer used. This can be passed as an argument when instantiating the renderer used.
Who's to say we have to limit ourselves to signed distance functions? With the new proposed Renderer
interface this is no longer the case.
sdf
and sdfx
consolidationNone planned.
Gopher rendition by Juliette Whittingslow.
Gopher design authored by Renée French
is licensed by the Creative Commons Attribution 3.0 licensed.