gsdf

package module
v0.0.0-...-01912a4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 22, 2025 License: BSD-3-Clause Imports: 13 Imported by: 0

README

gsdf

go.dev reference Go Report Card codecov Go sourcegraph

gsdf is a CAD 3D design library for Go that uses SDFs for shape definition. Rendering can be done on GPU or CPU for visualization or 3D printing file outputs. Quick jump to usage: bolt example.

All images and shapes in readme were generated using this library.

bolt-example circle text

Requirements

  • Go
  • Optional: See latest requirements on go-glfw if using GPU

Features

  • High test coverage (when GPU available, not the case in CI)

  • Extremely coherent API design.

  • UI for visualizing parts, rendered directly from shaders. See UI example by running go run ./examples/ui-mandala

  • Generate visualization for your parts as shaders.

  • GPU and CPU implementations for all shapes and operations. CPU implementations are actually faster for simple parts.

  • Include arbitrary buffers into GPU calculation. See Shader interface.

  • Heapless algorithms for everything. No usage of GC in happy path.

  • Heapless Octree triangle renderer. Is stupid fast.

    • Design your part using one API, switch between CPU and GPU after design.
  • TinyGo supported for CPU evaluation :)

Package layout/structure

  • gsdf: Top level package defines exact SDFs primitives and operations for use on CPU or GPU workloads. Consumes glbuild interfaces and logic to build shaders.
  • glbuild: Automatic shader generation interfaces and logic.
  • gleval: SDF evaluation interfaces and facilities, both CPU and GPU bound.
  • glrender: Triangle rendering logic which consumes gleval. STL generation.
  • forge: Engineering applications. Composed of subpackages.
    • textsdf package for text generation.
    • threads package for generating screw threads.
  • gsdfaux: High level helper functions to get users started up with gsdf. See examples.

Examples

Find examples under examples directory. Run on GPU with: -gpu flag.

Most 3D examples output two files:

  • example-name.glsl: Visualization shader that can be copy pasted into shadertoy to visualize the part, or rendered within your editor with an extension such as the Shader Toy Visual Studio Code extension.
  • example-name.stl: Triangle model file used in 3D printing software such as Cura. Can be visualized online in sites such as View STL.

Output and timings for

  • CPU: 12th Gen Intel i5-12400F (12) @ 4.400GHz
  • GPU: AMD ATI Radeon RX 6800

npt-flange - 9× GPU speedup

This was converted from the original sdf library example.

GPU rendering in 1 second. 0.4M triangles
time go run ./examples/npt-flange -resdiv 400 -gpu
using GPU       ᵍᵒᵗᵗᵃ ᵍᵒ ᶠᵃˢᵗ
compute invocation size  1024
instantiating evaluation SDF took 115.587024ms
wrote nptflange.glsl in 97.829µs
evaluated SDF 46148621 times and rendered 423852 triangles in 1.103100086s with 95.7 percent evaluations omitted
wrote nptflange.stl in 710.038498ms
finished npt-flange example
go run ./examples/npt-flange -resdiv 400 -gpu  1,01s user 1,10s system 95% cpu 2,217 total
CPU rendering in 9 seconds. 0.4M triangles
time go run ./examples/npt-flange -resdiv 400 
using CPU
instantiating evaluation SDF took 14.173µs
wrote nptflange.glsl in 73.155µs
evaluated SDF 46147934 times and rendered 423852 triangles in 8.482344469s with 95.7 percent evaluations omitted
wrote nptflange.stl in 703.931017ms
finished npt-flange example
go run ./examples/npt-flange -resdiv 400  9,01s user 0,82s system 103% cpu 9,481 total

npt-flange-example

fibonacci-showerhead - 40× GPU speedup

Note that the amount of triangles is very similar to the NPT flange example, but the speedup is much more notable due to the complexity of the part.

GPU rendering in 0.87 seconds. 0.3M triangles
time go run ./examples/fibonacci-showerhead -resdiv 350 -gpu
using GPU       ᵍᵒᵗᵗᵃ ᵍᵒ ᶠᵃˢᵗ
compute invocation size  1024
instantiating evaluation SDF took 108.241558ms
wrote showerhead.glsl in 581.351µs
evaluated SDF 14646305 times and rendered 309872 triangles in 768.731027ms with 89.08 percent evaluations omitted
wrote showerhead.stl in 509.470328ms
showerhead example done
go run ./examples/fibonacci-showerhead -resdiv 350 -gpu  0,87s user 0,69s system 94% cpu 1,646 total
CPU rendering in 36 seconds. 0.3M triangles
time go run ./examples/fibonacci-showerhead -resdiv 350 
using CPU
instantiating evaluation SDF took 27.757µs
wrote showerhead.glsl in 507.155µs
evaluated SDF 14645989 times and rendered 309872 triangles in 35.794768353s with 89.08 percent evaluations omitted
wrote showerhead.stl in 499.13903ms
SDF caching omitted 21.62 percent of 14645989 SDF evaluations
showerhead example done
go run ./examples/fibonacci-showerhead -resdiv 350  36,16s user 0,76s system 100% cpu 36,591 total

fibonacci-showerhead

More examples

iso-screw array-triangles geb-book-cover

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DyixAlv = oODrzM()

Functions

This section is empty.

Types

type Builder

type Builder struct {
	// contains filtered or unexported fields
}

Builder wraps all SDF primitive and operation logic generation. Provides error handling strategies with panics or error accumulation during shape generation.

func (*Builder) Annulus

func (bld *Builder) Annulus(s glbuild.Shader2D, sub float32) glbuild.Shader2D

Annulus makes a 2D shape annular by emptying it's center. It is the equivalent of the 3D Shell operation but in 2D.

func (*Builder) Array

func (bld *Builder) Array(s glbuild.Shader3D, spacingX, spacingY, spacingZ float32, nx, ny, nz int) glbuild.Shader3D

Array is the domain repetition operation. It repeats domain centered around the origin (x,y,z)=(0,0,0).

func (*Builder) Array2D

func (bld *Builder) Array2D(s glbuild.Shader2D, spacingX, spacingY float32, nx, ny int) glbuild.Shader2D

Array is the domain repetition operation. It repeats domain centered around (x,y)=(0,0).

func (*Builder) CircularArray

func (bld *Builder) CircularArray(s glbuild.Shader3D, numInstances, circleDiv int) glbuild.Shader3D

CircularArray is the circular domain repetition operation around the origin (x,y,z)=(0,0,0). It repeats the shape numInstances times and the spacing angle is defined by circleDiv such that angle = 2*pi/circleDiv. The operation is defined this way so that the argument shape is evaluated only twice per circular array evaluation, regardless of instances.

func (*Builder) CircularArray2D

func (bld *Builder) CircularArray2D(s glbuild.Shader2D, numInstances, circleDiv int) glbuild.Shader2D

CircularArray2D is the circular domain repetition operation around the origin (x,y)=(0,0). It repeats the shape numInstances times and the spacing angle is defined by circleDiv such that angle = 2*pi/circleDiv. The operation is defined this way so that the argument shape is evaluated only twice per circular array evaluation, regardless of instances.

func (*Builder) ClearErrors

func (bld *Builder) ClearErrors()

ClearErrors clears accumulated errors such that Builder.Err returns nil on next call.

func (*Builder) Difference

func (bld *Builder) Difference(a, b glbuild.Shader3D) glbuild.Shader3D

Difference is the SDF difference of a-b. Does not produce a true SDF.

func (*Builder) Difference2D

func (bld *Builder) Difference2D(a, b glbuild.Shader2D) glbuild.Shader2D

Difference2D is the SDF difference of a-b. Does not produce a true SDF.

func (*Builder) Elongate

func (bld *Builder) Elongate(s glbuild.Shader3D, dirX, dirY, dirZ float32) glbuild.Shader3D

Elongate "stretches" the SDF in a direction by splitting it on the origin in the plane perpendicular to the argument direction. The part of the shape in the negative plane is discarded and replaced with the elongated positive part.

Arguments are distances, so zero-valued arguments are no-op.

func (*Builder) Err

func (bld *Builder) Err() error

Err returns errors accumulated during SDF primitive creation and operations. The returned error implements `Unwrap() []error`.

func (*Builder) Extrude

func (bld *Builder) Extrude(s glbuild.Shader2D, h float32) glbuild.Shader3D

Extrude converts a 2D SDF into a 3D extrusion. Extrudes in both positive and negative Z direction, half of h both ways.

func (*Builder) Flags

func (bld *Builder) Flags() Flags

func (*Builder) Intersection

func (bld *Builder) Intersection(a, b glbuild.Shader3D) glbuild.Shader3D

Intersection is the SDF intersection of a ^ b. Does not produce an exact SDF.

func (*Builder) Intersection2D

func (bld *Builder) Intersection2D(a, b glbuild.Shader2D) glbuild.Shader2D

Intersection2D is the SDF intersection of a ^ b. Does not produce an exact SDF.

func (*Builder) NewArc

func (bld *Builder) NewArc(radius, arcAngle, thick float32) glbuild.Shader2D

NewArc returns a 2D arc centered at the origin (x,y)=(0,0) for a given radius and arc angle and thickness of the arc. The arc begins opening at (x,y)=(0,r) in both positive and negative x direction.

func (*Builder) NewBoundsBoxFrame

func (bld *Builder) NewBoundsBoxFrame(bb ms3.Box) glbuild.Shader3D

NewBoundsBoxFrame creates a BoxFrame from a bb (ms3.Box) such that the BoxFrame envelops the bb. Useful for debugging bounding boxes of glbuild.Shader3D primitives and operations.

func (*Builder) NewBox

func (bld *Builder) NewBox(x, y, z, round float32) glbuild.Shader3D

NewBox creates a box centered at the origin with x,y,z dimensions and a rounding parameter to round edges.

func (*Builder) NewBoxFrame

func (bld *Builder) NewBoxFrame(dimX, dimY, dimZ, e float32) glbuild.Shader3D

NewBoxFrame creates a framed box with the frame being composed of square beams of thickness e.

func (*Builder) NewCircle

func (bld *Builder) NewCircle(radius float32) glbuild.Shader2D

NewCircle creates a circle of a radius centered at the origin (x,y)=(0,0).

func (*Builder) NewCylinder

func (bld *Builder) NewCylinder(r, h, rounding float32) glbuild.Shader3D

NewCylinder creates a cylinder centered at the origin with given radius and height. The cylinder's axis points in z direction.

func (*Builder) NewEllipse

func (bld *Builder) NewEllipse(a, b float32) glbuild.Shader2D

NewEllipse creates a 2D ellipse SDF with a and b ellipse parameters.

func (*Builder) NewEquilateralTriangle

func (bld *Builder) NewEquilateralTriangle(triangleHeight float32) glbuild.Shader2D

NewEquilateralTriangle creates an equilater triangle with a given height with it's centroid located at the origin.

func (*Builder) NewHexagon

func (bld *Builder) NewHexagon(side float32) glbuild.Shader2D

NewHexagon creates a regular hexagon centered at (x,y)=(0,0) with sides of length `side`.

func (*Builder) NewHexagonalPrism

func (bld *Builder) NewHexagonalPrism(face2Face, h float32) glbuild.Shader3D

NewHexagonalPrism creates a hexagonal prism given a face-to-face dimension and height. The hexagon's length is in the z axis.

func (*Builder) NewLine2D

func (bld *Builder) NewLine2D(x0, y0, x1, y1, width float32) glbuild.Shader2D

NewLine2D creates a straight line between (x0,y0) and (x1,y1) with a given thickness.

func (*Builder) NewLines2D

func (bld *Builder) NewLines2D(segments [][2]ms2.Vec, width float32) glbuild.Shader2D

NewLines2D creates sequential straight lines between the argument points.

func (*Builder) NewPolygon

func (bld *Builder) NewPolygon(vertices []ms2.Vec) glbuild.Shader2D

NewPolygon creates a polygon from a set of vertices. The polygon can be self-intersecting.

func (*Builder) NewRectangle

func (bld *Builder) NewRectangle(x, y float32) glbuild.Shader2D

NewRectangle creates a rectangle centered at (x,y)=(0,0) with given x and y dimensions.

func (*Builder) NewSphere

func (bld *Builder) NewSphere(r float32) glbuild.Shader3D

NewSphere creates a sphere centered at the origin of radius r.

func (*Builder) NewTorus

func (bld *Builder) NewTorus(greaterRadius, lesserRadius float32) glbuild.Shader3D

NewTorus creates a 3D torus given 2 radii to define the radius across (greaterRadius) and the "solid" radius (lesserRadius). If the radius were cut and stretched straight to form a cylinder the lesser radius would be the radius of the cylinder. The torus' axis is in the z axis.

func (*Builder) NewTriangularPrism

func (bld *Builder) NewTriangularPrism(triHeight, extrudeLength float32) glbuild.Shader3D

NewTriangularPrism creates a 3D triangular prism with a given triangle cross-sectional height (2D) and a extrude length. The prism's extrude axis is in the z axis direction.

func (*Builder) Offset

func (bld *Builder) Offset(s glbuild.Shader3D, sdfAdd float32) glbuild.Shader3D

Offset adds sdfAdd to the entire argument SDF. If sdfAdd is negative this will round edges and increase the dimension of flat surfaces of the SDF by the absolute magnitude. See Inigo's youtube video on the subject.

func (*Builder) Offset2D

func (bld *Builder) Offset2D(s glbuild.Shader2D, sdfAdd float32) glbuild.Shader2D

Offset2D adds sdfAdd to the entire argument SDF. If sdfAdd is negative this will round edges and increase the dimension of flat surfaces of the SDF by the absolute magnitude. See Inigo's youtube video on the subject.

func (*Builder) Revolve

func (bld *Builder) Revolve(s glbuild.Shader2D, axisOffset float32) glbuild.Shader3D

Revolve revolves a 2D SDF around the y axis, offsetting the axis of revolution by axisOffset.

func (*Builder) Rotate

func (bld *Builder) Rotate(s glbuild.Shader3D, radians float32, axis ms3.Vec) glbuild.Shader3D

Rotate is the rotation of radians angle around an axis vector.

func (*Builder) Rotate2D

func (bld *Builder) Rotate2D(s glbuild.Shader2D, theta float32) glbuild.Shader2D

Rotate2D returns the argument shape rotated around the origin by theta (radians).

func (*Builder) Scale

func (bld *Builder) Scale(s glbuild.Shader3D, scaleFactor float32) glbuild.Shader3D

Scale scales s by scaleFactor around the origin.

func (*Builder) Scale2D

func (bld *Builder) Scale2D(s glbuild.Shader2D, scale float32) glbuild.Shader2D

ScaleXY scales s by scaleFactor around the origin.

func (*Builder) SetFlags

func (bld *Builder) SetFlags(flags Flags) error

func (*Builder) Shell

func (bld *Builder) Shell(s glbuild.Shader3D, thickness float32) glbuild.Shader3D

Shell carves the interior of the SDF leaving only the exterior shell of the part.

func (*Builder) SmoothDifference

func (bld *Builder) SmoothDifference(k float32, s1, s2 glbuild.Shader3D) glbuild.Shader3D

SmoothDifference performs the difference of two SDFs with a smoothing parameter.

func (*Builder) SmoothIntersect

func (bld *Builder) SmoothIntersect(k float32, s1, s2 glbuild.Shader3D) glbuild.Shader3D

SmoothIntersect performs the intesection of two SDFs with a smoothing parameter.

func (*Builder) SmoothUnion

func (bld *Builder) SmoothUnion(k float32, s1, s2 glbuild.Shader3D) glbuild.Shader3D

SmoothUnion joins the shapes of two shaders into one with a smoothing blend.

func (*Builder) Symmetry

func (bld *Builder) Symmetry(s glbuild.Shader3D, mirrorX, mirrorY, mirrorZ bool) glbuild.Shader3D

Symmetry reflects the SDF around one or more cartesian planes.

func (*Builder) Symmetry2D

func (bld *Builder) Symmetry2D(s glbuild.Shader2D, mirrorX, mirrorY bool) glbuild.Shader2D

Symmetry reflects the SDF around x or y (or both) axis.

func (*Builder) Transform

func (bld *Builder) Transform(s glbuild.Shader3D, m ms3.Mat4) glbuild.Shader3D

Transform applies a 4x4 matrix transformation to the argument shader by inverting the argument matrix.

func (*Builder) Translate

func (bld *Builder) Translate(s glbuild.Shader3D, dirX, dirY, dirZ float32) glbuild.Shader3D

Translate moves the SDF s in the given direction (dirX, dirY, dirZ) and returns the result.

func (*Builder) Translate2D

func (bld *Builder) Translate2D(s glbuild.Shader2D, dirX, dirY float32) glbuild.Shader2D

Translate2D moves the SDF s in the given direction.

func (*Builder) TranslateMulti2D

func (bld *Builder) TranslateMulti2D(s glbuild.Shader2D, displacements []ms2.Vec) glbuild.Shader2D

TranslateMulti2D displaces N instances of s SDF to positions given by displacements of length N.

func (*Builder) Union

func (bld *Builder) Union(shaders ...glbuild.Shader3D) glbuild.Shader3D

Union joins the shapes of several 3D SDFs into one. Is exact. Union aggregates nested Union results into its own. To prevent this behaviour use OpUnion directly.

func (*Builder) Union2D

func (*Builder) Union2D(shaders ...glbuild.Shader2D) glbuild.Shader2D

Union joins the shapes of several 2D SDFs into one. Is exact. Union aggregates nested Union results into its own.

func (*Builder) Xor

func (bld *Builder) Xor(s1, s2 glbuild.Shader3D) glbuild.Shader3D

Xor is the mutually exclusive boolean operation and results in an exact SDF.

func (*Builder) Xor2D

func (bld *Builder) Xor2D(s1, s2 glbuild.Shader2D) glbuild.Shader2D

Xor2D is the mutually exclusive boolean operation and results in an exact SDF.

type Flags

type Flags uint64

Flags is a bitmask of values to control the functioning of the Builder type.

const (
	// FlagNoDimensionPanic controls panicking behavior on invalid shape dimension errors.
	// If set then these errors do not panic, instead storing the error for later inspection with [Builder.Err].
	FlagNoDimensionPanic Flags = 1 << iota
	// FlagUseShaderBuffers enforces the use of shader object for all newly built
	// SDFs which require a dynamic array(s) to be rendered correctly.
	FlagUseShaderBuffers
)

type OpUnion

type OpUnion struct {
	// contains filtered or unexported fields
}

OpUnion is the result of the [Union] operation. Prefer using [Union] to using this type directly.

Normally primitives and results of operations in this package are not exported since their concrete type provides relatively little value. The result of Union is the exception to the rule since it is the most common operation to perform on SDFs and can provide several benefits to users seeking to optimize their SDFs creatively such as creating sectioned SDFs where conditional evaluation may be performed depending on the bounding boxes of the SDFs being evaluated.

By exporting OpUnion users can traverse a glbuild.Shader3D tree looking for OpUnion elements and checking how heavy their computation cost is and evaluating if sectioning their bounding box is effective.

func (*OpUnion) AppendShaderBody

func (u *OpUnion) AppendShaderBody(b []byte) []byte

AppendShaderBody implements glbuild.Shader.

func (*OpUnion) AppendShaderName

func (u *OpUnion) AppendShaderName(b []byte) []byte

AppendShaderName implements glbuild.Shader.

func (*OpUnion) AppendShaderObjects

func (u *OpUnion) AppendShaderObjects(objects []glbuild.ShaderObject) []glbuild.ShaderObject

AppendShaderObjects implements glbuild.Shader. This method returns the argument buffer with no modifications. See glbuild.Shader for more information.

func (*OpUnion) Bounds

func (u *OpUnion) Bounds() ms3.Box

Bounds returns the union of all joined SDFs. Implements glbuild.Shader3D and gleval.SDF3.

func (*OpUnion) Evaluate

func (u *OpUnion) Evaluate(pos []ms3.Vec, dist []float32, userData any) error

Evaluate implements gleval.SDF3.

func (*OpUnion) ForEachChild

func (u *OpUnion) ForEachChild(userData any, fn func(userData any, s *glbuild.Shader3D) error) error

ForEachChild implements glbuild.Shader3D.

type OpUnion2D

type OpUnion2D struct {
	// contains filtered or unexported fields
}

OpUnion2D is the result of [Union2D]. This type is exported for special reasons, see OpUnion documentation.

func (*OpUnion2D) AppendShaderBody

func (u *OpUnion2D) AppendShaderBody(b []byte) []byte

AppendShaderBody implements glbuild.Shader.

func (*OpUnion2D) AppendShaderName

func (u *OpUnion2D) AppendShaderName(b []byte) []byte

AppendShaderName implements glbuild.Shader.

func (*OpUnion2D) AppendShaderObjects

func (u *OpUnion2D) AppendShaderObjects(objects []glbuild.ShaderObject) []glbuild.ShaderObject

AppendShaderObjects implements glbuild.Shader. This method returns the argument buffer with no modifications. See glbuild.Shader for more information.

func (*OpUnion2D) Bounds

func (u *OpUnion2D) Bounds() ms2.Box

Bounds returns the union of all joined SDFs. Implements glbuild.Shader2D and gleval.SDF2.

func (*OpUnion2D) Evaluate

func (u *OpUnion2D) Evaluate(pos []ms2.Vec, dist []float32, userData any) error

Evaluate implements gleval.SDF2.

func (*OpUnion2D) ForEach2DChild

func (u *OpUnion2D) ForEach2DChild(userData any, fn func(userData any, s *glbuild.Shader2D) error) error

ForEachChild implements glbuild.Shader2D.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL