UNPKG

@jscad/modeling

Version:

Constructive Solid Geometry (CSG) Library for JSCAD

174 lines (157 loc) 8.39 kB
const test = require('ava') const { geom3 } = require('../../geometries') const retessellate = require('./retessellate') const { comparePolygonsAsPoints } = require('../../../test/helpers') test('geom3: retessellate() should create proper geometry from empty geometries', (t) => { const obj1 = geom3.create() // one empty geometry const ret1 = retessellate(obj1) const exp1 = { polygons: [], isRetesselated: true, transforms: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] } t.deepEqual(ret1, exp1) }) test('geom3: retessellate() should create proper geometry from solid geometries', (t) => { const box1 = [ [[-5.0, -5.0, -5.0], [-5.0, -5.0, 5.0], [-5.0, 5.0, 5.0], [-5.0, 5.0, -5.0]], [[5.0, -5.0, -5.0], [5.0, 5.0, -5.0], [5.0, 5.0, 5.0], [5.0, -5.0, 5.0]], [[-5.0, -5.0, -5.0], [5.0, -5.0, -5.0], [5.0, -5.0, 5.0], [-5.0, -5.0, 5.0]], [[-5.0, 5.0, -5.0], [-5.0, 5.0, 5.0], [5.0, 5.0, 5.0], [5.0, 5.0, -5.0]], [[-5.0, -5.0, -5.0], [-5.0, 5.0, -5.0], [5.0, 5.0, -5.0], [5.0, -5.0, -5.0]], [[-5.0, -5.0, 5.0], [5.0, -5.0, 5.0], [5.0, 5.0, 5.0], [-5.0, 5.0, 5.0]] ] const box2 = [ [[15.0, 15.0, 15.0], [15.0, 15.0, 25.0], [15.0, 25.0, 25.0], [15.0, 25.0, 15.0]], [[25.0, 15.0, 15.0], [25.0, 25.0, 15.0], [25.0, 25.0, 25.0], [25.0, 15.0, 25.0]], [[15.0, 15.0, 15.0], [25.0, 15.0, 15.0], [25.0, 15.0, 25.0], [15.0, 15.0, 25.0]], [[15.0, 25.0, 15.0], [15.0, 25.0, 25.0], [25.0, 25.0, 25.0], [25.0, 25.0, 15.0]], [[15.0, 15.0, 15.0], [15.0, 25.0, 15.0], [25.0, 25.0, 15.0], [25.0, 15.0, 15.0]], [[15.0, 15.0, 25.0], [25.0, 15.0, 25.0], [25.0, 25.0, 25.0], [15.0, 25.0, 25.0]] ] const box3 = [ [[-5.0, -5.0, -5.0], [-5.0, -5.0, 5.0], [-5.0, 5.0, 5.0], [-5.0, 5.0, -5.0]], [[5.0, -5.0, -5.0], [5.0, 5.0, -5.0], [5.0, 5.0, 5.0], [5.0, -5.0, 5.0]], [[-5.0, -5.0, -5.0], [5.0, -5.0, -5.0], [5.0, -5.0, 5.0], [-5.0, -5.0, 5.0]], [[-5.0, 5.0, -5.0], [-5.0, 5.0, 5.0], [5.0, 5.0, 5.0], [5.0, 5.0, -5.0]], [[-5.0, -5.0, -5.0], [-5.0, 5.0, -5.0], [5.0, 5.0, -5.0], [5.0, -5.0, -5.0]], [[-5.0, -5.0, 5.0], [-5.0, -5.0, 15.0], [-5.0, 5.0, 15.0], [-5.0, 5.0, 5.0]], [[5.0, -5.0, 5.0], [5.0, 5.0, 5.0], [5.0, 5.0, 15.0], [5.0, -5.0, 15.0]], [[-5.0, -5.0, 5.0], [5.0, -5.0, 5.0], [5.0, -5.0, 15.0], [-5.0, -5.0, 15.0]], [[-5.0, 5.0, 5.0], [-5.0, 5.0, 15.0], [5.0, 5.0, 15.0], [5.0, 5.0, 5.0]], [[-5.0, -5.0, 15.0], [5.0, -5.0, 15.0], [5.0, 5.0, 15.0], [-5.0, 5.0, 15.0]] ] const box4 = [ [[-5.0, -5.0, -5.0], [-5.0, -5.0, 5.0], [-5.0, 5.0, 5.0], [-5.0, 5.0, -5.0]], [[-5.0, -5.0, -5.0], [5.0, -5.0, -5.0], [5.0, -5.0, 5.0], [-5.0, -5.0, 5.0]], [[-5.0, -5.0, -5.0], [-5.0, 5.0, -5.0], [5.0, 5.0, -5.0], [5.0, -5.0, -5.0]], [[5.0, -5.0, -5.0], [5.0, 0.0, -5.0], [5.0, 0.0, 5.0], [5.0, -5.0, 5.0]], [[-5.0, 5.0, -5.0], [-5.0, 5.0, 5.0], [0.0, 5.0, 5.0], [0.0, 5.0, -5.0]], [[-5.0, -5.0, 5.0], [0.0, -5.0, 5.0], [0.0, 5.0, 5.0], [-5.0, 5.0, 5.0]], [[5.0, 0.0, -5.0], [5.0, 5.0, -5.0], [5.0, 5.0, 0.0], [5.0, 0.0, 0.0]], [[5.0, 5.0, 0.0], [5.0, 5.0, -5.0], [0.0, 5.0, -5.0], [0.0, 5.0, 0.0]], [[0.0, -5.0, 5.0], [5.0, -5.0, 5.0], [5.0, 0.0, 5.0], [0.0, 0.0, 5.0]], [[10.0, 0.0, 0.0], [10.0, 10.0, 0.0], [10.0, 10.0, 10.0], [10.0, 0.0, 10.0]], [[0.0, 10.0, 0.0], [0.0, 10.0, 10.0], [10.0, 10.0, 10.0], [10.0, 10.0, 0.0]], [[0.0, 0.0, 10.0], [10.0, 0.0, 10.0], [10.0, 10.0, 10.0], [0.0, 10.0, 10.0]], [[0.0, 5.0, 10.0], [0.0, 10.0, 10.0], [0.0, 10.0, 0.0], [0.0, 5.0, 0.0]], [[5.0, 0.0, 0.0], [10.0, 0.0, 0.0], [10.0, 0.0, 10.0], [5.0, 0.0, 10.0]], [[5.0, 10.0, 0.0], [10.0, 10.0, 0.0], [10.0, 0.0, 0.0], [5.0, 0.0, 0.0]], [[0.0, 0.0, 5.0], [0.0, 0.0, 10.0], [0.0, 5.0, 10.0], [0.0, 5.0, 5.0]], [[5.0, 0.0, 5.0], [5.0, 0.0, 10.0], [0.0, 0.0, 10.0], [0.0, 0.0, 5.0]], [[0.0, 5.0, 0.0], [0.0, 10.0, 0.0], [5.0, 10.0, 0.0], [5.0, 5.0, 0.0]] ] const box5 = [ // with coplanar polygons [[-5.0, -5.0, -5.0], [-5.0, -5.0, 5.0], [-5.0, 5.0, 5.0], [-5.0, 5.0, -5.0]], // end [[10.0, -5.0, -5.0], [10.0, -5.0, 5.0], [-5.0, -5.0, 5.0], [-5.0, -5.0, -5.0]], // side [[10.0, 5.0, 5.0], [10.0, 5.0, -5.0], [-5.0, 5.0, -5.0], [-5.0, 5.0, 5.0]], // side [[10.0, 5.0, -5.0], [10.0, -5.0, -5.0], [-5.0, -5.0, -5.0], [-5.0, 5.0, -5.0]], // bottom [[10.0, -5.0, 5.0], [10.0, 0.0, 5.0], [-5.0, 0.0, 5.0], [-5.0, -5.0, 5.0]], // top [[10.0, 0.0, 5.0], [10.0, 5.0, 5.0], [-5.0, 5.0, 5.0], [-5.0, 0.0, 5.0]], // top [[10.0, -5.0, -5.0], [10.0, 5.0, -5.0], [10.0, 5.0, 5.0], [10.0, -5.0, 5.0]] // end ] const obj1 = geom3.fromPoints(box1) const obj2 = geom3.fromPoints(box1.concat(box2)) // combined geometry const obj3 = geom3.fromPoints(box3) const obj4 = geom3.fromPoints(box4) const obj5 = geom3.fromPoints(box5) // one solid geometry const ret1 = retessellate(obj1) const pts1 = geom3.toPoints(ret1) const exp1 = [ [[-5, -5, -5], [-5, -5, 5], [-5, 5, 5], [-5, 5, -5]], [[5, -5, -5], [5, 5, -5], [5, 5, 5], [5, -5, 5]], [[-5, -5, -5], [5, -5, -5], [5, -5, 5], [-5, -5, 5]], [[-5, 5, -5], [-5, 5, 5], [5, 5, 5], [5, 5, -5]], [[-5, -5, -5], [-5, 5, -5], [5, 5, -5], [5, -5, -5]], [[-5, -5, 5], [5, -5, 5], [5, 5, 5], [-5, 5, 5]] ] t.true(comparePolygonsAsPoints(pts1, exp1)) // two non-overlapping geometries const ret2 = retessellate(obj2) const pts2 = geom3.toPoints(ret2) const exp2 = [ [[-5, -5, -5], [-5, -5, 5], [-5, 5, 5], [-5, 5, -5]], [[5, -5, -5], [5, 5, -5], [5, 5, 5], [5, -5, 5]], [[-5, -5, -5], [5, -5, -5], [5, -5, 5], [-5, -5, 5]], [[-5, 5, -5], [-5, 5, 5], [5, 5, 5], [5, 5, -5]], [[-5, -5, -5], [-5, 5, -5], [5, 5, -5], [5, -5, -5]], [[-5, -5, 5], [5, -5, 5], [5, 5, 5], [-5, 5, 5]], [[15, 15, 15], [15, 15, 25], [15, 25, 25], [15, 25, 15]], [[25, 15, 15], [25, 25, 15], [25, 25, 25], [25, 15, 25]], [[15, 15, 15], [25, 15, 15], [25, 15, 25], [15, 15, 25]], [[15, 25, 15], [15, 25, 25], [25, 25, 25], [25, 25, 15]], [[15, 15, 15], [15, 25, 15], [25, 25, 15], [25, 15, 15]], [[15, 15, 25], [25, 15, 25], [25, 25, 25], [15, 25, 25]] ] t.true(comparePolygonsAsPoints(pts2, exp2)) // two touching geometries (faces) const ret3 = retessellate(obj3) const pts3 = geom3.toPoints(ret3) const exp3 = [ [[-5, 5, 15], [-5, 5, -5], [-5, -5, -5], [-5, -5, 15]], [[5, -5, 15], [5, -5, -5], [5, 5, -5], [5, 5, 15]], [[-5, -5, 15], [-5, -5, -5], [5, -5, -5], [5, -5, 15]], [[5, 5, 15], [5, 5, -5], [-5, 5, -5], [-5, 5, 15]], [[-5, -5, -5], [-5, 5, -5], [5, 5, -5], [5, -5, -5]], [[-5, -5, 15], [5, -5, 15], [5, 5, 15], [-5, 5, 15]] ] t.true(comparePolygonsAsPoints(pts3, exp3)) // two overlapping geometries const ret4 = retessellate(obj4) const pts4 = geom3.toPoints(ret4) const exp4 = [ [[-5, -5, -5], [-5, -5, 5], [-5, 5, 5], [-5, 5, -5]], [[-5, -5, -5], [5, -5, -5], [5, -5, 5], [-5, -5, 5]], [[-5, -5, -5], [-5, 5, -5], [5, 5, -5], [5, -5, -5]], [[5, -5, 5], [5, -5, 0], [5, 0, 0], [5, 0, 5]], [[5, -5, 0], [5, -5, -5], [5, 5, -5], [5, 5, 0]], [[0, 5, 5], [0, 5, 0], [-5, 5, 0], [-5, 5, 5]], [[5, 5, 0], [5, 5, -5], [-5, 5, -5], [-5, 5, 0]], [[-5, 5, 5], [-5, 0, 5], [0, 0, 5], [0, 5, 5]], [[-5, 0, 5], [-5, -5, 5], [5, -5, 5], [5, 0, 5]], [[10, 0, 0], [10, 10, 0], [10, 10, 10], [10, 0, 10]], [[0, 10, 0], [0, 10, 10], [10, 10, 10], [10, 10, 0]], [[0, 0, 10], [10, 0, 10], [10, 10, 10], [0, 10, 10]], [[0, 10, 10], [0, 10, 5], [0, 0, 5], [0, 0, 10]], [[0, 10, 5], [0, 10, 0], [0, 5, 0], [0, 5, 5]], [[0, 0, 10], [0, 0, 5], [10, 0, 5], [10, 0, 10]], [[5, 0, 5], [5, -0, 0], [10, -0, 0], [10, 0, 5]], [[10, 10, 0], [10, 5, 0], [0, 5, 0], [0, 10, 0]], [[10, 5, 0], [10, 0, 0], [5, 0, 0], [5, 5, 0]] ] t.true(comparePolygonsAsPoints(pts4, exp4)) // coplanar polygons const ret5 = retessellate(obj5) const pts5 = geom3.toPoints(ret5) const exp5 = [ [[-5, -5, -5], [-5, -5, 5], [-5, 5, 5], [-5, 5, -5]], [[10, -5, -5], [10, -5, 5], [-5, -5, 5], [-5, -5, -5]], [[10, 5, 5], [10, 5, -5], [-5, 5, -5], [-5, 5, 5]], [[10, 5, -5], [10, -5, -5], [-5, -5, -5], [-5, 5, -5]], [[-5, 5, 5], [-5, -5, 5], [10, -5, 5], [10, 5, 5]], [[10, -5, -5], [10, 5, -5], [10, 5, 5], [10, -5, 5]] ] t.true(comparePolygonsAsPoints(pts5, exp5)) })