Created
September 3, 2021 02:27
-
-
Save soypat/149c7d655ca877b0edc3de5948be3d1b to your computer and use it in GitHub Desktop.
Creating STL cylinders in go using sdfx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package helpers | |
import ( | |
"github.com/deadsy/sdfx/sdf" | |
) | |
// Spaces sdf3's located at one point. | |
func DirectionalSpacing(shapes []sdf.SDF3, dir sdf.V3, baseSep float64) (spacings []sdf.V3) { | |
if dir.Equals(sdf.V3{}, 0) { | |
panic("direction must not be zero") | |
} | |
spacings = make([]sdf.V3, len(shapes)) | |
norm := dir.Normalize() | |
sep := norm.MulScalar(baseSep) | |
for i := 1; i < len(shapes); i++ { | |
prevCenter := shapes[i-1].BoundingBox().Center() | |
box := shapes[i].BoundingBox().Size() | |
boxPrev := shapes[i-1].BoundingBox().Size() | |
spacings[i] = norm.MulScalar((box.Dot(norm) + boxPrev.Dot(norm)) / 2) | |
spacings[i] = spacings[i].Add(sep.Add(prevCenter)) | |
shapes[i] = sdf.Transform3D(shapes[i], sdf.Translate3d(spacings[i])) | |
} | |
return spacings | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//----------------------------------------------------------------------------- | |
/* | |
Axoloti Board Mounting Kit | |
*/ | |
//----------------------------------------------------------------------------- | |
package main | |
import ( | |
"threedee/helpers" | |
"github.com/deadsy/sdfx/obj" | |
"github.com/deadsy/sdfx/render" | |
"github.com/deadsy/sdfx/sdf" | |
) | |
//----------------------------------------------------------------------------- | |
// material shrinkage | |
var shrink = 1.0 / 0.999 // PLA ~0.1% | |
//var shrink = 1.0/0.995; // ABS ~0.5% | |
//----------------------------------------------------------------------------- | |
const frontPanelThickness = 3.0 | |
const frontPanelLength = 170.0 | |
const frontPanelHeight = 50.0 | |
const frontPanelYOffset = 15.0 | |
const baseWidth = 50.0 | |
const baseLength = 170.0 | |
const baseThickness = 3.0 | |
const baseFootWidth = 10.0 | |
const baseFootCornerRadius = 3.0 | |
const pcbWidth = 50.0 | |
const pcbLength = 160.0 | |
const pillarHeight = 16.8 | |
func tenCyl() []sdf.SDF3 { | |
var err error | |
// sdf.Multi3d generates repeated structure | |
n := 10 | |
shapes := make([]sdf.SDF3, n) | |
for i := 0; i < n; i++ { | |
shapes[i], err = sdf.Cylinder3D(4, float64(i+1)/2, 0) | |
if err != nil { | |
panic(err) | |
} | |
} | |
return shapes | |
} | |
func main() { | |
cyls := tenCyl() | |
helpers.DirectionalSpacing(cyls, sdf.V3{1, 0, 0}, 0.5) | |
model := sdf.Union3D(cyls...) | |
box, _ := sdf.Box3D(model.BoundingBox().Size().MulScalar(1.1), 1) | |
diff := model.BoundingBox().Min.Sub(box.BoundingBox().Min) | |
box = sdf.Transform3D(box, sdf.Translate3d(diff.DivScalar(1.05))) | |
model = sdf.Difference3D(box, model) | |
render.RenderSTL(sdf.ScaleUniform3D(model, shrink), 400, "patoCylinders.stl") | |
} | |
//----------------------------------------------------------------------------- | |
// multiple standoffs | |
func standoffs() (sdf.SDF3, error) { | |
k := &obj.StandoffParms{ | |
PillarHeight: pillarHeight, | |
PillarDiameter: 6.0, | |
HoleDepth: 10.0, | |
HoleDiameter: 2.4, | |
} | |
zOfs := 0.5 * (pillarHeight + baseThickness) | |
// from the board mechanicals | |
positions := sdf.V3Set{ | |
{3.5, 10.0, zOfs}, // H1 | |
{3.5, 40.0, zOfs}, // H2 | |
{54.0, 40.0, zOfs}, // H3 | |
{156.5, 10.0, zOfs}, // H4 | |
//{54.0, 10.0, zOfs}, // H5 | |
{156.5, 40.0, zOfs}, // H6 | |
{44.0, 10.0, zOfs}, // H7 | |
{116.0, 10.0, zOfs}, // H8 | |
} | |
s, err := obj.Standoff3D(k) | |
if err != nil { | |
return nil, err | |
} | |
return sdf.Multi3D(s, positions), nil | |
} | |
//----------------------------------------------------------------------------- | |
// base returns the base m 3.5ount. | |
func base() (sdf.SDF3, error) { | |
// base | |
pp := &obj.PanelParms{ | |
Size: sdf.V2{baseLength, baseWidth}, | |
CornerRadius: 5.0, | |
HoleDiameter: 0, | |
HoleMargin: [4]float64{7.0, 20.0, 7.0, 20.0}, | |
HolePattern: [4]string{"xx", "x", "xx", "x"}, | |
} | |
s0, err := obj.Panel2D(pp) | |
if err != nil { | |
return nil, err | |
} | |
// cutout | |
l := baseLength - (2.0 * baseFootWidth) | |
w := 18.0 | |
s1 := sdf.Box2D(sdf.V2{l, w}, baseFootCornerRadius) | |
yOfs := 0.5 * (baseWidth - pcbWidth) | |
s1 = sdf.Transform2D(s1, sdf.Translate2d(sdf.V2{0, yOfs})) | |
s2 := sdf.Extrude3D(sdf.Difference2D(s0, s1), baseThickness) | |
xOfs := 0.5 * pcbLength | |
yOfs = pcbWidth - (0.5 * baseWidth) | |
s2 = sdf.Transform3D(s2, sdf.Translate3d(sdf.V3{xOfs, yOfs, 0})) | |
// standoffs | |
s3, err := standoffs() | |
if err != nil { | |
return nil, err | |
} | |
s4 := sdf.Union3D(s2, s3) | |
s4.(*sdf.UnionSDF3).SetMin(sdf.PolyMin(3.0)) | |
return s4, nil | |
} | |
//----------------------------------------------------------------------------- | |
// front panel cutouts | |
type panelHole struct { | |
center sdf.V2 // center of hole | |
hole sdf.SDF2 // 2d hole | |
} | |
// button positions | |
const pbX = 53.0 | |
var pb0 = sdf.V2{pbX, 0.8} | |
var pb1 = sdf.V2{pbX + 5.334, 0.8} | |
// panelCutouts returns the 2D front panel cutouts | |
func panelCutouts() (sdf.SDF2, error) { | |
sMidi, err := sdf.Circle2D(0.5 * 17.0) | |
if err != nil { | |
return nil, err | |
} | |
sJack0, err := sdf.Circle2D(0.5 * 11.5) | |
if err != nil { | |
return nil, err | |
} | |
sJack1, err := sdf.Circle2D(0.5 * 5.5) | |
if err != nil { | |
return nil, err | |
} | |
sLed := sdf.Box2D(sdf.V2{1.6, 1.6}, 0) | |
k := obj.FingerButtonParms{ | |
Width: 4.0, | |
Gap: 0.6, | |
Length: 20.0, | |
} | |
fb, err := obj.FingerButton2D(&k) | |
if err != nil { | |
return nil, err | |
} | |
sButton := sdf.Transform2D(fb, sdf.Rotate2d(sdf.DtoR(-90))) | |
jackX := 123.0 | |
midiX := 18.8 | |
ledX := 62.9 | |
holes := []panelHole{ | |
{sdf.V2{midiX, 10.2}, sMidi}, // MIDI DIN Jack | |
{sdf.V2{midiX + 20.32, 10.2}, sMidi}, // MIDI DIN Jack | |
{sdf.V2{jackX, 8.14}, sJack0}, // 1/4" Stereo Jack | |
{sdf.V2{jackX + 19.5, 8.14}, sJack0}, // 1/4" Stereo Jack | |
{sdf.V2{107.6, 2.3}, sJack1}, // 3.5 mm Headphone Jack | |
{sdf.V2{ledX, 0.5}, sLed}, // LED | |
{sdf.V2{ledX + 3.635, 0.5}, sLed}, // LED | |
{pb0, sButton}, // Push Button | |
{pb1, sButton}, // Push Button | |
{sdf.V2{84.1, 1.0}, sdf.Box2D(sdf.V2{16.0, 7.5}, 0)}, // micro SD card | |
{sdf.V2{96.7, 1.0}, sdf.Box2D(sdf.V2{11.0, 7.5}, 0)}, // micro USB connector | |
{sdf.V2{73.1, 7.1}, sdf.Box2D(sdf.V2{7.5, 15.0}, 0)}, // fullsize USB connector | |
} | |
s := make([]sdf.SDF2, len(holes)) | |
for i, k := range holes { | |
s[i] = sdf.Transform2D(k.hole, sdf.Translate2d(k.center)) | |
} | |
return sdf.Union2D(s...), nil | |
} | |
//----------------------------------------------------------------------------- | |
// frontPanel returns the front panel mount. | |
func frontPanel() (sdf.SDF3, error) { | |
// overall panel | |
pp := &obj.PanelParms{ | |
Size: sdf.V2{frontPanelLength, frontPanelHeight}, | |
CornerRadius: 5.0, | |
HoleDiameter: 3.5, | |
HoleMargin: [4]float64{5.0, 5.0, 5.0, 5.0}, | |
HolePattern: [4]string{"xx", "x", "xx", "x"}, | |
} | |
panel, err := obj.Panel2D(pp) | |
if err != nil { | |
return nil, err | |
} | |
xOfs := 0.5 * pcbLength | |
yOfs := (0.5 * frontPanelHeight) - frontPanelYOffset | |
panel = sdf.Transform2D(panel, sdf.Translate2d(sdf.V2{xOfs, yOfs})) | |
// extrude to 3d | |
panelCutouts, err := panelCutouts() | |
if err != nil { | |
return nil, err | |
} | |
fp := sdf.Extrude3D(sdf.Difference2D(panel, panelCutouts), frontPanelThickness) | |
// Add buttons to the finger button | |
bHeight := 4.0 | |
b, _ := sdf.Cylinder3D(bHeight, 1.4, 0) | |
b0 := sdf.Transform3D(b, sdf.Translate3d(pb0.ToV3(-0.5*bHeight))) | |
b1 := sdf.Transform3D(b, sdf.Translate3d(pb1.ToV3(-0.5*bHeight))) | |
return sdf.Union3D(fp, b0, b1), nil | |
} | |
//----------------------------------------------------------------------------- |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment