-
Notifications
You must be signed in to change notification settings - Fork 12
/
main.go
103 lines (89 loc) · 2.65 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package main
import (
"log"
"math"
"github.com/unixpickle/model3d/render3d"
"github.com/unixpickle/model3d/model3d"
"github.com/unixpickle/model3d/toolbox3d"
)
const (
SideHeight = 2.0
SideMinRadius = 1.5
SideEdgeCut = 0.3
BarRadius = 0.4
BarSlack = 0.02
BarLength = 5.0
BarTotalLength = BarLength + SideHeight
// Cause a slope of more than 45 degrees to prevent
// support structures.
ZWithExtraSlope = 0.999
)
func main() {
sideWithHole := &model3d.SubtractedSolid{
Positive: CreateSide().Solid(),
Negative: &model3d.Cylinder{
P1: model3d.Z(SideHeight / 2),
P2: model3d.Z(SideHeight + 1e-5),
Radius: BarRadius + BarSlack,
},
}
log.Println("Creating meshes...")
squeeze := toolbox3d.NewSmartSqueeze(toolbox3d.AxisZ, 0, 0.03, 0)
squeeze.AddUnsqueezable(0, SideEdgeCut+0.02)
squeeze.AddUnsqueezable(SideHeight-SideEdgeCut-0.02, SideHeight)
squeeze.AddPinch(SideHeight / 2)
mesh := squeeze.MarchingCubesSearch(sideWithHole, 0.01, 16)
squeeze.Pinches = nil
squeeze.Unsqueezable = nil
squeeze.AddPinch(0)
squeeze.AddPinch(BarTotalLength)
bar := &model3d.Cylinder{
P2: model3d.Z(BarTotalLength),
Radius: BarRadius,
}
barMesh := squeeze.MarchingCubesSearch(bar, 0.01, 16)
log.Println("Simplifying meshes...")
mesh = mesh.EliminateCoplanar(1e-5)
barMesh = barMesh.EliminateCoplanar(1e-5)
log.Println("Saving meshes...")
mesh.SaveGroupedSTL("side.stl")
barMesh.SaveGroupedSTL("bar.stl")
log.Println("Rendering...")
render3d.SaveRandomGrid("rendering_side.png", mesh, 3, 3, 300, nil)
render3d.SaveRandomGrid("rendering_bar.png", barMesh, 3, 3, 300, nil)
}
func CreateSide() model3d.ConvexPolytope {
rawShape := model3d.ConvexPolytope{
&model3d.LinearConstraint{
Normal: model3d.Z(1),
Max: SideHeight,
},
&model3d.LinearConstraint{
Normal: model3d.Z(-1),
Max: 0,
},
}
for i := 0; i < 6; i++ {
theta := float64(i) / 6 * math.Pi * 2
normal := model3d.XY(math.Cos(theta), math.Sin(theta))
rawShape = append(rawShape, &model3d.LinearConstraint{
Normal: normal,
Max: SideMinRadius,
})
// Do the top edge cut.
angledUp := normal.Add(model3d.Z(ZWithExtraSlope)).Normalize()
topPoint := normal.Scale(SideMinRadius - SideEdgeCut).Add(model3d.Z(SideHeight))
rawShape = append(rawShape, &model3d.LinearConstraint{
Normal: angledUp,
Max: angledUp.Dot(topPoint),
})
// Do the bottom edge cut.
angledDown := normal.Add(model3d.Z(-ZWithExtraSlope)).Normalize()
bottomPoint := normal.Scale(SideMinRadius - SideEdgeCut)
rawShape = append(rawShape, &model3d.LinearConstraint{
Normal: angledDown,
Max: angledDown.Dot(bottomPoint),
})
}
return rawShape
}