three.cad/src/extrude.js

199 lines
5.7 KiB
JavaScript
Raw Normal View History

2021-04-07 03:46:16 +08:00
import * as THREE from '../node_modules/three/src/Three';
2021-04-16 08:05:40 +08:00
import { color } from './shared'
2021-04-17 07:03:30 +08:00
export function extrude(sketch, depth, refresh=false) {
2021-03-26 12:30:35 +08:00
2021-03-29 18:27:34 +08:00
let constraints = sketch.constraints;
let linkedObjs = sketch.linkedObjs;
2021-04-01 13:35:08 +08:00
let children = sketch.obj3d.children;
2021-03-30 06:12:46 +08:00
let objIdx = sketch.objIdx;
2021-03-26 12:30:35 +08:00
let visited = new Set()
let v2s = []
function findPair(node) {
2021-04-17 07:03:30 +08:00
// console.log(node.name, 'xx')
2021-04-03 12:05:28 +08:00
if (node.userData.construction) return;
2021-03-26 12:30:35 +08:00
visited.add(node)
2021-03-31 16:07:34 +08:00
let linkedObj = linkedObjs.get(node.userData.l_id)
2021-03-26 12:30:35 +08:00
let arr;
2021-04-16 16:12:10 +08:00
let lineNode
2021-03-26 12:30:35 +08:00
if (linkedObj[0] == 'line') {
2021-04-16 16:12:10 +08:00
lineNode = linkedObj[1][2]
2021-03-26 12:30:35 +08:00
} else if (linkedObj[0] == 'arc') {
2021-04-16 16:12:10 +08:00
lineNode = linkedObj[1][3]
2021-03-26 12:30:35 +08:00
}
2021-04-16 16:12:10 +08:00
arr = children[objIdx.get(lineNode)].geometry.attributes.position.array
let nextIdx
if (linkedObj[1][0] == node.name) {
nextIdx = 1
for (let i = 0; i < arr.length; i += 3) {
v2s.push(new THREE.Vector2(arr[i], arr[i + 1]))
}
} else {
nextIdx = 0
for (let i = arr.length - 3; i >= 0; i -= 3) {
v2s.push(new THREE.Vector2(arr[i], arr[i + 1]))
}
2021-03-26 12:30:35 +08:00
}
2021-04-16 16:12:10 +08:00
let d = children[
objIdx.get(
linkedObj[1][nextIdx]
)
]
if (d == children[2]) {
2021-04-17 07:03:30 +08:00
// console.log('pair found')
2021-04-16 16:12:10 +08:00
};
findTouching(d)
2021-03-26 12:30:35 +08:00
}
function findTouching(node) {
2021-04-17 07:03:30 +08:00
// console.log(node.name, 'yy')
2021-03-31 16:07:34 +08:00
for (let t of node.userData.constraints) {
2021-04-17 07:03:30 +08:00
// console.log(constraints.get(t)[2], node.name)
2021-04-03 12:05:28 +08:00
if (constraints.get(t)[0] != 'points_coincident') continue
2021-03-30 06:12:46 +08:00
for (let c of constraints.get(t)[2]) {
if (c == -1) continue;
const d = children[objIdx.get(c)]
if (d == node) continue;
2021-04-16 16:12:10 +08:00
if (d == children[2]) {
2021-04-17 07:03:30 +08:00
// console.log('loop found')
2021-03-26 12:30:35 +08:00
} else {
2021-04-16 16:12:10 +08:00
// if (!visited.has(d)) {
2021-04-17 07:03:30 +08:00
findPair(d)
2021-04-16 16:12:10 +08:00
// }
2021-03-26 12:30:35 +08:00
};
}
}
}
2021-04-17 07:03:30 +08:00
findPair(children[sketch.geomStartIdx + 1]) // ?? possibly allow user select search start point
2021-03-26 12:30:35 +08:00
const shape = new THREE.Shape(v2s);
2021-04-16 08:05:40 +08:00
// const extrudeSettings = { depth: Math.abs(depth), bevelEnabled: false };
2021-04-15 16:36:54 +08:00
const extrudeSettings = { depth, bevelEnabled: false };
2021-04-07 05:10:07 +08:00
2021-03-26 12:30:35 +08:00
const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
2021-04-10 16:45:15 +08:00
2021-04-16 16:12:10 +08:00
const material = new THREE.MeshPhongMaterial({
color: color.mesh,
emissive: color.emissive,
// wireframe:true
});
2021-04-11 07:50:12 +08:00
2021-04-16 16:12:10 +08:00
const mesh = new THREE.Mesh(geometry, material)
2021-04-16 08:05:40 +08:00
mesh.name = 'e' + this.mid++
2021-04-05 11:52:17 +08:00
mesh.userData.type = 'mesh'
2021-04-16 08:05:40 +08:00
mesh.userData.featureInfo = [sketch.obj3d.name, depth]
2021-04-10 16:45:15 +08:00
mesh.layers.enable(1)
2021-03-31 07:20:24 +08:00
2021-04-11 07:50:12 +08:00
const vertices = new THREE.Points(mesh.geometry, new THREE.PointsMaterial({ size: 0 }));
2021-04-10 16:45:15 +08:00
vertices.userData.type = 'point'
vertices.layers.enable(1)
mesh.add(vertices)
2021-04-16 08:05:40 +08:00
2021-03-29 18:27:34 +08:00
mesh.matrixAutoUpdate = false;
2021-04-01 13:35:08 +08:00
mesh.matrix.multiply(sketch.obj3d.matrix)
2021-04-11 07:50:12 +08:00
2021-04-16 08:05:40 +08:00
if (depth < 0) {
flipBufferGeometryNormals(mesh.geometry)
mesh.userData.inverted = true
}
2021-04-17 07:03:30 +08:00
if (!refresh) {
this.obj3d.add(mesh)
2021-03-28 20:00:31 +08:00
2021-04-17 07:03:30 +08:00
this.store.dispatch({ type: 'rx-extrusion', mesh, sketchId: sketch.obj3d.name })
2021-04-11 15:57:39 +08:00
2021-04-17 07:03:30 +08:00
if (this.activeSketch == sketch) {
2021-04-17 21:32:14 +08:00
this.store.dispatch({ type: 'finish-sketch' })
2021-04-17 07:03:30 +08:00
sketch.deactivate()
}
this.render()
} else {
return mesh
2021-04-11 15:57:39 +08:00
}
2021-03-26 12:30:35 +08:00
}
2021-04-16 08:05:40 +08:00
export function flipBufferGeometryNormals(geometry) {
//https://stackoverflow.com/a/54496265
const tempXYZ = [0, 0, 0];
// flip normals
for (let i = 0; i < geometry.attributes.normal.array.length / 9; i++) {
// cache a coordinates
tempXYZ[0] = geometry.attributes.normal.array[i * 9];
tempXYZ[1] = geometry.attributes.normal.array[i * 9 + 1];
tempXYZ[2] = geometry.attributes.normal.array[i * 9 + 2];
// overwrite a with c
geometry.attributes.normal.array[i * 9] =
geometry.attributes.normal.array[i * 9 + 6];
geometry.attributes.normal.array[i * 9 + 1] =
geometry.attributes.normal.array[i * 9 + 7];
geometry.attributes.normal.array[i * 9 + 2] =
geometry.attributes.normal.array[i * 9 + 8];
// overwrite c with stored a values
geometry.attributes.normal.array[i * 9 + 6] = tempXYZ[0];
geometry.attributes.normal.array[i * 9 + 7] = tempXYZ[1];
geometry.attributes.normal.array[i * 9 + 8] = tempXYZ[2];
}
// change face winding order
for (let i = 0; i < geometry.attributes.position.array.length / 9; i++) {
// cache a coordinates
tempXYZ[0] = geometry.attributes.position.array[i * 9];
tempXYZ[1] = geometry.attributes.position.array[i * 9 + 1];
tempXYZ[2] = geometry.attributes.position.array[i * 9 + 2];
// overwrite a with c
geometry.attributes.position.array[i * 9] =
geometry.attributes.position.array[i * 9 + 6];
geometry.attributes.position.array[i * 9 + 1] =
geometry.attributes.position.array[i * 9 + 7];
geometry.attributes.position.array[i * 9 + 2] =
geometry.attributes.position.array[i * 9 + 8];
// overwrite c with stored a values
geometry.attributes.position.array[i * 9 + 6] = tempXYZ[0];
geometry.attributes.position.array[i * 9 + 7] = tempXYZ[1];
geometry.attributes.position.array[i * 9 + 8] = tempXYZ[2];
}
// flip UV coordinates
for (let i = 0; i < geometry.attributes.uv.array.length / 6; i++) {
// cache a coordinates
tempXYZ[0] = geometry.attributes.uv.array[i * 6];
tempXYZ[1] = geometry.attributes.uv.array[i * 6 + 1];
// overwrite a with c
geometry.attributes.uv.array[i * 6] =
geometry.attributes.uv.array[i * 6 + 4];
geometry.attributes.uv.array[i * 6 + 1] =
geometry.attributes.uv.array[i * 6 + 5];
// overwrite c with stored a values
geometry.attributes.uv.array[i * 6 + 4] = tempXYZ[0];
geometry.attributes.uv.array[i * 6 + 5] = tempXYZ[1];
}
geometry.attributes.normal.needsUpdate = true;
geometry.attributes.position.needsUpdate = true;
geometry.attributes.uv.needsUpdate = true;
}