Skip to content

Commit 10ae73b

Browse files
committed
Vector types have been implemented in their own packages (See ./vec).
A type alias (./sdf/alias.go) keeps older code working (to be removed eventually...) There are a couple of breaking changes: All vector type conversion functions are in the ./conv package. No more .ToV3(), .ToV3i() etc. Integer vector components are now referenced by .X .Y .Z rather than by [0] [1] [2].
1 parent 9c5bcf2 commit 10ae73b

31 files changed

+353
-1025
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
DIRS = $(wildcard ./examples/*/.)
33

4-
all clean:
4+
all clean hash:
55
for dir in $(DIRS); do \
66
$(MAKE) -C $$dir $@ || exit 1; \
77
done

examples/axoloti/main.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/deadsy/sdfx/obj"
1515
"github.com/deadsy/sdfx/render"
1616
"github.com/deadsy/sdfx/sdf"
17+
"github.com/deadsy/sdfx/vec/conv"
1718
)
1819

1920
//-----------------------------------------------------------------------------
@@ -217,8 +218,8 @@ func frontPanel() (sdf.SDF3, error) {
217218
// Add buttons to the finger button
218219
bHeight := 4.0
219220
b, _ := sdf.Cylinder3D(bHeight, 1.4, 0)
220-
b0 := sdf.Transform3D(b, sdf.Translate3d(pb0.ToV3(-0.5*bHeight)))
221-
b1 := sdf.Transform3D(b, sdf.Translate3d(pb1.ToV3(-0.5*bHeight)))
221+
b0 := sdf.Transform3D(b, sdf.Translate3d(conv.V2ToV3(pb0, -0.5*bHeight)))
222+
b1 := sdf.Transform3D(b, sdf.Translate3d(conv.V2ToV3(pb1, -0.5*bHeight)))
222223

223224
return sdf.Union3D(fp, b0, b1), nil
224225
}

examples/cylinder_head/SHA1SUM

+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
fd81ca2704865f9f236aaae2cd0e7889341eb482 head2.stl
12
81329c1098ac9bba0043e6507868fd5337d69d9e head.stl

examples/fidget/main.go

+18-16
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import (
1414
"github.com/deadsy/sdfx/obj"
1515
"github.com/deadsy/sdfx/render"
1616
"github.com/deadsy/sdfx/sdf"
17+
"github.com/deadsy/sdfx/vec/conv"
18+
"github.com/deadsy/sdfx/vec/p2"
1719
)
1820

1921
//-----------------------------------------------------------------------------
@@ -42,28 +44,28 @@ func flower(n int, r0, r1, r2 float64) (sdf.SDF2, error) {
4244
theta := sdf.Tau / float64(n)
4345
b := sdf.NewBezier()
4446

45-
p0 := sdf.V2{r1, 0}.Add(sdf.PolarToXY(r0, sdf.DtoR(-135)))
46-
p1 := sdf.V2{r1, 0}.Add(sdf.PolarToXY(r0, sdf.DtoR(-45)))
47-
p2 := sdf.V2{r1, 0}.Add(sdf.PolarToXY(r0, sdf.DtoR(45)))
48-
p3 := sdf.V2{r1, 0}.Add(sdf.PolarToXY(r0, sdf.DtoR(135)))
49-
p4 := sdf.PolarToXY(r2, theta/2)
47+
k0 := sdf.V2{r1, 0}.Add(conv.P2ToV2(p2.Vec{r0, sdf.DtoR(-135)}))
48+
k1 := sdf.V2{r1, 0}.Add(conv.P2ToV2(p2.Vec{r0, sdf.DtoR(-45)}))
49+
k2 := sdf.V2{r1, 0}.Add(conv.P2ToV2(p2.Vec{r0, sdf.DtoR(45)}))
50+
k3 := sdf.V2{r1, 0}.Add(conv.P2ToV2(p2.Vec{r0, sdf.DtoR(135)}))
51+
k4 := conv.P2ToV2(p2.Vec{r2, theta / 2})
5052

5153
m := sdf.Rotate(theta)
5254

5355
for i := 0; i < n; i++ {
5456
ofs := float64(i) * theta
5557

56-
b.AddV2(p0).Handle(ofs+sdf.DtoR(-45), r0/2, r0/2)
57-
b.AddV2(p1).Handle(ofs+sdf.DtoR(45), r0/2, r0/2)
58-
b.AddV2(p2).Handle(ofs+sdf.DtoR(135), r0/2, r0/2)
59-
b.AddV2(p3).Handle(ofs+sdf.DtoR(225), r0/2, r0/2)
60-
b.AddV2(p4).Handle(ofs+theta/2+sdf.DtoR(90), r2/1.5, r2/1.5)
61-
62-
p0 = m.MulPosition(p0)
63-
p1 = m.MulPosition(p1)
64-
p2 = m.MulPosition(p2)
65-
p3 = m.MulPosition(p3)
66-
p4 = m.MulPosition(p4)
58+
b.AddV2(k0).Handle(ofs+sdf.DtoR(-45), r0/2, r0/2)
59+
b.AddV2(k1).Handle(ofs+sdf.DtoR(45), r0/2, r0/2)
60+
b.AddV2(k2).Handle(ofs+sdf.DtoR(135), r0/2, r0/2)
61+
b.AddV2(k3).Handle(ofs+sdf.DtoR(225), r0/2, r0/2)
62+
b.AddV2(k4).Handle(ofs+theta/2+sdf.DtoR(90), r2/1.5, r2/1.5)
63+
64+
k0 = m.MulPosition(k0)
65+
k1 = m.MulPosition(k1)
66+
k2 = m.MulPosition(k2)
67+
k3 = m.MulPosition(k3)
68+
k4 = m.MulPosition(k4)
6769
}
6870

6971
b.Close()

examples/square_flange/main.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/deadsy/sdfx/obj"
1515
"github.com/deadsy/sdfx/render"
1616
"github.com/deadsy/sdfx/sdf"
17+
"github.com/deadsy/sdfx/vec/conv"
1718
)
1819

1920
//-----------------------------------------------------------------------------
@@ -55,11 +56,11 @@ func flange() (sdf.SDF3, error) {
5556

5657
// outer pipe
5758
outerPipe, _ := sdf.Cylinder3D(2.0*pipeLength, pipeRadius+pipeWall, 0.0)
58-
outerPipe = sdf.Transform3D(outerPipe, sdf.Translate3d(pipeOffset.ToV3(0)))
59+
outerPipe = sdf.Transform3D(outerPipe, sdf.Translate3d(conv.V2ToV3(pipeOffset, 0)))
5960

6061
// inner pipe
6162
innerPipe, _ := sdf.Cylinder3D(2.0*pipeLength, pipeRadius, 0.0)
62-
innerPipe = sdf.Transform3D(innerPipe, sdf.Translate3d(pipeOffset.ToV3(0)))
63+
innerPipe = sdf.Transform3D(innerPipe, sdf.Translate3d(conv.V2ToV3(pipeOffset, 0)))
6364

6465
// combine the outer pipe and base (with a fillet)
6566
s0 := sdf.Union3D(base, outerPipe)

examples/voronoi/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func main() {
3939

4040
// work out the region we will sample
4141
bb := s0.BoundingBox().ScaleAboutCenter(k)
42-
log.Printf("rendering %s (%dx%d)\n", path, pixels[0], pixels[1])
42+
log.Printf("rendering %s (%dx%d)\n", path, pixels.X, pixels.Y)
4343
d, err := render.NewPNG(path, bb, pixels)
4444
if err != nil {
4545
log.Fatalf("error: %s", err)

obj/arrow.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ func DirectedArrow3D(k *ArrowParms, head, tail sdf.V3) (sdf.SDF3, error) {
173173
}
174174
// position the arrow
175175
ofs := head.Add(tail).MulScalar(0.5)
176-
m := sdf.Translate3d(ofs).Mul(sdf.V3{0, 0, 1}.RotateToVector(v))
176+
m := sdf.Translate3d(ofs).Mul(sdf.RotateToVector(sdf.V3{0, 0, 1}, v))
177177
return sdf.Transform3D(arrow, m), nil
178178
}
179179

render/dc/dc3v1.go

+14-13
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020

2121
"github.com/deadsy/sdfx/render"
2222
"github.com/deadsy/sdfx/sdf"
23+
"github.com/deadsy/sdfx/vec/conv"
2324
"gonum.org/v1/gonum/mat"
2425
)
2526

@@ -48,8 +49,8 @@ func NewDualContouringV1(simplify float64, RCond float64, lockVertices bool) *Du
4849
func (m *DualContouringV1) Info(s sdf.SDF3, meshCells int) string {
4950
bbSize := s.BoundingBox().Size()
5051
resolution := bbSize.MaxComponent() / float64(meshCells)
51-
cells := bbSize.DivScalar(resolution).ToV3i()
52-
return fmt.Sprintf("%dx%dx%d, resolution %.2f", cells[0], cells[1], cells[2], resolution)
52+
cells := conv.V3ToV3i(bbSize.DivScalar(resolution))
53+
return fmt.Sprintf("%dx%dx%d, resolution %.2f", cells.X, cells.Y, cells.Z, resolution)
5354
}
5455

5556
// Render produces a 3d triangle mesh over the bounding volume of an sdf3.
@@ -60,7 +61,7 @@ func (m *DualContouringV1) Render(s sdf.SDF3, meshCells int, output chan<- *rend
6061
// work out the sampling resolution to use
6162
bbSize := s.BoundingBox().Size()
6263
resolution := bbSize.MaxComponent() / float64(meshCells)
63-
cells := bbSize.DivScalar(resolution).ToV3i()
64+
cells := conv.V3ToV3i(bbSize.DivScalar(resolution))
6465
// Build the octree
6566
dcOctreeRootNode := dcNewOctree(cells, m.RCond, m.LockVertices)
6667
dcOctreeRootNode.Populate(s)
@@ -170,12 +171,12 @@ func nextPowerOfTwo(v int) int {
170171
// dcNewOctree builds the whole octree structure (without simplification) for the given size.
171172
func dcNewOctree(cellCounts sdf.V3i, rCond float64, lockVertices bool) *dcOctree {
172173
cellCounts = sdf.V3i{ // Need powers of 2 for this algorithm (round-up for more precision)
173-
nextPowerOfTwo(cellCounts[0]),
174-
nextPowerOfTwo(cellCounts[1]),
175-
nextPowerOfTwo(cellCounts[2]),
174+
nextPowerOfTwo(cellCounts.X),
175+
nextPowerOfTwo(cellCounts.Y),
176+
nextPowerOfTwo(cellCounts.Z),
176177
}
177178
// Compute the complete octree with the largest component as the size and then ignoring cells outside of bounds
178-
cubicSize := int(cellCounts.ToV3().MaxComponent())
179+
cubicSize := int(conv.V3iToV3(cellCounts).MaxComponent())
179180
rootNode := &dcOctree{
180181
kind: dcOctreeNodeTypeInternal,
181182
minOffset: sdf.V3i{0, 0, 0},
@@ -196,14 +197,14 @@ func (node *dcOctree) Populate(d sdf.SDF3) {
196197
cellCounts := node.cellCounts
197198
maxOffset := minOffset.AddScalar(meshSize)
198199
// Avoid generating any octree node outside the bounding volume (may filter before reaching leaves)
199-
if minOffset[0] > (meshSize+cellCounts[0])/2 || maxOffset[0] < (meshSize-cellCounts[0])/2 ||
200-
minOffset[1] > (meshSize+cellCounts[1])/2 || maxOffset[1] < (meshSize-cellCounts[1])/2 ||
201-
minOffset[2] > (meshSize+cellCounts[2])/2 || maxOffset[2] < (meshSize-cellCounts[2])/2 {
200+
if minOffset.X > (meshSize+cellCounts.X)/2 || maxOffset.X < (meshSize-cellCounts.X)/2 ||
201+
minOffset.Y > (meshSize+cellCounts.Y)/2 || maxOffset.Y < (meshSize-cellCounts.Y)/2 ||
202+
minOffset.Z > (meshSize+cellCounts.Z)/2 || maxOffset.Z < (meshSize-cellCounts.Z)/2 {
202203
return
203204
}
204205
childSize := node.size / 2
205206
for i := 0; i < 8; i++ {
206-
childMinOffset := minOffset.Add(dcChildMinOffsets[i].ToV3().MulScalar(float64(childSize)).ToV3i())
207+
childMinOffset := minOffset.Add(conv.V3ToV3i(conv.V3iToV3(dcChildMinOffsets[i]).MulScalar(float64(childSize))))
207208
node.children[i] = &dcOctree{
208209
kind: dcOctreeNodeTypeInternal,
209210
minOffset: childMinOffset,
@@ -226,8 +227,8 @@ func (node *dcOctree) Populate(d sdf.SDF3) {
226227

227228
func (node *dcOctree) relToSDF(d sdf.SDF3, i sdf.V3i) sdf.V3 {
228229
bb := d.BoundingBox()
229-
return bb.Min.Add(bb.Size().Mul(i.ToV3().DivScalar(float64(node.meshSize)).
230-
Div(node.cellCounts.ToV3().DivScalar(float64(node.meshSize)))))
230+
return bb.Min.Add(bb.Size().Mul(conv.V3iToV3(i).DivScalar(float64(node.meshSize)).
231+
Div(conv.V3iToV3(node.cellCounts).DivScalar(float64(node.meshSize)))))
231232
}
232233

233234
// computeOctreeLeaf computes the required leaf information that later will be used for meshing

render/dc/dc3v2.go

+16-15
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919

2020
"github.com/deadsy/sdfx/render"
2121
"github.com/deadsy/sdfx/sdf"
22+
"github.com/deadsy/sdfx/vec/conv"
2223
)
2324

2425
//-----------------------------------------------------------------------------
@@ -68,7 +69,7 @@ func NewDualContouringV2(farAway float64, centerPush float64, raycastScaleAndSig
6869
// Info returns a string describing the rendered volume.
6970
func (dc *DualContouringV2) Info(s sdf.SDF3, meshCells int) string {
7071
resolution, cells := dc.getCells(s, meshCells)
71-
return fmt.Sprintf("%dx%dx%d, resolution %.2f", cells[0], cells[1], cells[2], resolution)
72+
return fmt.Sprintf("%dx%dx%d, resolution %.2f", cells.X, cells.Y, cells.Z, resolution)
7273
}
7374

7475
// Render produces a 3d triangle mesh over the bounding volume of an sdf3.
@@ -84,7 +85,7 @@ func (dc *DualContouringV2) Render(s sdf.SDF3, meshCells int, output chan<- *ren
8485
func (dc *DualContouringV2) getCells(s sdf.SDF3, meshCells int) (float64, sdf.V3i) {
8586
bbSize := s.BoundingBox().Size()
8687
resolution := bbSize.MaxComponent() / float64(meshCells)
87-
return resolution, bbSize.DivScalar(resolution).ToV3i()
88+
return resolution, conv.V3ToV3i(bbSize.DivScalar(resolution))
8889
}
8990

9091
//-----------------------------------------------------------------------------
@@ -156,23 +157,23 @@ type dcVoxelInfo struct {
156157

157158
func (dc *DualContouringV2) placeVertices(s *dcSdf, cells sdf.V3i) (buf []sdf.V3, bufMap []*dcVoxelInfo, bufMapIndexed map[sdf.V3i]*dcVoxelInfo) {
158159
// Start with big enough buffers for performance avoiding allocations (but not too big, may expand later)
159-
buf = make([]sdf.V3, 0, dcMaxI(32, cells[0]*cells[1]*cells[2]/100))
160-
bufMap = make([]*dcVoxelInfo, 0, dcMaxI(32, cells[0]*cells[1]*cells[2]/100))
161-
bufMapIndexed = make(map[sdf.V3i]*dcVoxelInfo, dcMaxI(32, cells[0]*cells[1]*cells[2]/100))
160+
buf = make([]sdf.V3, 0, dcMaxI(32, cells.X*cells.Y*cells.Z/100))
161+
bufMap = make([]*dcVoxelInfo, 0, dcMaxI(32, cells.X*cells.Y*cells.Z/100))
162+
bufMapIndexed = make(map[sdf.V3i]*dcVoxelInfo, dcMaxI(32, cells.X*cells.Y*cells.Z/100))
162163
// Other pre-allocated vertex placing buffers
163164
normals := make([]sdf.V3, 0, 11)
164165
planeDs := make([]float64, 0, 11)
165166
// Some cached variables
166167
bb := s.BoundingBox()
167-
cellSize := bb.Size().Div(cells.ToV3())
168+
cellSize := bb.Size().Div(conv.V3iToV3(cells))
168169
cellSizeHalf := cellSize.DivScalar(2)
169170
cellIndex := sdf.V3i{}
170171
// Iterate over all cells (could be parallelized, synchronizing on each vertex positioned)
171-
for cellIndex[0] = 0; cellIndex[0] < cells[0]; cellIndex[0]++ {
172-
for cellIndex[1] = 0; cellIndex[1] < cells[1]; cellIndex[1]++ {
173-
for cellIndex[2] = 0; cellIndex[2] < cells[2]; cellIndex[2]++ {
172+
for cellIndex.X = 0; cellIndex.X < cells.X; cellIndex.X++ {
173+
for cellIndex.Y = 0; cellIndex.Y < cells.Y; cellIndex.Y++ {
174+
for cellIndex.Z = 0; cellIndex.Z < cells.Z; cellIndex.Z++ {
174175
// Generate each vertex (if the surface crosses the voxel)
175-
cellStart := bb.Min.Add(cellSize.Mul(cellIndex.ToV3()))
176+
cellStart := bb.Min.Add(cellSize.Mul(conv.V3iToV3(cellIndex)))
176177
cellCenter := cellStart.Add(cellSizeHalf)
177178
vertexPos := dc.placeVertex(s, cellStart, cellCenter, cellSize, normals[:0], planeDs[:0])
178179
if !math.IsInf(vertexPos.X, 0) {
@@ -203,12 +204,12 @@ func (dc *DualContouringV2) placeVertex(s *dcSdf, cellStart, cellCenter, cellSiz
203204

204205
//// Add candidate planes from all surface-crossing edges (using the surface point on the edge)
205206
for _, edge := range dcEdges { // Use edges instead of corners to generate less positions and normals.
206-
if ((inside >> edge[0]) & 1) == ((inside >> edge[1]) & 1) { // Not crossing edge
207+
if ((inside >> edge.X) & 1) == ((inside >> edge.Y) & 1) { // Not crossing edge
207208
continue
208209
}
209210
//crossingCorners = crossingCorners | (1 << edge[0]) | (1 << edge[1])
210-
cornerPos1 := cellStart.Add(dcCorners[edge[0]].Mul(cellSize))
211-
cornerPos2 := cellStart.Add(dcCorners[edge[1]].Mul(cellSize))
211+
cornerPos1 := cellStart.Add(dcCorners[edge.X].Mul(cellSize))
212+
cornerPos2 := cellStart.Add(dcCorners[edge.Y].Mul(cellSize))
212213
//edgeSurfPos := dcApproximateZeroCrossingPosition(s, cornerPos1, cornerPos2)
213214
dir := cornerPos2.Sub(cornerPos1)
214215
dirLength := dir.Length()
@@ -291,7 +292,7 @@ func (dc *DualContouringV2) generateTriangles(s *dcSdf, vertices []sdf.V3, info
291292
// Connect to triangles in the 3 main axes (two triangles each, if crossing the surface)
292293
for ai := 0; ai < 3; ai++ {
293294
edge := dcFarEdges[ai]
294-
if ((inside >> edge[0]) & 1) == ((inside >> edge[1]) & 1) {
295+
if ((inside >> edge.X) & 1) == ((inside >> edge.Y) & 1) {
295296
continue // Not a crossing
296297
}
297298

@@ -324,7 +325,7 @@ func (dc *DualContouringV2) generateTriangles(s *dcSdf, vertices []sdf.V3, info
324325
t1 := &render.Triangle3{V: [3]sdf.V3{vertices[v0], vertices[v3.bufIndex], vertices[v2.bufIndex]}}
325326

326327
// Get the normals right:
327-
if ((inside >> edge[0]) & 1) != uint8(ai&1) { // xor
328+
if ((inside >> edge.X) & 1) != uint8(ai&1) { // xor
328329
t0 = dcFlip(t0)
329330
t1 = dcFlip(t1)
330331
}

render/delaunay.go

+7-5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import (
1919
"sort"
2020

2121
"github.com/deadsy/sdfx/sdf"
22+
"github.com/deadsy/sdfx/vec/conv"
23+
v2 "github.com/deadsy/sdfx/vec/v2"
2224
)
2325

2426
//-----------------------------------------------------------------------------
@@ -243,7 +245,7 @@ func Delaunay2d(vs sdf.V2Set) (TriangleISet, error) {
243245
n := len(vs)
244246

245247
// sort the vertices by x value
246-
sort.Sort(sdf.V2SetByX(vs))
248+
sort.Sort(v2.VecSetByX(vs))
247249

248250
// work out the super triangle
249251
t, err := superTriangle(vs)
@@ -369,9 +371,9 @@ func Delaunay2dSlow(vs sdf.V2Set) (TriangleISet, error) {
369371

370372
t := TriangleI{c[0], c[1], c[2]}
371373

372-
p0 := vs[t[0]].ToV3(z[t[0]])
373-
p1 := vs[t[1]].ToV3(z[t[1]])
374-
p2 := vs[t[2]].ToV3(z[t[2]])
374+
p0 := conv.V2ToV3(vs[t[0]], z[t[0]])
375+
p1 := conv.V2ToV3(vs[t[1]], z[t[1]])
376+
p2 := conv.V2ToV3(vs[t[2]], z[t[2]])
375377

376378
norm := p1.Sub(p0).Cross(p2.Sub(p1))
377379

@@ -389,7 +391,7 @@ func Delaunay2dSlow(vs sdf.V2Set) (TriangleISet, error) {
389391
// on the plane
390392
continue
391393
}
392-
pi := v.ToV3(z[i])
394+
pi := conv.V2ToV3(v, z[i])
393395
if pi.Sub(p0).Dot(norm) > 0 {
394396
// below the plane
395397
hull = false

render/dxf.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"sync"
1515

1616
"github.com/deadsy/sdfx/sdf"
17+
"github.com/deadsy/sdfx/vec/conv"
1718
"github.com/yofu/dxf"
1819
"github.com/yofu/dxf/color"
1920
"github.com/yofu/dxf/drawing"
@@ -138,9 +139,9 @@ func RenderDXF(
138139
// work out the sampling resolution to use
139140
bbSize := s.BoundingBox().Size()
140141
resolution := bbSize.MaxComponent() / float64(meshCells)
141-
cells := bbSize.DivScalar(resolution).ToV2i()
142+
cells := conv.V2ToV2i(bbSize.MulScalar(1 / resolution))
142143

143-
fmt.Printf("rendering %s (%dx%d, resolution %.2f)\n", path, cells[0], cells[1], resolution)
144+
fmt.Printf("rendering %s (%dx%d, resolution %.2f)\n", path, cells.X, cells.Y, resolution)
144145

145146
// write the line segments to a DXF file
146147
var wg sync.WaitGroup
@@ -169,13 +170,13 @@ func RenderDXFSlow(
169170
bb0 := s.BoundingBox()
170171
bb0Size := bb0.Size()
171172
meshInc := bb0Size.MaxComponent() / float64(meshCells)
172-
bb1Size := bb0Size.DivScalar(meshInc)
173+
bb1Size := bb0Size.MulScalar(1 / meshInc)
173174
bb1Size = bb1Size.Ceil().AddScalar(1)
174-
cells := bb1Size.ToV2i()
175+
cells := conv.V2ToV2i(bb1Size)
175176
bb1Size = bb1Size.MulScalar(meshInc)
176177
bb := sdf.NewBox2(bb0.Center(), bb1Size)
177178

178-
fmt.Printf("rendering %s (%dx%d)\n", path, cells[0], cells[1])
179+
fmt.Printf("rendering %s (%dx%d)\n", path, cells.X, cells.Y)
179180

180181
// run marching squares to generate the line segments
181182
m := marchingSquares(s, bb, meshInc)

0 commit comments

Comments
 (0)