From 7bb920b149077f0fa9c31e1580a3434cb7d71971 Mon Sep 17 00:00:00 2001 From: seveibar Date: Tue, 9 Jul 2024 08:25:40 -0700 Subject: [PATCH 1/3] Fix rendering for polygons --- examples/polygon.fixture.tsx | 2 +- lib/components/jscad-fixture.tsx | 27 ++++-- lib/convert-csg-to-three-geom.ts | 142 +++++++++++++++---------------- 3 files changed, 91 insertions(+), 80 deletions(-) diff --git a/examples/polygon.fixture.tsx b/examples/polygon.fixture.tsx index 2f196a3..d49d870 100644 --- a/examples/polygon.fixture.tsx +++ b/examples/polygon.fixture.tsx @@ -2,7 +2,7 @@ import { JsCadFixture } from "../lib/components/jscad-fixture" import { Polygon } from "../lib/jscad-fns/polygon" export default () => ( - + { - polygon.vertices.forEach((vertex) => { - vertex.index = idx - vertices.push(vertex[0], vertex[1], vertex[2]) - idx++ + console.log("csg", csg) + + if (csg.polygons) { + // 3D shape + const vertices = [] + const indices = [] + let idx = 0 + + csg.polygons.forEach((polygon) => { + polygon.vertices.forEach((vertex) => { + vertex.index = idx + vertices.push(vertex[0], vertex[1], vertex[2]) + idx++ + }) + const first = polygon.vertices[0].index + for (let i = 2; i < polygon.vertices.length; i++) { + const second = polygon.vertices[i - 1].index + const third = polygon.vertices[i].index + indices.push(first, second, third) + } }) - const first = polygon.vertices[0].index - for (let i = 2; i < polygon.vertices.length; i++) { - const second = polygon.vertices[i - 1].index - const third = polygon.vertices[i].index - indices.push(first, second, third) + + const geo = new BufferGeometry() + geo.setAttribute( + "position", + new BufferAttribute(new Float32Array(vertices), 3) + ) + geo.setIndex(indices) + if (csg.transforms) { + const transforms = new Matrix4() + transforms.set(...csg.transforms).transpose() + geo.applyMatrix4(transforms) } - }) + geo.computeVertexNormals() - const geo = new BufferGeometry() - geo.setAttribute( - "position", - new BufferAttribute(new Float32Array(vertices), 3), - ) - geo.setIndex(indices) - if (csg.transforms) { - const transforms = new Matrix4() - transforms.set(...csg.transforms).transpose() - geo.applyMatrix4(transforms) - } - geo.computeVertexNormals() + // Vertex normal averaging code (if needed) + // ... + + geo.attributes.normal.needsUpdate = true + return geo + } else if (csg.sides) { + // 2D shape + const shape = new Shape() - const positions = {} - for (let i = 0; i < geo.attributes.position.count; i++) { - const pArray = geo.attributes.position.array - const x = Math.round(pArray[i * 3] * 100) - const y = Math.round(pArray[i * 3 + 1] * 100) - const z = Math.round(pArray[i * 3 + 2] * 100) - const position = `${x},${y},${z}` - if (!positions[position]) { - positions[position] = { normals: [] } + // Move to the first point + const firstPoint = csg.sides[0][0] + shape.moveTo(firstPoint[0], firstPoint[1]) + + // Draw lines to subsequent points + for (let i = 1; i < csg.sides.length; i++) { + const point = csg.sides[i][0] + shape.lineTo(point[0], point[1]) } - const nArray = geo.attributes.normal.array - const nx = nArray[i * 3] - const ny = nArray[i * 3 + 1] - const nz = nArray[i * 3 + 2] - const normal = new Vector3(nx, ny, nz) - positions[position].normals.push({ index: i, normal: normal }) - } - for (let p in positions) { - const currentPosition = positions[p] - const nl = currentPosition.normals.length - const toAverage = {} - for (let i = 0; i < nl - 1; i += 1) { - for (let j = i + 1; j < nl; j += 1) { - const n1 = currentPosition.normals[i].normal - const n2 = currentPosition.normals[j].normal - if (n1.angleTo(n2) < Math.PI * 0.5 && n1.angleTo(n2) !== 0) { - toAverage[currentPosition.normals[i].index] = - currentPosition.normals[i].normal - toAverage[currentPosition.normals[j].index] = - currentPosition.normals[j].normal - } - } + // Close the shape + shape.closePath() + + const geometry = new ShapeGeometry(shape) + + if (csg.transforms) { + const transforms = new Matrix4() + transforms.set(...csg.transforms).transpose() + geometry.applyMatrix4(transforms) } - const averageNormal = new Vector3() - const indexes = Object.keys(toAverage) - indexes.forEach((index) => { - averageNormal.add(toAverage[index]) - averageNormal.normalize() - }) - indexes.forEach((index) => { - geo.attributes.normal.array[index * 3] = averageNormal.x - geo.attributes.normal.array[index * 3 + 1] = averageNormal.y - geo.attributes.normal.array[index * 3 + 2] = averageNormal.z - }) - } - geo.attributes.normal.array.needsUpdate = true - return geo + return geometry + } else { + console.error("Invalid CSG object: neither polygons nor sides found") + return new BufferGeometry() + } } From 9165afa1b634785a8d7c6da34c1146a728547bec Mon Sep 17 00:00:00 2001 From: seveibar Date: Tue, 9 Jul 2024 08:40:17 -0700 Subject: [PATCH 2/3] draw polygons without fill --- lib/components/jscad-fixture.tsx | 18 +++++++++++------- lib/convert-csg-to-three-geom.ts | 28 ++++++++++++++-------------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/lib/components/jscad-fixture.tsx b/lib/components/jscad-fixture.tsx index d9f9394..3425801 100644 --- a/lib/components/jscad-fixture.tsx +++ b/lib/components/jscad-fixture.tsx @@ -54,26 +54,30 @@ export function JsCadFixture({ for (const csg of jscadGeoms) { const geometry = convertCSGToThreeGeom(csg) - console.log(geometry) let material if (csg.sides) { // 2D shape - material = new THREE.MeshBasicMaterial({ + // material = new THREE.MeshBasicMaterial({ + // color: 0xffffff, + // side: THREE.DoubleSide, + // wireframe: wireframe, + // }) + const material = new THREE.LineBasicMaterial({ color: 0xffffff, - side: THREE.DoubleSide, - wireframe: wireframe, + linewidth: 2, // Note: linewidth > 1 only works in WebGL 2 }) + const lineLoop = new THREE.LineLoop(geometry, material) + scene.add(lineLoop) } else { // 3D shape material = new THREE.MeshStandardMaterial({ color: 0xffffff, wireframe: wireframe, }) + const mesh = new THREE.Mesh(geometry, material) + scene.add(mesh) } - - const mesh = new THREE.Mesh(geometry, material) - scene.add(mesh) } camera.position.x = 20 diff --git a/lib/convert-csg-to-three-geom.ts b/lib/convert-csg-to-three-geom.ts index 2742f64..a6a35bd 100644 --- a/lib/convert-csg-to-three-geom.ts +++ b/lib/convert-csg-to-three-geom.ts @@ -2,12 +2,13 @@ import { BufferGeometry, BufferAttribute, Vector3, + Vector2, Matrix4, Shape, ShapeGeometry, } from "three" -export default function convertCSGToThreeGeom(csg) { +export default function convertCSGToThreeGeom(csg): BufferGeometry { console.log("csg", csg) if (csg.polygons) { @@ -49,23 +50,22 @@ export default function convertCSGToThreeGeom(csg) { geo.attributes.normal.needsUpdate = true return geo } else if (csg.sides) { - // 2D shape - const shape = new Shape() + const points = csg.sides.map((side) => new Vector2(side[0][0], side[0][1])) - // Move to the first point - const firstPoint = csg.sides[0][0] - shape.moveTo(firstPoint[0], firstPoint[1]) + const geometry = new BufferGeometry().setFromPoints(points) - // Draw lines to subsequent points - for (let i = 1; i < csg.sides.length; i++) { - const point = csg.sides[i][0] - shape.lineTo(point[0], point[1]) - } + // // 2D shape + // const shape = new Shape() - // Close the shape - shape.closePath() + // // Move to the first point + // const firstPoint = csg.sides[0][0] + // shape.moveTo(firstPoint[0], firstPoint[1]) - const geometry = new ShapeGeometry(shape) + // // Draw lines to subsequent points + // for (let i = 1; i < csg.sides.length; i++) { + // const point = csg.sides[i][0] + // shape.lineTo(point[0], point[1]) + // } if (csg.transforms) { const transforms = new Matrix4() From ef625a0b236e2be559f87859739a692663f92469 Mon Sep 17 00:00:00 2001 From: seveibar Date: Tue, 9 Jul 2024 08:41:04 -0700 Subject: [PATCH 3/3] fix formatting --- lib/components/jscad-fixture.tsx | 2 +- lib/convert-csg-to-three-geom.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/components/jscad-fixture.tsx b/lib/components/jscad-fixture.tsx index 3425801..eb4e554 100644 --- a/lib/components/jscad-fixture.tsx +++ b/lib/components/jscad-fixture.tsx @@ -32,7 +32,7 @@ export function JsCadFixture({ 75, window.innerWidth / window.innerHeight, 0.1, - 1000 + 1000, ) // Add ambient light diff --git a/lib/convert-csg-to-three-geom.ts b/lib/convert-csg-to-three-geom.ts index a6a35bd..1497eb4 100644 --- a/lib/convert-csg-to-three-geom.ts +++ b/lib/convert-csg-to-three-geom.ts @@ -34,7 +34,7 @@ export default function convertCSGToThreeGeom(csg): BufferGeometry { const geo = new BufferGeometry() geo.setAttribute( "position", - new BufferAttribute(new Float32Array(vertices), 3) + new BufferAttribute(new Float32Array(vertices), 3), ) geo.setIndex(indices) if (csg.transforms) {