From 78f3aae2fba36a8b1ed949f1bb41475028c07967 Mon Sep 17 00:00:00 2001 From: Wouter Horlings Date: Fri, 28 May 2021 15:16:44 +0200 Subject: [PATCH] Add box struct --- box.go | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++ box_test.go | 51 ++++++++++++++++++++++++++++ go.mod | 5 +++ go.sum | 19 +++++++++++ 4 files changed, 173 insertions(+) create mode 100644 box.go create mode 100644 box_test.go create mode 100644 go.mod create mode 100644 go.sum diff --git a/box.go b/box.go new file mode 100644 index 0000000..1093229 --- /dev/null +++ b/box.go @@ -0,0 +1,98 @@ +package objects + +import ( + "github.com/deadsy/sdfx/sdf" + "math" +) + +type BoxParams struct { + Size sdf.V3 // internal box size + Wall float64 // wall thickness + BottomTopRatio float64 // ratio between the height of the top and the bottom + CornerRadius float64 // radius of rounded corners + Taper float64 // angle of split + ClosingHeight float64 // height of the closing + Margin float64 // Margin for closing + Text string +} + +func Box3D(k *BoxParams) (top sdf.SDF3, bottom sdf.SDF3, err error) { + top, err = TopBox3D(k) + bottom, err = TopBox3D(k) + if err != nil { + return + } + return +} + +func baseBox3D(k *BoxParams) (sdf.SDF3, error) { + box, err := sdf.Box3D(k.Size.AddScalar(k.Wall*2), k.CornerRadius) + if err != nil { + return nil, err + } + return box, nil +} + +func TopBox3D(k *BoxParams) (top sdf.SDF3, err error) { + box, err := baseBox3D(k) + if err != nil { + return + } + a := sdf.V3{X: 0, Y: 0, Z: 0.5 - k.BottomTopRatio}.Mul(k.Size).Add(sdf.V3{X: 0, Y: 0, Z: k.ClosingHeight / 2}) + n := sdf.V3{X: 0, Y: 0, Z: 1} + top = sdf.Cut3D(box, a, n) + closing, err := InnerClosing(k) + if err != nil { + return + } + top = sdf.Union3D(top,closing) + return +} + +func BottomBox3D(k *BoxParams) (bottom sdf.SDF3, err error) { + box, err := baseBox3D(k) + if err != nil { + return + } + a := sdf.V3{X: 0, Y: 0, Z: 0.5 - k.BottomTopRatio}.Mul(k.Size).Add(sdf.V3{X: 0, Y: 0, Z: k.ClosingHeight / 2}) + n := sdf.V3{X: 0, Y: 0, Z: -1} + bottom = sdf.Cut3D(box, a, n) + closing, err := InnerClosing(k) + scale := k.Size.Add(sdf.V3{X: k.Margin, Y: k.Margin, Z: 0}).Div(k.Size) + closing = sdf.Transform3D(closing, sdf.Scale3d(scale)) + if err != nil { + return + } + bottom = sdf.Difference3D(bottom,closing) + return +} + +func InnerClosing(k *BoxParams) (closing sdf.SDF3, err error) { + offset := math.Tan(k.Taper) * k.ClosingHeight / 2 + size := sdf.V2{X: k.Size.X, Y: k.Size.Y} + s1 := sdf.Box2D(size.AddScalar(k.Wall-offset), k.CornerRadius) + s2 := sdf.Box2D(size.AddScalar(k.Wall+offset), k.CornerRadius) + closing, err = sdf.Loft3D(s1, s2, k.ClosingHeight, 0) + if err != nil { + return + } + closing = sdf.Transform3D(closing, sdf.Translate3d(sdf.V3{0,0,0.5-k.BottomTopRatio}.Mul(k.Size))) + return +} + +func OuterClosing(k *BoxParams) (closing sdf.SDF3, err error) { + s0, err := InnerClosing(k) + if err != nil { + return + } + s1, err := baseBox3D(k) + if err != nil { + return + } + a := sdf.V3{0, 0, k.ClosingHeight / 2} + n := sdf.V3{0, 0, -1} + s1 = sdf.Cut3D(s1, a, n) + s1 = sdf.Cut3D(s1, a.Neg(), n.Neg()) + closing = sdf.Difference3D(s1, s0) + return +} diff --git a/box_test.go b/box_test.go new file mode 100644 index 0000000..9ed1644 --- /dev/null +++ b/box_test.go @@ -0,0 +1,51 @@ +package objects + +import ( + "github.com/deadsy/sdfx/render" + "github.com/deadsy/sdfx/sdf" + "testing" +) + +var k = BoxParams{ + Size: sdf.V3{X: 40, Y: 40, Z: 40}, + CornerRadius: 6.0, + BottomTopRatio: 0.3, + Wall: 3, + ClosingHeight: 4, + Taper: 0.2, + Margin: 0.2, +} + +func TestBottomBox3D(t *testing.T) { + bottom, err := BottomBox3D(&k) + if err != nil { + t.Failed() + return + } + render.RenderSTL(bottom, 400, "test_box_bottom.stl") +} + +func TestTopBox3D(t *testing.T) { + top, err := TopBox3D(&k) + if err != nil { + t.Failed() + return + } + render.RenderSTL(top, 100, "test_box_top.stl") +} + +func TestInnerClosing(t *testing.T) { + stl, err := InnerClosing(&k) + if err != nil { + t.FailNow() + } + render.RenderSTL(stl, 100, "inner_closing.stl") +} + +func TestOuterClosing(t *testing.T) { + stl, err := OuterClosing(&k) + if err != nil { + t.FailNow() + } + render.RenderSTL(stl, 100, "outer_closing.stl") +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..5d2f822 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module git.wtrh.nl/3D-models/objects + +go 1.16 + +require github.com/deadsy/sdfx v0.0.0-20210428225541-69bac33c47f0 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..7d740ef --- /dev/null +++ b/go.sum @@ -0,0 +1,19 @@ +github.com/ajstarks/svgo v0.0.0-20200725142600-7a3c8b57fecb h1:EVl3FJLQCzSbgBezKo/1A4ADnJ4mtJZ0RvnNzDJ44nY= +github.com/ajstarks/svgo v0.0.0-20200725142600-7a3c8b57fecb/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +github.com/deadsy/sdfx v0.0.0-20210428225541-69bac33c47f0 h1:nCkBC+PowWnmkCMe+3cCOtxpNVw+R1TQI8hzmCmPyKI= +github.com/deadsy/sdfx v0.0.0-20210428225541-69bac33c47f0/go.mod h1:abZaCad/jNP8KcO+XMyLX6C/cZOdnwefasReJEva4cE= +github.com/go-gl/gl v0.0.0-20180407155706-68e253793080/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk= +github.com/go-gl/glfw v0.0.0-20180426074136-46a8d530c326/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/llgcode/draw2d v0.0.0-20200930101115-bfaf5d914d1e h1:YRRazju3DMGuZTSWEj0nE2SCRcK3DW/qdHQ4UQx7sgs= +github.com/llgcode/draw2d v0.0.0-20200930101115-bfaf5d914d1e/go.mod h1:mVa0dA29Db2S4LVqDYLlsePDzRJLDfdhVZiI15uY0FA= +github.com/llgcode/ps v0.0.0-20150911083025-f1443b32eedb h1:61ndUreYSlWFeCY44JxDDkngVoI7/1MVhEl98Nm0KOk= +github.com/llgcode/ps v0.0.0-20150911083025-f1443b32eedb/go.mod h1:1l8ky+Ew27CMX29uG+a2hNOKpeNYEQjjtiALiBlFQbY= +github.com/yofu/dxf v0.0.0-20190710012328-5a6d1e83f16c h1:qgsxLgTXCVH8Dxar36HI5af2ZfinVz5vF8erPpyzM+A= +github.com/yofu/dxf v0.0.0-20190710012328-5a6d1e83f16c/go.mod h1:gnT4GQzgKW8+TLI0xheUgdmNV4dsAN0WJUVnztRZkfI= +golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= +golang.org/x/image v0.0.0-20201208152932-35266b937fa6 h1:nfeHNc1nAqecKCy2FCy4HY+soOOe5sDLJ/gZLbx6GYI= +golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=