UNPKG

@jscad/modeling

Version:

Constructive Solid Geometry (CSG) Library for JSCAD

227 lines (209 loc) 10.3 kB
const test = require('ava') const comparePolygonsAsPoints = require('../../../test/helpers/comparePolygonsAsPoints') const { TAU } = require('../../maths/constants') const { geom2, geom3, path2 } = require('../../geometries') const { extrudeLinear } = require('./index') test('extrudeLinear (defaults)', (t) => { const geometry2 = geom2.fromPoints([[5, 5], [-5, 5], [-5, -5], [5, -5]]) const geometry3 = extrudeLinear({ }, geometry2) const pts = geom3.toPoints(geometry3) const exp = [ [[5, -5, 0], [5, 5, 0], [5, 5, 1]], [[5, -5, 0], [5, 5, 1], [5, -5, 1]], [[5, 5, 0], [-5, 5, 0], [-5, 5, 1]], [[5, 5, 0], [-5, 5, 1], [5, 5, 1]], [[-5, 5, 0], [-5, -5, 0], [-5, -5, 1]], [[-5, 5, 0], [-5, -5, 1], [-5, 5, 1]], [[-5, -5, 0], [5, -5, 0], [5, -5, 1]], [[-5, -5, 0], [5, -5, 1], [-5, -5, 1]], [[-5, -5, 1], [5, -5, 1], [5, 5, 1]], [[5, 5, 1], [-5, 5, 1], [-5, -5, 1]], [[5, 5, 0], [5, -5, 0], [-5, -5, 0]], [[-5, -5, 0], [-5, 5, 0], [5, 5, 0]] ] t.notThrows(() => geom3.validate(geometry3)) t.is(pts.length, 12) t.true(comparePolygonsAsPoints(pts, exp)) }) test('extrudeLinear (no twist)', (t) => { const geometry2 = geom2.fromPoints([[5, 5], [-5, 5], [-5, -5], [5, -5]]) let geometry3 = extrudeLinear({ height: 15 }, geometry2) let pts = geom3.toPoints(geometry3) let exp = [ [[5, -5, 0], [5, 5, 0], [5, 5, 15]], [[5, -5, 0], [5, 5, 15], [5, -5, 15]], [[5, 5, 0], [-5, 5, 0], [-5, 5, 15]], [[5, 5, 0], [-5, 5, 15], [5, 5, 15]], [[-5, 5, 0], [-5, -5, 0], [-5, -5, 15]], [[-5, 5, 0], [-5, -5, 15], [-5, 5, 15]], [[-5, -5, 0], [5, -5, 0], [5, -5, 15]], [[-5, -5, 0], [5, -5, 15], [-5, -5, 15]], [[-5, -5, 15], [5, -5, 15], [5, 5, 15]], [[5, 5, 15], [-5, 5, 15], [-5, -5, 15]], [[5, 5, 0], [5, -5, 0], [-5, -5, 0]], [[-5, -5, 0], [-5, 5, 0], [5, 5, 0]] ] t.notThrows(() => geom3.validate(geometry3)) t.is(pts.length, 12) t.true(comparePolygonsAsPoints(pts, exp)) geometry3 = extrudeLinear({ height: -15 }, geometry2) pts = geom3.toPoints(geometry3) exp = [ [[5, 5, 0], [5, -5, 0], [5, -5, -15]], [[5, 5, 0], [5, -5, -15], [5, 5, -15]], [[-5, 5, 0], [5, 5, 0], [5, 5, -15]], [[-5, 5, 0], [5, 5, -15], [-5, 5, -15]], [[-5, -5, 0], [-5, 5, 0], [-5, 5, -15]], [[-5, -5, 0], [-5, 5, -15], [-5, -5, -15]], [[5, -5, 0], [-5, -5, 0], [-5, -5, -15]], [[5, -5, 0], [-5, -5, -15], [5, -5, -15]], [[-5, 5, -15], [5, 5, -15], [5, -5, -15]], [[5, -5, -15], [-5, -5, -15], [-5, 5, -15]], [[5, -5, 0], [5, 5, 0], [-5, 5, 0]], [[-5, 5, 0], [-5, -5, 0], [5, -5, 0]] ] t.notThrows(() => geom3.validate(geometry3)) t.is(pts.length, 12) t.true(comparePolygonsAsPoints(pts, exp)) }) test('extrudeLinear (twist)', (t) => { const geometry2 = geom2.fromPoints([[5, 5], [-5, 5], [-5, -5], [5, -5]]) let geometry3 = extrudeLinear({ height: 15, twistAngle: -TAU / 8 }, geometry2) let pts = geom3.toPoints(geometry3) let exp = [ [[5, -5, 0], [5, 5, 0], [7.0710678118654755, 4.440892098500626e-16, 15]], [[5, -5, 0], [7.0710678118654755, 4.440892098500626e-16, 15], [4.440892098500626e-16, -7.0710678118654755, 15]], [[5, 5, 0], [-5, 5, 0], [-4.440892098500626e-16, 7.0710678118654755, 15]], [[5, 5, 0], [-4.440892098500626e-16, 7.0710678118654755, 15], [7.0710678118654755, 4.440892098500626e-16, 15]], [[-5, 5, 0], [-5, -5, 0], [-7.0710678118654755, -4.440892098500626e-16, 15]], [[-5, 5, 0], [-7.0710678118654755, -4.440892098500626e-16, 15], [-4.440892098500626e-16, 7.0710678118654755, 15]], [[-5, -5, 0], [5, -5, 0], [4.440892098500626e-16, -7.0710678118654755, 15]], [[-5, -5, 0], [4.440892098500626e-16, -7.0710678118654755, 15], [-7.0710678118654755, -4.440892098500626e-16, 15]], [ [-7.0710678118654755, -4.440892098500626e-16, 15], [4.440892098500626e-16, -7.0710678118654755, 15], [7.0710678118654755, 4.440892098500626e-16, 15] ], [ [7.0710678118654755, 4.440892098500626e-16, 15], [-4.440892098500626e-16, 7.0710678118654755, 15], [-7.0710678118654755, -4.440892098500626e-16, 15] ], [[5, 5, 0], [5, -5, 0], [-5, -5, 0]], [[-5, -5, 0], [-5, 5, 0], [5, 5, 0]] ] t.notThrows(() => geom3.validate(geometry3)) t.is(pts.length, 12) t.true(comparePolygonsAsPoints(pts, exp)) geometry3 = extrudeLinear({ height: 15, twistAngle: TAU / 4, twistSteps: 3 }, geometry2) pts = geom3.toPoints(geometry3) exp = [ [[5, -5, 0], [5, 5, 0], [1.830127018922194, 6.830127018922193, 5]], [[5, -5, 0], [1.830127018922194, 6.830127018922193, 5], [6.830127018922193, -1.830127018922194, 5]], [[5, 5, 0], [-5, 5, 0], [-6.830127018922193, 1.830127018922194, 5]], [[5, 5, 0], [-6.830127018922193, 1.830127018922194, 5], [1.830127018922194, 6.830127018922193, 5]], [[-5, 5, 0], [-5, -5, 0], [-1.830127018922194, -6.830127018922193, 5]], [[-5, 5, 0], [-1.830127018922194, -6.830127018922193, 5], [-6.830127018922193, 1.830127018922194, 5]], [[-5, -5, 0], [5, -5, 0], [6.830127018922193, -1.830127018922194, 5]], [[-5, -5, 0], [6.830127018922193, -1.830127018922194, 5], [-1.830127018922194, -6.830127018922193, 5]], [[6.830127018922193, -1.830127018922194, 5], [1.830127018922194, 6.830127018922193, 5], [-1.8301270189221923, 6.830127018922193, 10]], [[6.830127018922193, -1.830127018922194, 5], [-1.8301270189221923, 6.830127018922193, 10], [6.830127018922193, 1.8301270189221923, 10]], [[1.830127018922194, 6.830127018922193, 5], [-6.830127018922193, 1.830127018922194, 5], [-6.830127018922193, -1.8301270189221923, 10]], [[1.830127018922194, 6.830127018922193, 5], [-6.830127018922193, -1.8301270189221923, 10], [-1.8301270189221923, 6.830127018922193, 10]], [[-6.830127018922193, 1.830127018922194, 5], [-1.830127018922194, -6.830127018922193, 5], [1.8301270189221923, -6.830127018922193, 10]], [[-6.830127018922193, 1.830127018922194, 5], [1.8301270189221923, -6.830127018922193, 10], [-6.830127018922193, -1.8301270189221923, 10]], [[-1.830127018922194, -6.830127018922193, 5], [6.830127018922193, -1.830127018922194, 5], [6.830127018922193, 1.8301270189221923, 10]], [[-1.830127018922194, -6.830127018922193, 5], [6.830127018922193, 1.8301270189221923, 10], [1.8301270189221923, -6.830127018922193, 10]], [[6.830127018922193, 1.8301270189221923, 10], [-1.8301270189221923, 6.830127018922193, 10], [-5, 5, 15]], [[6.830127018922193, 1.8301270189221923, 10], [-5, 5, 15], [5, 5, 15]], [[-1.8301270189221923, 6.830127018922193, 10], [-6.830127018922193, -1.8301270189221923, 10], [-5, -5, 15]], [[-1.8301270189221923, 6.830127018922193, 10], [-5, -5, 15], [-5, 5, 15]], [[-6.830127018922193, -1.8301270189221923, 10], [1.8301270189221923, -6.830127018922193, 10], [5, -5, 15]], [[-6.830127018922193, -1.8301270189221923, 10], [5, -5, 15], [-5, -5, 15]], [[1.8301270189221923, -6.830127018922193, 10], [6.830127018922193, 1.8301270189221923, 10], [5, 5, 15]], [[1.8301270189221923, -6.830127018922193, 10], [5, 5, 15], [5, -5, 15]], [[5, -5, 15], [5, 5, 15], [-5, 5, 15]], [[-5, 5, 15], [-5, -5, 15], [5, -5, 15]], [[5, 5, 0], [5, -5, 0], [-5, -5, 0]], [[-5, -5, 0], [-5, 5, 0], [5, 5, 0]] ] t.is(pts.length, 28) t.true(comparePolygonsAsPoints(pts, exp)) geometry3 = extrudeLinear({ height: 15, twistAngle: TAU / 2, twistSteps: 30 }, geometry2) pts = geom3.toPoints(geometry3) t.notThrows(() => geom3.validate(geometry3)) t.is(pts.length, 244) }) test('extrudeLinear (holes)', (t) => { const geometry2 = geom2.create([ [[-5, 5], [-5, -5]], [[-5, -5], [5, -5]], [[5, -5], [5, 5]], [[5, 5], [-5, 5]], [[-2, -2], [-2, 2]], [[2, -2], [-2, -2]], [[2, 2], [2, -2]], [[-2, 2], [2, 2]] ]) const geometry3 = extrudeLinear({ height: 15 }, geometry2) const pts = geom3.toPoints(geometry3) const exp = [ [[-5, 5, 0], [-5, -5, 0], [-5, -5, 15]], [[-5, 5, 0], [-5, -5, 15], [-5, 5, 15]], [[-5, -5, 0], [5, -5, 0], [5, -5, 15]], [[-5, -5, 0], [5, -5, 15], [-5, -5, 15]], [[5, -5, 0], [5, 5, 0], [5, 5, 15]], [[5, -5, 0], [5, 5, 15], [5, -5, 15]], [[5, 5, 0], [-5, 5, 0], [-5, 5, 15]], [[5, 5, 0], [-5, 5, 15], [5, 5, 15]], [[-2, -2, 0], [-2, 2, 0], [-2, 2, 15]], [[-2, -2, 0], [-2, 2, 15], [-2, -2, 15]], [[2, -2, 0], [-2, -2, 0], [-2, -2, 15]], [[2, -2, 0], [-2, -2, 15], [2, -2, 15]], [[2, 2, 0], [2, -2, 0], [2, -2, 15]], [[2, 2, 0], [2, -2, 15], [2, 2, 15]], [[-2, 2, 0], [2, 2, 0], [2, 2, 15]], [[-2, 2, 0], [2, 2, 15], [-2, 2, 15]], [[5, -5, 15], [5, 5, 15], [2, 2, 15]], [[-2, 2, 15], [2, 2, 15], [5, 5, 15]], [[5, -5, 15], [2, 2, 15], [2, -2, 15]], [[-2, 2, 15], [5, 5, 15], [-5, 5, 15]], [[-5, -5, 15], [5, -5, 15], [2, -2, 15]], [[-2, -2, 15], [-2, 2, 15], [-5, 5, 15]], [[-5, -5, 15], [2, -2, 15], [-2, -2, 15]], [[-2, -2, 15], [-5, 5, 15], [-5, -5, 15]], [[2, 2, 0], [5, 5, 0], [5, -5, 0]], [[5, 5, 0], [2, 2, 0], [-2, 2, 0]], [[2, -2, 0], [2, 2, 0], [5, -5, 0]], [[-5, 5, 0], [5, 5, 0], [-2, 2, 0]], [[2, -2, 0], [5, -5, 0], [-5, -5, 0]], [[-5, 5, 0], [-2, 2, 0], [-2, -2, 0]], [[-2, -2, 0], [2, -2, 0], [-5, -5, 0]], [[-5, -5, 0], [-5, 5, 0], [-2, -2, 0]] ] t.notThrows(() => geom3.validate(geometry3)) t.is(pts.length, 32) t.true(comparePolygonsAsPoints(pts, exp)) }) test('extrudeLinear (path2)', (t) => { const geometry2 = path2.fromPoints({ closed: true }, [[0, 0], [12, 0], [6, 10]]) const geometry3 = extrudeLinear({ height: 15 }, geometry2) t.notThrows(() => geom3.validate(geometry3)) const pts = geom3.toPoints(geometry3) const exp = [ [[6, 10, 0], [0, 0, 0], [0, 0, 15]], [[6, 10, 0], [0, 0, 15], [6, 10, 15]], [[0, 0, 0], [12, 0, 0], [12, 0, 15]], [[0, 0, 0], [12, 0, 15], [0, 0, 15]], [[12, 0, 0], [6, 10, 0], [6, 10, 15]], [[12, 0, 0], [6, 10, 15], [12, 0, 15]], [[12, 0, 15], [6, 10, 15], [0, 0, 15]], [[0, 0, 0], [6, 10, 0], [12, 0, 0]] ] t.is(pts.length, 8) t.true(comparePolygonsAsPoints(pts, exp)) }) test('extrudeLinear (unclosed path throws error)', (t) => { const geometry2 = path2.fromPoints({ closed: false }, [[0, 0], [12, 0], [6, 10]]) t.throws(() => extrudeLinear({}, geometry2)) })