[READ-ONLY] Mirror of https://github.com/flo-bit/shapecraft.
flo-bit.dev/shapecraft/
2.0 kB
57 lines
1import { describe, it, expect } from 'vitest'
2import { box, cylinder } from '../src/primitives'
3import { extrudeFaces, insetFaces, bevel } from '../src/ops'
4import type { Mesh } from '../src/core/mesh'
5
6function finite(m: Mesh): boolean {
7 const p = m.positions
8 for (let i = 0; i < p.length; i++) if (!Number.isFinite(p[i])) return false
9 return true
10}
11
12describe('extrudeFaces', () => {
13 it('adds geometry and walls when pushing a face out', () => {
14 const b = box({ size: 1 })
15 const e = extrudeFaces(b, { distance: 0.5, only: (n) => n[1] > 0.9 }) // top face only
16 expect(e.faceCount).toBeGreaterThan(b.faceCount)
17 expect(finite(e)).toBe(true)
18 expect(e.boundingBox.max.y).toBeCloseTo(1, 1) // box half 0.5 + extrude 0.5
19 })
20})
21
22describe('insetFaces', () => {
23 it('shrinks a face inward, keeping the outer bounds', () => {
24 const b = box({ size: 1 })
25 const i = insetFaces(b, { amount: 0.2, only: (n) => n[1] > 0.9 })
26 expect(i.faceCount).toBeGreaterThan(b.faceCount)
27 expect(finite(i)).toBe(true)
28 expect(i.boundingBox.max.x).toBeCloseTo(0.5, 2)
29 })
30
31 it('depth recesses the inset face', () => {
32 const b = box({ size: 1 })
33 const i = insetFaces(b, { amount: 0.2, depth: -0.3, only: (n) => n[1] > 0.9 })
34 expect(finite(i)).toBe(true)
35 // recessed panel dips below the original top
36 expect(i.boundingBox.max.y).toBeCloseTo(0.5, 2)
37 })
38})
39
40describe('bevel', () => {
41 it('chamfers a box (more faces, same bounds, finite)', () => {
42 const b = box({ size: 1 })
43 const v = bevel(b, { amount: 0.15 })
44 expect(v.faceCount).toBeGreaterThan(b.faceCount)
45 expect(finite(v)).toBe(true)
46 const bb = v.boundingBox
47 expect(bb.max.x).toBeCloseTo(0.5, 2)
48 expect(bb.min.x).toBeCloseTo(-0.5, 2)
49 })
50
51 it('works on a cylinder', () => {
52 const c = cylinder({ radius: 0.5, height: 1, segments: 12 })
53 const v = bevel(c, { amount: 0.08 })
54 expect(v.faceCount).toBeGreaterThan(0)
55 expect(finite(v)).toBe(true)
56 })
57})