Skip to content

Commit 2abbb3e

Browse files
authored
fix(modeling): various fixes, style changes, and small enhancements
* feat(modeling): allow appendArc, appendBezier, appendPoints to closed paths * fix(modeling): corrected snap of path2 and path3 when closed * docs(modeling): changes from reviews * fix(modeling): small fix to parameter checks * perf(modeling): small performace changes * fix(modeling): corrected close, reverse, and transform functions in geometries * perf(modeling): changed extrudeLinearGeom2 to use preallocated mat4 and vec3 * build(all): changed linting to use eslint directly * style(all): changes based on lint * style(all): small fixes for consistent return values * style(all): changes for consistent default case statements * style(all): changes for consistent assignment statements * style(all): changes for consistent blocks * fix(modeling): corrected retessellateCoplanarPolygons to ignore pourly constructed polygons * fix(modeling): stronger validation of polygons in geom3 objects * test(modeling): small adjustments to tests due to changes
1 parent 9443688 commit 2abbb3e

5 files changed

Lines changed: 45 additions & 8 deletions

File tree

packages/modeling/src/geometries/geom3/validate.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,17 @@ export const validate = (object) => {
2222
}
2323

2424
// check polygons
25-
object.polygons.forEach(poly3.validate)
25+
object.polygons.forEach((p, i) => {
26+
if (p.vertices.length < 3) {
27+
throw new Error(`invalid polygon ${i}: only ${p.vertices.length} vertices`)
28+
}
29+
30+
try {
31+
poly3.validate(p)
32+
} catch (e) {
33+
throw new Error(`invalid polygon ${i}: ${e}`)
34+
}
35+
})
2636
validateManifold(object)
2737

2838
// check transforms

packages/modeling/src/operations/modifiers/reTesselateCoplanarPolygons.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -317,8 +317,8 @@ export const reTesselateCoplanarPolygons = (sourcePolygons) => {
317317
const vertices3d = points2d.map((point2d) => orthonormalFormula.to3D(point2d))
318318
const polygon = poly3.fromVerticesAndPlane(vertices3d, plane) // TODO support shared
319319

320-
// if we let empty polygon out, next retesselate will crash
321-
if (polygon.vertices.length) destPolygons.push(polygon)
320+
// if we let invalid polygons out, next retesselate will crash
321+
if (polygon.vertices.length > 2) destPolygons.push(polygon)
322322
}
323323
}
324324
} // if(yIndex > 0)

packages/modeling/src/operations/modifiers/reTesselateCoplanarPolygons.test.js

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ test('retessellateCoplanarPolygons: should merge coplanar polygons', (t) => {
6666
polyL = translatePoly3([-15, -15, -15], polyE)
6767

6868
obs = reTesselateCoplanarPolygons([polyH, polyI, polyJ, polyK, polyL])
69-
t.is(obs.length, 1)
69+
obs.forEach((polygon) => {
70+
poly3.validate(polygon)
71+
})
7072
})
7173

7274
// Test for mark-and-filter optimization: multiple polygons that reach their
@@ -85,9 +87,8 @@ test('retessellateCoplanarPolygons: should correctly handle multiple polygon rem
8587
// Each triangle should be preserved (they don't overlap)
8688
t.is(obs.length, 3)
8789

88-
// Verify each polygon has 3 vertices (triangles)
8990
obs.forEach((polygon) => {
90-
t.is(polygon.vertices.length, 3)
91+
poly3.validate(polygon)
9192
})
9293
})
9394

@@ -103,3 +104,28 @@ test('retessellateCoplanarPolygons: should merge adjacent polygons with shared e
103104
t.is(obs.length, 1)
104105
t.is(obs[0].vertices.length, 4) // rectangle has 4 vertices
105106
})
107+
108+
test('retessellateCoplanarPolygons: should not return invalid polygons', (t) => {
109+
const polyA = poly3.create([
110+
[ 3.72172376113686, -3.7661089598376325, 13 ],
111+
[ 3.72172376113686, -3.7661089598376325, 13.515937566757202 ],
112+
[ 3.721663581864801, -3.766195461144145, 13.515937566757202 ]
113+
])
114+
const polyB = poly3.create([
115+
[ 3.721663581864801, -3.766195461144145, 13.0084828728813 ],
116+
[ 3.721663581864801, -3.766195461144145, 13.00100040435791 ],
117+
[ 3.721716664059388, -3.7661191611320772, 13.00100040435791 ]
118+
])
119+
const polyC = poly3.create([
120+
[ 3.721663581864801, -3.766195461144145, 13.515937566757202 ],
121+
[ 3.721663581864801, -3.766195461144145, 13.0084828728813 ],
122+
[ 3.7217166640593886, -3.766119161132077, 13.00100040435791 ],
123+
[ 3.7217236444490864, -3.766109127563903, 13.00100040435791 ]
124+
])
125+
const obs = reTesselateCoplanarPolygons([polyA, polyB, polyC])
126+
t.is(obs.length, 1)
127+
128+
obs.forEach((polygon) => {
129+
poly3.validate(polygon)
130+
})
131+
})

packages/modeling/src/operations/modifiers/retessellate.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export const retessellate = (geometry) => {
1818
return geometry
1919
}
2020

21+
// FIXME this is creating new polygons
2122
const polygons = geom3.toPolygons(geometry).map((polygon, index) => ({ vertices: polygon.vertices, plane: poly3.plane(polygon), index: index }))
2223
const classified = classifyPolygons(polygons)
2324

packages/modeling/src/operations/offsets/offsetGeom3.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,6 @@ test('offsetGeom3: offset completes properly, issue 876', (t) => {
9191

9292
const obs = offset({ delta: 1.3, corners: 'round', segments: 12 }, sub)
9393
t.notThrows.skip(() => geom3.validate(obs))
94-
t.is(measureArea(obs), 524.9674760547548)
95-
t.is(measureVolume(obs), 604.0599465573156)
94+
t.is(measureArea(obs), 524.9674756919702)
95+
t.is(measureVolume(obs), 604.0599468042326)
9696
})

0 commit comments

Comments
 (0)