i met my challenge
parent
1af670fde9
commit
0ae39d196a
75
src/Scene.js
75
src/Scene.js
|
@ -9,7 +9,7 @@ import Stats from './stats.module.js';
|
||||||
import { add3DPoint } from './datums'
|
import { add3DPoint } from './datums'
|
||||||
import { extrude } from './extrude'
|
import { extrude } from './extrude'
|
||||||
import { onHover, onPick } from './mouseEvents';
|
import { onHover, onPick } from './mouseEvents';
|
||||||
import { _vec2, _vec3, color, awaitSelection } from './shared'
|
import { _vec2, _vec3, color, awaitSelection, ptObj} from './shared'
|
||||||
|
|
||||||
import {AxesHelper} from './axes'
|
import {AxesHelper} from './axes'
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ export class Scene {
|
||||||
|
|
||||||
this.rect = this.canvas.getBoundingClientRect().toJSON()
|
this.rect = this.canvas.getBoundingClientRect().toJSON()
|
||||||
|
|
||||||
this.renderer = new THREE.WebGLRenderer({ canvas: this.canvas });
|
this.renderer = new THREE.WebGLRenderer({ canvas: this.canvas, antialias:true });
|
||||||
|
|
||||||
const size = 1;
|
const size = 1;
|
||||||
const near = 0;
|
const near = 0;
|
||||||
|
@ -66,13 +66,23 @@ export class Scene {
|
||||||
this.obj3d.add(helpersGroup);
|
this.obj3d.add(helpersGroup);
|
||||||
|
|
||||||
|
|
||||||
|
for (let i=0; i<4;i ++) {
|
||||||
|
const freePt = ptObj()
|
||||||
|
freePt.matrixAutoUpdate = false
|
||||||
|
freePt.material.size=8
|
||||||
|
freePt.visible = false
|
||||||
|
freePt.depthTest = false
|
||||||
|
helpersGroup.add(freePt);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.fptIdx = 0;
|
||||||
|
this.fptObj = {}
|
||||||
|
|
||||||
|
|
||||||
this.axes = new AxesHelper(this.camera.zoom)
|
this.axes = new AxesHelper(this.camera.zoom)
|
||||||
this.axes.visible = false
|
this.axes.visible = false
|
||||||
|
|
||||||
helpersGroup.add(this.axes);
|
helpersGroup.add(this.axes);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const planeGeom = new THREE.PlaneGeometry(5, 5)
|
const planeGeom = new THREE.PlaneGeometry(5, 5)
|
||||||
|
|
||||||
const pxy = new THREE.Mesh(
|
const pxy = new THREE.Mesh(
|
||||||
|
@ -88,6 +98,7 @@ export class Scene {
|
||||||
);
|
);
|
||||||
|
|
||||||
pxy.userData.type = 'plane'
|
pxy.userData.type = 'plane'
|
||||||
|
pxy.layers.enable(1)
|
||||||
|
|
||||||
pxy.add(
|
pxy.add(
|
||||||
new THREE.LineSegments(
|
new THREE.LineSegments(
|
||||||
|
@ -109,7 +120,7 @@ export class Scene {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const intensity = 1;
|
const intensity = 0.5;
|
||||||
const light1 = new THREE.DirectionalLight(color.lighting, intensity);
|
const light1 = new THREE.DirectionalLight(color.lighting, intensity);
|
||||||
light1.position.set(10, 10, 10);
|
light1.position.set(10, 10, 10);
|
||||||
this.obj3d.add(light1);
|
this.obj3d.add(light1);
|
||||||
|
@ -122,6 +133,8 @@ export class Scene {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
this.render = render.bind(this);
|
this.render = render.bind(this);
|
||||||
this.addSketch = addSketch.bind(this);
|
this.addSketch = addSketch.bind(this);
|
||||||
this.extrude = extrude.bind(this);
|
this.extrude = extrude.bind(this);
|
||||||
|
@ -208,6 +221,45 @@ export class Scene {
|
||||||
console.log('fireed')
|
console.log('fireed')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
subtract (m1, m2) {
|
||||||
|
let bspA = CSG.fromMesh(m1)
|
||||||
|
let bspB = CSG.fromMesh(m2)
|
||||||
|
m1.traverse(e=>e.layers.disable(0))
|
||||||
|
m2.traverse(e=>e.layers.disable(0))
|
||||||
|
// m1.visible = false
|
||||||
|
// m2.visible = false
|
||||||
|
|
||||||
|
// // Subtract one bsp from the other via .subtract... other supported modes are .union and .intersect
|
||||||
|
|
||||||
|
let bspResult = bspA.subtract(bspB)
|
||||||
|
|
||||||
|
// //Get the resulting mesh from the result bsp, and assign meshA.material to the resulting mesh
|
||||||
|
|
||||||
|
let mesh = CSG.toMesh(bspResult, m1.matrix, m1.material)
|
||||||
|
mesh.userData.type = 'mesh'
|
||||||
|
mesh.name = `${m1.name}-${m2.name}`
|
||||||
|
|
||||||
|
const edges = new THREE.EdgesGeometry( mesh.geometry, 15 );
|
||||||
|
edges.type = 'BufferGeometry'
|
||||||
|
edges.parameters = undefined
|
||||||
|
|
||||||
|
const line = new THREE.LineSegments( edges, new THREE.LineBasicMaterial( { color: 0x000000 } ) );
|
||||||
|
line.userData.type = 'line'
|
||||||
|
|
||||||
|
// const vertices = new THREE.Points( edges, new THREE.PointsMaterial({ color: 0x000000, size:4}) );
|
||||||
|
const vertices = new THREE.Points( edges, new THREE.PointsMaterial() );
|
||||||
|
vertices.userData.type = 'point'
|
||||||
|
vertices.layers.enable(1)
|
||||||
|
|
||||||
|
mesh.add(line)
|
||||||
|
mesh.add(vertices)
|
||||||
|
|
||||||
|
|
||||||
|
sc.obj3d.add(mesh)
|
||||||
|
return mesh
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -299,12 +351,7 @@ async function addSketch() {
|
||||||
}
|
}
|
||||||
|
|
||||||
window.sc = new Scene(store)
|
window.sc = new Scene(store)
|
||||||
// sc.loadState()
|
sc.loadState()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// sc.camera.layers.enable(1)
|
||||||
|
// rc.layers.set(1)
|
|
@ -152,6 +152,7 @@ class Sketch {
|
||||||
|
|
||||||
this.setDimLines()
|
this.setDimLines()
|
||||||
|
|
||||||
|
this.obj3d.traverse(e=>e.layers.enable(0))
|
||||||
this.scene.axes.matrix = this.obj3d.matrix
|
this.scene.axes.matrix = this.obj3d.matrix
|
||||||
this.scene.axes.visible = true
|
this.scene.axes.visible = true
|
||||||
|
|
||||||
|
@ -164,6 +165,7 @@ class Sketch {
|
||||||
this.canvas.removeEventListener('pointermove', this.onHover)
|
this.canvas.removeEventListener('pointermove', this.onHover)
|
||||||
this.store.dispatch({ type: 'exit-sketch' })
|
this.store.dispatch({ type: 'exit-sketch' })
|
||||||
this.labelContainer.innerHTML = ""
|
this.labelContainer.innerHTML = ""
|
||||||
|
this.obj3d.traverse(e=>e.layers.disable(0))
|
||||||
this.scene.axes.visible = false
|
this.scene.axes.visible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,6 @@ import { color } from './shared'
|
||||||
const lineMaterial = new THREE.LineBasicMaterial({
|
const lineMaterial = new THREE.LineBasicMaterial({
|
||||||
linewidth: 2,
|
linewidth: 2,
|
||||||
color: color.dimension,
|
color: color.dimension,
|
||||||
opacity: 0.2,
|
|
||||||
transparent: true,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,7 +24,7 @@ export async function drawDimension() {
|
||||||
|
|
||||||
const line = new THREE.LineSegments(
|
const line = new THREE.LineSegments(
|
||||||
new THREE.BufferGeometry().setAttribute('position',
|
new THREE.BufferGeometry().setAttribute('position',
|
||||||
new THREE.Float32BufferAttribute(3 * 8, 3)
|
new THREE.Float32BufferAttribute(Array(3 * 8).fill(-0.001), 3)
|
||||||
),
|
),
|
||||||
lineMaterial.clone()
|
lineMaterial.clone()
|
||||||
);
|
);
|
||||||
|
|
|
@ -77,23 +77,43 @@ export function extrude(sketch) {
|
||||||
|
|
||||||
|
|
||||||
const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
|
const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
|
||||||
const material = new THREE.MeshPhongMaterial({
|
|
||||||
|
|
||||||
|
const material = new THREE.MeshLambertMaterial({
|
||||||
|
// const material = new THREE.MeshPhongMaterial({
|
||||||
color: color.mesh,
|
color: color.mesh,
|
||||||
emissive: color.emissive,
|
emissive: color.emissive,
|
||||||
|
// flatShading:true,
|
||||||
});
|
});
|
||||||
const mesh = new THREE.Mesh(geometry, material)
|
const mesh = new THREE.Mesh(geometry, material)
|
||||||
mesh.name = 'm' + id++
|
mesh.name = 'm' + id++
|
||||||
mesh.userData.type = 'mesh'
|
mesh.userData.type = 'mesh'
|
||||||
|
mesh.layers.enable(1)
|
||||||
|
|
||||||
for (let i = 0; i < offSetPts.length; i += 2) {
|
const edges = new THREE.EdgesGeometry( geometry, 15 );
|
||||||
if (
|
edges.type = 'BufferGeometry'
|
||||||
offSetPts[i] == offSetPts[i - 2] &&
|
edges.parameters = undefined
|
||||||
offSetPts[i + 1] == offSetPts[i - 1]
|
|
||||||
) continue;
|
const line = new THREE.LineSegments( edges, new THREE.LineBasicMaterial( { color: 0x000000 } ) );
|
||||||
mesh.add(
|
line.userData.type = 'line'
|
||||||
ptObj([offSetPts[i], offSetPts[i + 1], 8])
|
|
||||||
)
|
const vertices = new THREE.Points( edges, new THREE.PointsMaterial() );
|
||||||
}
|
vertices.userData.type = 'point'
|
||||||
|
vertices.layers.enable(1)
|
||||||
|
|
||||||
|
mesh.add(line)
|
||||||
|
mesh.add(vertices)
|
||||||
|
|
||||||
|
// for (let i = 0; i < offSetPts.length; i += 2) {
|
||||||
|
// if (
|
||||||
|
// offSetPts[i] == offSetPts[i - 2] &&
|
||||||
|
// offSetPts[i + 1] == offSetPts[i - 1]
|
||||||
|
// ) continue;
|
||||||
|
// mesh.add(
|
||||||
|
// ptObj([offSetPts[i], offSetPts[i + 1], 0], false),
|
||||||
|
// ptObj([offSetPts[i], offSetPts[i + 1], 8], false),
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
mesh.matrixAutoUpdate = false;
|
mesh.matrixAutoUpdate = false;
|
||||||
|
@ -103,7 +123,6 @@ export function extrude(sketch) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
this.render()
|
this.render()
|
||||||
|
|
||||||
// sketch.visible = false
|
// sketch.visible = false
|
||||||
|
|
|
@ -1,106 +1,112 @@
|
||||||
import * as THREE from '../node_modules/three/src/Three';
|
import * as THREE from '../node_modules/three/src/Three';
|
||||||
import { raycaster, color, hoverColor } from './shared';
|
import { raycaster, color, hoverColor } from './shared';
|
||||||
|
|
||||||
|
|
||||||
|
let ptLoc
|
||||||
|
|
||||||
export function onHover(e) {
|
export function onHover(e) {
|
||||||
if (this.mode || e.buttons) return
|
if (this.mode || e.buttons) return
|
||||||
|
|
||||||
raycaster.setFromCamera(
|
raycaster.setFromCamera(
|
||||||
new THREE.Vector2(
|
new THREE.Vector2(
|
||||||
(e.clientX - this.rect.left)/ this.rect.width * 2 - 1,
|
(e.clientX - this.rect.left) / this.rect.width * 2 - 1,
|
||||||
- (e.clientY - this.rect.top)/ this.rect.height * 2 + 1
|
- (e.clientY - this.rect.top) / this.rect.height * 2 + 1
|
||||||
),
|
),
|
||||||
this.camera
|
this.camera
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
let hoverPts;
|
let hoverPts;
|
||||||
let idx = []
|
|
||||||
|
|
||||||
if (this.obj3d.userData.type == 'sketch') {
|
if (this.obj3d.userData.type != 'sketch') {
|
||||||
hoverPts = raycaster.intersectObjects([...this.obj3d.children[1].children, ...this.obj3d.children])
|
raycaster.layers.set(1)
|
||||||
|
|
||||||
if (hoverPts.length) {
|
|
||||||
|
|
||||||
let minDist = Infinity;
|
|
||||||
for (let i = 0; i < hoverPts.length; i++) {
|
|
||||||
if (!hoverPts[i].distanceToRay) continue;
|
|
||||||
if (hoverPts[i].distanceToRay < minDist - 0.0001) {
|
|
||||||
minDist = hoverPts[i].distanceToRay
|
|
||||||
idx = [i]
|
|
||||||
} else if (Math.abs(hoverPts[i].distanceToRay - minDist) < 0.0001) {
|
|
||||||
idx.push(i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// console.log(hoverPts, idx)
|
|
||||||
if (!idx.length) idx.push(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// hoverPts = raycaster.intersectObjects(this.obj3d.children)
|
|
||||||
hoverPts = raycaster.intersectObjects(this.obj3d.children, true)
|
hoverPts = raycaster.intersectObjects(this.obj3d.children, true)
|
||||||
|
} else {
|
||||||
if (hoverPts.length) {
|
raycaster.layers.set(0)
|
||||||
|
hoverPts = raycaster.intersectObjects([...this.obj3d.children[1].children, ...this.obj3d.children])
|
||||||
// console.log(hoverPts)
|
|
||||||
// for (let i = 0; i < hoverPts.length; i++) {
|
|
||||||
// const obj = hoverPts[i].object
|
|
||||||
// if (['point', 'plane'].includes(obj.userData.type)) {
|
|
||||||
// idx.push(i)
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
let minDist = Infinity;
|
|
||||||
for (let i = 0; i < hoverPts.length; i++) {
|
|
||||||
if (!hoverPts[i].distanceToRay) continue;
|
|
||||||
|
|
||||||
if (hoverPts[i].distanceToRay < minDist - 0.0001) {
|
|
||||||
minDist = hoverPts[i].distanceToRay
|
|
||||||
idx = [i]
|
|
||||||
} else if (Math.abs(hoverPts[i].distanceToRay - minDist) < 0.0001) {
|
|
||||||
idx.push(i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!idx.length) {
|
|
||||||
const obj = hoverPts[0].object
|
|
||||||
if (obj.userData.type == "mesh" && obj.visible) {
|
|
||||||
idx.push(0)
|
|
||||||
} else if (['point', 'plane'].includes(obj.userData.type)) {
|
|
||||||
idx.push(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let idx = []
|
||||||
|
if (hoverPts.length) {
|
||||||
|
|
||||||
|
let minDist = Infinity;
|
||||||
|
for (let i = 0; i < hoverPts.length; i++) {
|
||||||
|
if (!hoverPts[i].distanceToRay) continue;
|
||||||
|
if (hoverPts[i].distanceToRay < minDist - 0.0001) {
|
||||||
|
idx = [i]
|
||||||
|
|
||||||
|
if (this.obj3d.userData.type != 'sketch') break
|
||||||
|
|
||||||
|
minDist = hoverPts[i].distanceToRay
|
||||||
|
} else if (Math.abs(hoverPts[i].distanceToRay - minDist) < 0.0001) {
|
||||||
|
idx.push(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!idx.length) {
|
||||||
|
idx.push(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx.length) { // after filtering, if hovered objs still exists
|
||||||
|
|
||||||
if (idx.length) { // after filtering, hovered objs still exists
|
|
||||||
if (hoverPts[idx[0]].object != this.hovered[0]) { // if the previous hovered obj is not the same as current
|
if (hoverPts[idx[0]].object != this.hovered[0]) { // if the previous hovered obj is not the same as current
|
||||||
|
|
||||||
for (let x = 0; x < this.hovered.length; x++) {
|
for (let x = 0; x < this.hovered.length; x++) { // first clear old hovers that are not selected
|
||||||
const obj = this.hovered[x]
|
const obj = this.hovered[x]
|
||||||
if (obj && !this.selected.includes(obj)) {
|
if (!this.selected.includes(obj)) {
|
||||||
obj.material.color.set(color[obj.userData.type])
|
if (typeof obj == 'object') {
|
||||||
|
obj.material.color.set(color[obj.userData.type])
|
||||||
|
|
||||||
|
if (this.obj3d.userData.type != 'sketch') {
|
||||||
|
if (obj.userData.type == 'mesh') {
|
||||||
|
obj.children[0].material.color.set(color['line'])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// this.obj3d.children[0].children[this.fptObj[obj]].visible = false
|
||||||
|
this.obj3d.children[0].children[0].visible = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.hovered = []
|
this.hovered = []
|
||||||
|
|
||||||
for (let x = 0; x < idx.length; x++) {
|
for (let x = 0; x < idx.length; x++) {
|
||||||
const obj = hoverPts[idx[x]].object
|
let obj = hoverPts[idx[x]].object
|
||||||
obj.material.color.set(hoverColor[obj.userData.type])
|
|
||||||
|
if (this.obj3d.userData.type == 'sketch') {
|
||||||
|
obj.material.color.set(hoverColor[obj.userData.type])
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (obj.userData.type == 'mesh') {
|
||||||
|
obj.children[0].material.color.set(hoverColor['line'])
|
||||||
|
} else if (obj.userData.type == 'plane') {
|
||||||
|
obj.material.color.set(hoverColor[obj.userData.type])
|
||||||
|
} else if (obj.userData.type == 'point') {
|
||||||
|
|
||||||
|
ptLoc = obj.geometry.attributes.position.array
|
||||||
|
.slice(
|
||||||
|
3 * hoverPts[idx[x]].index,
|
||||||
|
3 * hoverPts[idx[x]].index + 3
|
||||||
|
)
|
||||||
|
|
||||||
|
// const pp = this.obj3d.children[0].children[this.fptIdx % 3]
|
||||||
|
const pp = this.obj3d.children[0].children[0]
|
||||||
|
pp.geometry.attributes.position.array.set(ptLoc)
|
||||||
|
pp.matrix = obj.parent.matrix
|
||||||
|
pp.geometry.attributes.position.needsUpdate = true
|
||||||
|
pp.visible = true
|
||||||
|
|
||||||
|
obj = hoverPts[idx[x]].index
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
this.hovered.push(obj)
|
this.hovered.push(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,11 +115,22 @@ export function onHover(e) {
|
||||||
}
|
}
|
||||||
} else { // no hovered object after filtering
|
} else { // no hovered object after filtering
|
||||||
if (this.hovered.length) { // if previously something was hovered, then we need to clear it
|
if (this.hovered.length) { // if previously something was hovered, then we need to clear it
|
||||||
|
|
||||||
|
|
||||||
for (let x = 0; x < this.hovered.length; x++) {
|
for (let x = 0; x < this.hovered.length; x++) {
|
||||||
const obj = this.hovered[x]
|
const obj = this.hovered[x]
|
||||||
// console.log(obj, 'here')
|
|
||||||
if (!this.selected.includes(obj)) {
|
if (!this.selected.includes(obj)) {
|
||||||
obj.material.color.set(color[obj.userData.type])
|
if (typeof obj == 'object') {
|
||||||
|
obj.material.color.set(color[obj.userData.type])
|
||||||
|
if (this.obj3d.userData.type != 'sketch') {
|
||||||
|
if (obj.userData.type == 'mesh') {
|
||||||
|
obj.children[0].material.color.set(color['line'])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// this.obj3d.children[0].children[this.fptObj[obj]].visible = false
|
||||||
|
this.obj3d.children[0].children[0].visible = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.hovered = []
|
this.hovered = []
|
||||||
|
@ -122,6 +139,8 @@ export function onHover(e) {
|
||||||
this.obj3d.dispatchEvent({ type: 'change' })
|
this.obj3d.dispatchEvent({ type: 'change' })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let draggedLabel;
|
let draggedLabel;
|
||||||
|
@ -129,40 +148,70 @@ export function onPick(e) {
|
||||||
if (this.mode || e.buttons != 1) return
|
if (this.mode || e.buttons != 1) return
|
||||||
|
|
||||||
if (this.hovered.length) {
|
if (this.hovered.length) {
|
||||||
|
const obj = this.hovered[this.hovered.length - 1]
|
||||||
|
|
||||||
this.selected.push(this.hovered[this.hovered.length - 1])
|
this.selected.push(this.hovered[this.hovered.length - 1])
|
||||||
|
|
||||||
switch (this.hovered[0].userData.type) {
|
if (this.obj3d.userData.type != 'sketch') {
|
||||||
case 'dimension':
|
if (typeof obj == 'object') {
|
||||||
const idx = this.obj3d.children[1].children.indexOf(this.hovered[0])
|
if (obj.userData.type == "mesh") {
|
||||||
if (idx % 2) {
|
obj.material.color.set(hoverColor[obj.userData.type])
|
||||||
|
|
||||||
this.onDragDim = this._onMoveDimension(
|
|
||||||
this.obj3d.children[1].children[idx],
|
|
||||||
this.obj3d.children[1].children[idx - 1],
|
|
||||||
)
|
|
||||||
this.canvas.addEventListener('pointermove', this.onDragDim);
|
|
||||||
this.canvas.addEventListener('pointerup', this.onRelease)
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
const pp = this.obj3d.children[0].children[this.fptIdx % 3 + 1]
|
||||||
|
const p0 = this.obj3d.children[0].children[0]
|
||||||
|
|
||||||
draggedLabel = this.obj3d.children[1].children[idx].label
|
pp.geometry.attributes.position.array.set(p0.geometry.attributes.position.array)
|
||||||
draggedLabel.style.zIndex = -1;
|
pp.matrix = p0.matrix
|
||||||
break;
|
pp.geometry.attributes.position.needsUpdate = true
|
||||||
case 'point':
|
pp.visible = true
|
||||||
|
|
||||||
this.canvas.addEventListener('pointermove', this.onDrag);
|
this.fptObj[obj] = this.fptIdx
|
||||||
this.canvas.addEventListener('pointerup', this.onRelease)
|
this.fptIdx++
|
||||||
break;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
if (typeof this.hovered[0] == 'object') {
|
||||||
break;
|
switch (this.hovered[0].userData.type) {
|
||||||
|
case 'dimension':
|
||||||
|
const idx = this.obj3d.children[1].children.indexOf(this.hovered[0])
|
||||||
|
if (idx % 2) {
|
||||||
|
|
||||||
|
this.onDragDim = this._onMoveDimension(
|
||||||
|
this.obj3d.children[1].children[idx],
|
||||||
|
this.obj3d.children[1].children[idx - 1],
|
||||||
|
)
|
||||||
|
this.canvas.addEventListener('pointermove', this.onDragDim);
|
||||||
|
this.canvas.addEventListener('pointerup', this.onRelease)
|
||||||
|
}
|
||||||
|
|
||||||
|
draggedLabel = this.obj3d.children[1].children[idx].label
|
||||||
|
draggedLabel.style.zIndex = -1;
|
||||||
|
break;
|
||||||
|
case 'point':
|
||||||
|
|
||||||
|
this.canvas.addEventListener('pointermove', this.onDrag);
|
||||||
|
this.canvas.addEventListener('pointerup', this.onRelease)
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
for (let x = 0; x < this.selected.length; x++) {
|
for (let x = 0; x < this.selected.length; x++) {
|
||||||
const obj = this.selected[x]
|
const obj = this.selected[x]
|
||||||
obj.material.color.set(color[obj.userData.type])
|
if (typeof obj == 'object') {
|
||||||
|
obj.material.color.set(color[obj.userData.type])
|
||||||
|
if (this.obj3d.userData.type != 'sketch' && obj.userData.type == 'mesh') {
|
||||||
|
obj.children[0].material.color.set(color['line'])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.obj3d.children[0].children[this.fptObj[obj] + 1].visible = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
this.obj3d.children[0].children[0].visible = false
|
||||||
this.obj3d.dispatchEvent({ type: 'change' })
|
this.obj3d.dispatchEvent({ type: 'change' })
|
||||||
this.selected = []
|
this.selected = []
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,14 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.btn-green {
|
||||||
|
cursor: pointer;
|
||||||
|
@apply fill-current
|
||||||
|
bg-transparent text-gray-700
|
||||||
|
hover:bg-gray-300 hover:text-green-200;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.tooltip {
|
.tooltip {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
display: block;
|
display: block;
|
||||||
|
|
|
@ -58,7 +58,7 @@ export class DepTree {
|
||||||
|
|
||||||
this.allIds.splice(spliceIdx, 1)
|
this.allIds.splice(spliceIdx, 1)
|
||||||
|
|
||||||
const deletedObj = sc.obj3d.children.splice(spliceIdx + 4, 1)[0]
|
const deletedObj = sc.obj3d.children.splice(spliceIdx + 4, 1)[0] // first 4 elements are non geom
|
||||||
|
|
||||||
deletedObj.traverse((obj)=>{
|
deletedObj.traverse((obj)=>{
|
||||||
if (obj.geometry) obj.geometry.dispose()
|
if (obj.geometry) obj.geometry.dispose()
|
||||||
|
|
|
@ -43,7 +43,7 @@ export const NavBar = () => {
|
||||||
if (sc.selected.length != 2 || !sc.selected.every(e => e.userData.type == 'mesh')) return
|
if (sc.selected.length != 2 || !sc.selected.every(e => e.userData.type == 'mesh')) return
|
||||||
// console.log('here')
|
// console.log('here')
|
||||||
const [m1, m2] = sc.selected
|
const [m1, m2] = sc.selected
|
||||||
const mesh = subtract(m1, m2)
|
const mesh = sc.subtract(m1, m2)
|
||||||
|
|
||||||
console.log(mesh, 'meshres')
|
console.log(mesh, 'meshres')
|
||||||
dispatch({ type: 'rx-boolean', mesh, deps: [m1.name, m2.name] })
|
dispatch({ type: 'rx-boolean', mesh, deps: [m1.name, m2.name] })
|
||||||
|
@ -68,29 +68,3 @@ export const NavBar = () => {
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
const subtract = (m1, m2) => {
|
|
||||||
// //Create a bsp tree from each of the meshes
|
|
||||||
// console.log(sc.selected.length != 2 || !sc.selected.every(e => e.userData.type == 'mesh'), "wtf")
|
|
||||||
|
|
||||||
|
|
||||||
let bspA = BoolOp.fromMesh(m1)
|
|
||||||
let bspB = BoolOp.fromMesh(m2)
|
|
||||||
m1.visible = false
|
|
||||||
m2.visible = false
|
|
||||||
|
|
||||||
// // Subtract one bsp from the other via .subtract... other supported modes are .union and .intersect
|
|
||||||
|
|
||||||
let bspResult = bspA.subtract(bspB)
|
|
||||||
|
|
||||||
// //Get the resulting mesh from the result bsp, and assign meshA.material to the resulting mesh
|
|
||||||
|
|
||||||
let meshResult = BoolOp.toMesh(bspResult, m1.matrix, m1.material)
|
|
||||||
meshResult.userData.type = 'mesh'
|
|
||||||
meshResult.name = `${m1.name}-${m2.name}`
|
|
||||||
|
|
||||||
sc.obj3d.add(meshResult)
|
|
||||||
|
|
||||||
return meshResult
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import React, { useReducer } from 'react';
|
||||||
import { useDispatch, useSelector } from 'react-redux'
|
import { useDispatch, useSelector } from 'react-redux'
|
||||||
import { MdEdit, MdVisibilityOff, MdVisibility, MdDelete } from 'react-icons/md'
|
import { MdEdit, MdVisibilityOff, MdVisibility, MdDelete } from 'react-icons/md'
|
||||||
|
|
||||||
|
import { FaCube, FaEdit } from 'react-icons/fa'
|
||||||
|
|
||||||
export const Tree = () => {
|
export const Tree = () => {
|
||||||
const treeEntries = useSelector(state => state.treeEntries)
|
const treeEntries = useSelector(state => state.treeEntries)
|
||||||
|
@ -17,6 +18,12 @@ export const Tree = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const treeIcons = {
|
||||||
|
'mesh': FaCube,
|
||||||
|
'sketch': FaEdit
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const TreeEntry = ({ entId }) => {
|
const TreeEntry = ({ entId }) => {
|
||||||
|
|
||||||
const treeEntries = useSelector(state => state.treeEntries.byId)
|
const treeEntries = useSelector(state => state.treeEntries.byId)
|
||||||
|
@ -28,18 +35,30 @@ const TreeEntry = ({ entId }) => {
|
||||||
|
|
||||||
entry = treeEntries[entId]
|
entry = treeEntries[entId]
|
||||||
|
|
||||||
if (entId[0] == "s") {
|
if (treeEntries[entId].obj3d) {
|
||||||
obj3d = treeEntries[entId].obj3d
|
obj3d = treeEntries[entId].obj3d
|
||||||
} else {
|
} else {
|
||||||
obj3d = treeEntries[entId]
|
obj3d = treeEntries[entId]
|
||||||
}
|
}
|
||||||
|
console.log(obj3d.userData.type)
|
||||||
|
let Icon = treeIcons[obj3d.userData.type]
|
||||||
|
|
||||||
const [_, forceUpdate] = useReducer(x => x + 1, 0);
|
const [_, forceUpdate] = useReducer(x => x + 1, 0);
|
||||||
|
|
||||||
const vis = obj3d.visible
|
// const vis = obj3d.visible
|
||||||
|
const vis = obj3d.layers.mask&1
|
||||||
|
|
||||||
return <div className='bg-gray-50 flex justify-between w-full'>
|
return <div className='btn-light select-none flex justify-start w-full h-7 items-center text-sm'
|
||||||
<div className="btn-light"
|
|
||||||
|
onDoubleClick={() => {
|
||||||
|
activeSketchId && treeEntries[activeSketchId].deactivate()
|
||||||
|
entry.activate()
|
||||||
|
sc.clearSelection()
|
||||||
|
sc.activeSketch = entry;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Icon className='h-full w-auto p-1.5' />
|
||||||
|
<div className="btn-light pl-1"
|
||||||
onPointerEnter={() => {
|
onPointerEnter={() => {
|
||||||
if (entId[0] == 'm') {
|
if (entId[0] == 'm') {
|
||||||
// entry.material.color.set(color.hover)
|
// entry.material.color.set(color.hover)
|
||||||
|
@ -64,46 +83,31 @@ const TreeEntry = ({ entId }) => {
|
||||||
>
|
>
|
||||||
{entId}
|
{entId}
|
||||||
</div>
|
</div>
|
||||||
<div className='flex'>
|
<div className='flex h-full ml-auto'>
|
||||||
<div className='btn-light'
|
|
||||||
onClick={() => {
|
|
||||||
activeSketchId && treeEntries[activeSketchId].deactivate()
|
|
||||||
entry.activate()
|
|
||||||
sc.clearSelection()
|
|
||||||
sc.activeSketch = entry;
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<MdEdit />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='btn-light'
|
<MdDelete className='btn-green h-full w-auto p-1.5'
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
dispatch({ type: 'delete-node', id: entId })
|
dispatch({ type: 'delete-node', id: entId })
|
||||||
}}
|
}}
|
||||||
>
|
/>
|
||||||
<MdDelete />
|
|
||||||
</div>
|
|
||||||
{
|
{
|
||||||
vis ?
|
vis ?
|
||||||
<div className='btn-light'
|
<MdVisibility className='btn-green h-full w-auto p-1.5'
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
obj3d.visible = false;
|
obj3d.traverse((e)=>e.layers.disable(0))
|
||||||
sc.render()
|
sc.render()
|
||||||
forceUpdate()
|
forceUpdate()
|
||||||
}}
|
}}
|
||||||
>
|
/>
|
||||||
<MdVisibility />
|
|
||||||
</div>
|
|
||||||
:
|
:
|
||||||
<div className='btn-light'
|
<MdVisibilityOff className='btn-green h-full w-auto p-1.5'
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
obj3d.visible = true;
|
obj3d.traverse((e)=>e.layers.enable(0))
|
||||||
sc.render()
|
sc.render()
|
||||||
forceUpdate()
|
forceUpdate()
|
||||||
}}
|
}}
|
||||||
>
|
/>
|
||||||
<MdVisibilityOff />
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -12,20 +12,16 @@ raycaster.params.Points.threshold = 0.1;
|
||||||
|
|
||||||
|
|
||||||
const color = {
|
const color = {
|
||||||
// background:0xdae1e7,
|
background:0xdae1e7,
|
||||||
background:0xffffff,
|
|
||||||
// background:0xbbbbbb,
|
|
||||||
lighting: 0xFFFFFF,
|
lighting: 0xFFFFFF,
|
||||||
emissive: 0x072534,
|
emissive: 0x072534,
|
||||||
|
|
||||||
hover: 0x00ff00,
|
hover: 0x00ff00,
|
||||||
point: 0x555555, //points
|
point: 0x555555, //points
|
||||||
line: 0x555555, //lines
|
line: 0x000000, //lines
|
||||||
mesh: 0x156289, //mesh:
|
mesh: 0x9DCFED, //mesh:
|
||||||
dimension: 0x0000ff, //
|
dimension: 0x0000ff, //
|
||||||
|
|
||||||
// plane: 0xdaacac, //
|
|
||||||
// planeBorder: 0xc59797, //
|
|
||||||
plane: 0x88adcd, //
|
plane: 0x88adcd, //
|
||||||
planeBorder: 0xa7cae8, //
|
planeBorder: 0xa7cae8, //
|
||||||
}
|
}
|
||||||
|
@ -34,7 +30,7 @@ const hoverColor = {
|
||||||
hover: 0x00ff00,
|
hover: 0x00ff00,
|
||||||
point: 0x00ff00, //points
|
point: 0x00ff00, //points
|
||||||
line: 0x00ff00, //lines
|
line: 0x00ff00, //lines
|
||||||
mesh: 0x00ff00, //mesh:
|
mesh: 0xFAB601, //mesh:
|
||||||
dimension: 0x00ff00, //
|
dimension: 0x00ff00, //
|
||||||
plane: 0x005dff, //
|
plane: 0x005dff, //
|
||||||
}
|
}
|
||||||
|
@ -52,7 +48,7 @@ const pointMaterial = new THREE.PointsMaterial({
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
const ptObj = (n) => {
|
const ptObj = (n, visibility = true) => {
|
||||||
const ret = new THREE.Points(
|
const ret = new THREE.Points(
|
||||||
new THREE.BufferGeometry().setAttribute('position',
|
new THREE.BufferGeometry().setAttribute('position',
|
||||||
new THREE.Float32BufferAttribute(n || 3, 3)
|
new THREE.Float32BufferAttribute(n || 3, 3)
|
||||||
|
@ -61,6 +57,7 @@ const ptObj = (n) => {
|
||||||
);
|
);
|
||||||
ret.name = "p" + id++
|
ret.name = "p" + id++
|
||||||
ret.userData.type = 'point'
|
ret.userData.type = 'point'
|
||||||
|
ret.visible = visibility
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,6 +142,7 @@ async function awaitSelection(...criteria) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.rc = raycaster
|
||||||
|
|
||||||
|
|
||||||
export { lineMaterial, pointMaterial, _vec2, _vec3, raycaster, color, hoverColor, ptObj, lineObj, awaitSelection }
|
export { lineMaterial, pointMaterial, _vec2, _vec3, raycaster, color, hoverColor, ptObj, lineObj, awaitSelection }
|
Loading…
Reference in New Issue