ugly but works
parent
d88eb2845d
commit
636f8bc560
|
@ -10,8 +10,8 @@ import { setCoincident, setOrdinate } from './constraintEvents'
|
||||||
import { get3PtArc } from './drawArc'
|
import { get3PtArc } from './drawArc'
|
||||||
import { replacer, reviver } from './utils'
|
import { replacer, reviver } from './utils'
|
||||||
import { AxesHelper } from './sketchAxes'
|
import { AxesHelper } from './sketchAxes'
|
||||||
import { drawDimension, _onMoveDimension, setDimLines, updateDim } from './drawDimension';
|
import { drawDimension, _onMoveDimension, setDimLines, updateDim, drawAngle } from './drawDimension';
|
||||||
import { drawAngle, _onMoveAngle, setAngLines, updateAng } from './drawAngle';
|
import { updateAng } from './drawAngle';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -131,9 +131,9 @@ class Sketch {
|
||||||
this.drawDimension = drawDimension.bind(this)
|
this.drawDimension = drawDimension.bind(this)
|
||||||
this.drawAngle = drawAngle.bind(this)
|
this.drawAngle = drawAngle.bind(this)
|
||||||
this._onMoveDimension = _onMoveDimension.bind(this)
|
this._onMoveDimension = _onMoveDimension.bind(this)
|
||||||
this._onMoveAngle = _onMoveAngle.bind(this)
|
// this._onMoveAngle = _onMoveAngle.bind(this)
|
||||||
this.setDimLines = setDimLines.bind(this)
|
this.setDimLines = setDimLines.bind(this)
|
||||||
this.setAngLines = setAngLines.bind(this)
|
// this.setAngLines = setAngLines.bind(this)
|
||||||
this.updateDim = updateDim.bind(this)
|
this.updateDim = updateDim.bind(this)
|
||||||
this.updateAng = updateAng.bind(this)
|
this.updateAng = updateAng.bind(this)
|
||||||
|
|
||||||
|
@ -223,11 +223,11 @@ class Sketch {
|
||||||
this.mode = "arc"
|
this.mode = "arc"
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
this.drawDimension()
|
this.drawDimension('d')
|
||||||
this.mode = ""
|
this.mode = ""
|
||||||
break;
|
break;
|
||||||
case 'q':
|
case 'q':
|
||||||
this.drawAngle()
|
this.drawDimension('a')
|
||||||
this.mode = ""
|
this.mode = ""
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
|
@ -482,10 +482,10 @@ class Sketch {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// this.setDimLines()
|
this.setDimLines()
|
||||||
// this.setAngLines()
|
// this.setAngLines()
|
||||||
|
|
||||||
this.obj3d.dispatchEvent({ type: 'change' })
|
// this.obj3d.dispatchEvent({ type: 'change' })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
363
src/drawAngle.js
363
src/drawAngle.js
|
@ -18,97 +18,6 @@ const pointMaterial = new THREE.PointsMaterial({
|
||||||
|
|
||||||
const divisions = 12
|
const divisions = 12
|
||||||
|
|
||||||
export async function drawAngle() {
|
|
||||||
let selection = await this.awaitSelection({ line: 2 })
|
|
||||||
|
|
||||||
if (selection == null) return;
|
|
||||||
|
|
||||||
const line = new THREE.LineSegments(
|
|
||||||
new THREE.BufferGeometry().setAttribute('position',
|
|
||||||
new THREE.Float32BufferAttribute(Array((divisions + 2) * 2 * 3).fill(-0.001), 3)
|
|
||||||
),
|
|
||||||
lineMaterial.clone()
|
|
||||||
);
|
|
||||||
|
|
||||||
const point = new THREE.Points(
|
|
||||||
new THREE.BufferGeometry().setAttribute('position',
|
|
||||||
new THREE.Float32BufferAttribute(3, 3)
|
|
||||||
),
|
|
||||||
pointMaterial.clone()
|
|
||||||
)
|
|
||||||
|
|
||||||
line.userData.ids = selection.map(e => e.name)
|
|
||||||
|
|
||||||
line.layers.enable(2)
|
|
||||||
point.layers.enable(2)
|
|
||||||
|
|
||||||
let angle = getAngle(selection)
|
|
||||||
|
|
||||||
|
|
||||||
this.obj3d.children[1].add(line).add(point)
|
|
||||||
|
|
||||||
const onMove = this._onMoveAngle(point, line)
|
|
||||||
|
|
||||||
point.label = document.createElement('div');
|
|
||||||
point.label.textContent = angle.toFixed(3);
|
|
||||||
point.label.contentEditable = true;
|
|
||||||
this.labelContainer.append(point.label)
|
|
||||||
|
|
||||||
let onEnd, onKey;
|
|
||||||
let add = await new Promise((res) => {
|
|
||||||
onEnd = (e) => {
|
|
||||||
point.userData.offset = vecArr[5].toArray()
|
|
||||||
res(true)
|
|
||||||
}
|
|
||||||
onKey = (e) => e.key == 'Escape' && res(false)
|
|
||||||
|
|
||||||
this.canvas.addEventListener('pointermove', onMove)
|
|
||||||
this.canvas.addEventListener('pointerdown', onEnd)
|
|
||||||
window.addEventListener('keydown', onKey)
|
|
||||||
})
|
|
||||||
|
|
||||||
this.canvas.removeEventListener('pointermove', onMove)
|
|
||||||
this.canvas.removeEventListener('pointerdown', onEnd)
|
|
||||||
window.removeEventListener('keydown', onKey)
|
|
||||||
point.geometry.computeBoundingSphere()
|
|
||||||
line.geometry.computeBoundingSphere()
|
|
||||||
|
|
||||||
if (add) {
|
|
||||||
|
|
||||||
this.constraints.set(++this.c_id,
|
|
||||||
[
|
|
||||||
'angle', angle,
|
|
||||||
[-1, -1, selection[0].name, selection[1].name]
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
selection[0].userData.constraints.push(this.c_id)
|
|
||||||
selection[1].userData.constraints.push(this.c_id)
|
|
||||||
|
|
||||||
this.updateOtherBuffers()
|
|
||||||
|
|
||||||
line.name = this.c_id
|
|
||||||
line.userData.type = 'dimension'
|
|
||||||
point.name = this.c_id
|
|
||||||
point.userData.type = 'dimension'
|
|
||||||
|
|
||||||
point.label.addEventListener('focus', this.updateAng(this.c_id))
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
this.obj3d.children[1].children.splice(this.obj3d.children[1].length - 2, 2).forEach(
|
|
||||||
e => {
|
|
||||||
e.geometry.dispose()
|
|
||||||
e.material.dispose()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
this.labelContainer.removeChild(this.labelContainer.lastChild);
|
|
||||||
sc.render()
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export function updateAng(c_id) {
|
export function updateAng(c_id) {
|
||||||
|
@ -136,74 +45,74 @@ export function updateAng(c_id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
let ids, _l1, _l2
|
// let ids, _l1, _l2
|
||||||
export function _onMoveAngle(point, line) {
|
// export function _onMoveAngle(point, line) {
|
||||||
|
|
||||||
ids = line.userData.ids
|
// ids = line.userData.ids
|
||||||
|
|
||||||
_l1 = this.obj3d.children[this.objIdx.get(ids[0])].geometry.attributes.position.array
|
// _l1 = this.obj3d.children[this.objIdx.get(ids[0])].geometry.attributes.position.array
|
||||||
_l2 = this.obj3d.children[this.objIdx.get(ids[1])].geometry.attributes.position.array
|
// _l2 = this.obj3d.children[this.objIdx.get(ids[1])].geometry.attributes.position.array
|
||||||
|
|
||||||
let loc;
|
// let loc;
|
||||||
|
|
||||||
return (e) => {
|
// return (e) => {
|
||||||
loc = this.getLocation(e)
|
// loc = this.getLocation(e)
|
||||||
|
|
||||||
p3.set(loc.x, loc.y)
|
// p3.set(loc.x, loc.y)
|
||||||
|
|
||||||
update(
|
// update(
|
||||||
line.geometry.attributes.position,
|
// line.geometry.attributes.position,
|
||||||
point.geometry.attributes.position,
|
// point.geometry.attributes.position,
|
||||||
_l1, _l2
|
// _l1, _l2
|
||||||
)
|
// )
|
||||||
|
|
||||||
// point.userData.offset = tagOffset.toArray() // save offset vector from center
|
// // point.userData.offset = tagOffset.toArray() // save offset vector from center
|
||||||
// point.userData.offset = tagOffset // save offset vector from center
|
// // point.userData.offset = tagOffset // save offset vector from center
|
||||||
// tagOffset = undefined
|
// // tagOffset = undefined
|
||||||
|
|
||||||
sc.render()
|
// sc.render()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
export function setAngLines() {
|
// export function setAngLines() {
|
||||||
|
|
||||||
const restoreLabels = this.labelContainer.childElementCount == 0;
|
// const restoreLabels = this.labelContainer.childElementCount == 0;
|
||||||
|
|
||||||
const dims = this.obj3d.children[1].children
|
// const dims = this.obj3d.children[1].children
|
||||||
|
|
||||||
let point, dist;
|
// let point, dist;
|
||||||
for (let i = 0; i < dims.length; i += 2) {
|
// for (let i = 0; i < dims.length; i += 2) {
|
||||||
// if (restoreLabels) {
|
// // if (restoreLabels) {
|
||||||
// point = dims[i + 1] // point node is at i+1
|
// // point = dims[i + 1] // point node is at i+1
|
||||||
// dist = this.constraints.get(point.name)[1]
|
// // dist = this.constraints.get(point.name)[1]
|
||||||
// point.label = document.createElement('div');
|
// // point.label = document.createElement('div');
|
||||||
// point.label.textContent = dist.toFixed(3);
|
// // point.label.textContent = dist.toFixed(3);
|
||||||
// point.label.contentEditable = true;
|
// // point.label.contentEditable = true;
|
||||||
// this.labelContainer.append(point.label)
|
// // this.labelContainer.append(point.label)
|
||||||
|
|
||||||
// point.label.addEventListener('focus', this.updateAng(this.c_id))
|
// // point.label.addEventListener('focus', this.updateAng(this.c_id))
|
||||||
// }
|
// // }
|
||||||
|
|
||||||
ids = dims[i].userData.ids
|
// ids = dims[i].userData.ids
|
||||||
|
|
||||||
_l1 = this.obj3d.children[this.objIdx.get(ids[0])].geometry.attributes.position.array
|
// _l1 = this.obj3d.children[this.objIdx.get(ids[0])].geometry.attributes.position.array
|
||||||
_l2 = this.obj3d.children[this.objIdx.get(ids[1])].geometry.attributes.position.array
|
// _l2 = this.obj3d.children[this.objIdx.get(ids[1])].geometry.attributes.position.array
|
||||||
|
|
||||||
|
|
||||||
tagOffset = dims[i + 1].userData.offset
|
// tagOffset = dims[i + 1].userData.offset
|
||||||
|
// p3.set(_l1[0] + tagOffset[0], _l1[1] + tagOffset[1])
|
||||||
|
|
||||||
|
|
||||||
|
// update(
|
||||||
|
// dims[i].geometry.attributes.position,
|
||||||
|
// dims[i + 1].geometry.attributes.position,
|
||||||
|
// _l1,
|
||||||
|
// _l2
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
|
||||||
update(
|
// }
|
||||||
dims[i].geometry.attributes.position,
|
|
||||||
dims[i + 1].geometry.attributes.position,
|
|
||||||
_l1,
|
|
||||||
_l2
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -271,120 +180,120 @@ const getAngle = (Obj3dLines) => {
|
||||||
return deltaAngle / Math.PI * 180
|
return deltaAngle / Math.PI * 180
|
||||||
}
|
}
|
||||||
|
|
||||||
function update(linegeom, pointgeom, _l1, _l2) {
|
// function update(linegeom, pointgeom, _l1, _l2) {
|
||||||
|
|
||||||
let i = 0;
|
// let i = 0;
|
||||||
for (; i < 4;) {
|
// for (; i < 4;) {
|
||||||
const arr = i == 0 ? _l1 : _l2
|
// const arr = i == 0 ? _l1 : _l2
|
||||||
vecArr[i++].set(arr[0], arr[1])
|
// vecArr[i++].set(arr[0], arr[1])
|
||||||
vecArr[i++].set(arr[3] - arr[0], arr[4] - arr[1])
|
// vecArr[i++].set(arr[3] - arr[0], arr[4] - arr[1])
|
||||||
}
|
// }
|
||||||
|
|
||||||
const centerScalar = findIntersection(...vecArr.slice(0, 4))
|
// const centerScalar = findIntersection(...vecArr.slice(0, 4))
|
||||||
const center = vecArr[i++].addVectors(vecArr[0], vecArr[1].clone().multiplyScalar(centerScalar))
|
// const center = vecArr[4].addVectors(vecArr[0], vecArr[1].clone().multiplyScalar(centerScalar))
|
||||||
|
|
||||||
if (tagOffset === undefined) {
|
// // if (tagOffset === undefined) {
|
||||||
vecArr[i++].subVectors(p3, center)
|
// // vecArr[5].subVectors(p3, center)
|
||||||
} else {
|
// // } else {
|
||||||
p3.set(center.x + tagOffset[0], center.y + tagOffset[1])
|
// // p3.set(center.x + tagOffset[0], center.y + tagOffset[1])
|
||||||
vecArr[i++].subVectors(p3, center)
|
// // }
|
||||||
}
|
// vecArr[5].subVectors(p3, center)
|
||||||
|
|
||||||
const tagRadius = vecArr[5].length()
|
// const tagRadius = vecArr[5].length()
|
||||||
|
|
||||||
/*
|
// /*
|
||||||
if tag is more than 90 deg away from midline, we shift everything by 180
|
// if tag is more than 90 deg away from midline, we shift everything by 180
|
||||||
|
|
||||||
a: array that describes absolute angular position of angle start, angle end, and tag
|
// a: array that describes absolute angular position of angle start, angle end, and tag
|
||||||
|
|
||||||
a[2]:
|
// a[2]:
|
||||||
tag a[1]:angle end
|
// tag a[1]:angle end
|
||||||
\ | /
|
// \ | /
|
||||||
\ | /
|
// \ | /
|
||||||
___\|/___ a[0]+dA/2:midline
|
// ___\|/___ a[0]+dA/2:midline
|
||||||
/ \
|
// / \
|
||||||
/ \
|
// / \
|
||||||
/ \
|
// / \
|
||||||
a[0]:angle start
|
// a[0]:angle start
|
||||||
*/
|
// */
|
||||||
|
|
||||||
for (let j = 1, i = 0; j < vecArr.length; j += 2, i++) {
|
// for (let j = 1, i = 0; j < vecArr.length; j += 2, i++) {
|
||||||
a[i] = Math.atan2(vecArr[j].y, vecArr[j].x)
|
// a[i] = Math.atan2(vecArr[j].y, vecArr[j].x)
|
||||||
}
|
// }
|
||||||
|
|
||||||
let dA = unreflex(a[1] - a[0])
|
// let dA = unreflex(a[1] - a[0])
|
||||||
|
|
||||||
|
|
||||||
let tagtoMidline = unreflex(a[2] - (a[0] + dA / 2))
|
// let tagtoMidline = unreflex(a[2] - (a[0] + dA / 2))
|
||||||
|
|
||||||
let shift = Math.abs(tagtoMidline) < Math.PI / 2 ? 0 : Math.PI;
|
// let shift = Math.abs(tagtoMidline) < Math.PI / 2 ? 0 : Math.PI;
|
||||||
|
|
||||||
let tA1 = unreflex(a[2] - (a[0] + shift))
|
// let tA1 = unreflex(a[2] - (a[0] + shift))
|
||||||
let tA2 = unreflex(a[2] - (a[0] + dA + shift))
|
// let tA2 = unreflex(a[2] - (a[0] + dA + shift))
|
||||||
|
|
||||||
|
|
||||||
let a1, deltaAngle;
|
// let a1, deltaAngle;
|
||||||
if (dA * tA1 < 0) {
|
// if (dA * tA1 < 0) {
|
||||||
a1 = a[0] + tA1 + shift
|
// a1 = a[0] + tA1 + shift
|
||||||
deltaAngle = dA - tA1
|
// deltaAngle = dA - tA1
|
||||||
} else if (dA * tA2 > 0) {
|
// } else if (dA * tA2 > 0) {
|
||||||
a1 = a[0] + shift
|
// a1 = a[0] + shift
|
||||||
deltaAngle = dA + tA2
|
// deltaAngle = dA + tA2
|
||||||
} else {
|
// } else {
|
||||||
a1 = a[0] + shift
|
// a1 = a[0] + shift
|
||||||
deltaAngle = dA
|
// deltaAngle = dA
|
||||||
}
|
// }
|
||||||
|
|
||||||
let points = linegeom.array
|
// let points = linegeom.array
|
||||||
|
|
||||||
let d = 0;
|
// let d = 0;
|
||||||
points[d++] = center.x + tagRadius * Math.cos(a1)
|
// points[d++] = center.x + tagRadius * Math.cos(a1)
|
||||||
points[d++] = center.y + tagRadius * Math.sin(a1)
|
// points[d++] = center.y + tagRadius * Math.sin(a1)
|
||||||
d++
|
// d++
|
||||||
|
|
||||||
const angle = a1 + (1 / divisions) * deltaAngle
|
// const angle = a1 + (1 / divisions) * deltaAngle
|
||||||
points[d++] = center.x + tagRadius * Math.cos(angle)
|
// points[d++] = center.x + tagRadius * Math.cos(angle)
|
||||||
points[d++] = center.y + tagRadius * Math.sin(angle)
|
// points[d++] = center.y + tagRadius * Math.sin(angle)
|
||||||
d++
|
// d++
|
||||||
|
|
||||||
for (i = 2; i <= divisions; i++) {
|
// for (i = 2; i <= divisions; i++) {
|
||||||
points[d++] = points[d - 4]
|
// points[d++] = points[d - 4]
|
||||||
points[d++] = points[d - 4]
|
// points[d++] = points[d - 4]
|
||||||
d++
|
// d++
|
||||||
const angle = a1 + (i / divisions) * deltaAngle
|
// const angle = a1 + (i / divisions) * deltaAngle
|
||||||
points[d++] = center.x + tagRadius * Math.cos(angle)
|
// points[d++] = center.x + tagRadius * Math.cos(angle)
|
||||||
points[d++] = center.y + tagRadius * Math.sin(angle)
|
// points[d++] = center.y + tagRadius * Math.sin(angle)
|
||||||
d++
|
// d++
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
// for (i = 0; i < 2; i++) {
|
||||||
points[d++] = vecArr[2 * i].x
|
// points[d++] = vecArr[2 * i].x
|
||||||
points[d++] = vecArr[2 * i].y
|
// points[d++] = vecArr[2 * i].y
|
||||||
d++
|
// d++
|
||||||
points[d++] = center.x + tagRadius * Math.cos(a[i] + shift)
|
// points[d++] = center.x + tagRadius * Math.cos(a[i] + shift)
|
||||||
points[d++] = center.y + tagRadius * Math.sin(a[i] + shift)
|
// points[d++] = center.y + tagRadius * Math.sin(a[i] + shift)
|
||||||
d++
|
// d++
|
||||||
}
|
// }
|
||||||
|
|
||||||
linegeom.needsUpdate = true;
|
// linegeom.needsUpdate = true;
|
||||||
|
|
||||||
pointgeom.array.set(p3.toArray())
|
// pointgeom.array.set(p3.toArray())
|
||||||
pointgeom.needsUpdate = true;
|
// pointgeom.needsUpdate = true;
|
||||||
|
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
const twoPi = Math.PI * 2
|
// const twoPi = Math.PI * 2
|
||||||
const negTwoPi = - Math.PI * 2
|
// const negTwoPi = - Math.PI * 2
|
||||||
const negPi = - Math.PI
|
// const negPi = - Math.PI
|
||||||
|
|
||||||
function unreflex(angle) {
|
// function unreflex(angle) {
|
||||||
if (angle > Math.PI) {
|
// if (angle > Math.PI) {
|
||||||
angle = negTwoPi + angle
|
// angle = negTwoPi + angle
|
||||||
} else if (angle < negPi) {
|
// } else if (angle < negPi) {
|
||||||
angle = twoPi + angle
|
// angle = twoPi + angle
|
||||||
}
|
// }
|
||||||
return angle
|
// return angle
|
||||||
}
|
// }
|
|
@ -13,21 +13,38 @@ const pointMaterial = new THREE.PointsMaterial({
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
export async function drawDimension() {
|
export async function drawDimension(cc) {
|
||||||
let selection = await this.awaitSelection({ point: 2 }, { point: 1, line: 1 })
|
//////////
|
||||||
|
let selection
|
||||||
|
if (cc == 'd') {
|
||||||
|
selection = await this.awaitSelection({ point: 2 }, { point: 1, line: 1 })
|
||||||
|
} else {
|
||||||
|
selection = await this.awaitSelection({ line: 2 })
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////
|
||||||
|
|
||||||
if (selection == null) return;
|
if (selection == null) return;
|
||||||
|
|
||||||
|
let line;
|
||||||
|
if (cc == 'd') {
|
||||||
|
line = new THREE.LineSegments(
|
||||||
|
|
||||||
const line = new THREE.LineSegments(
|
|
||||||
new THREE.BufferGeometry().setAttribute('position',
|
new THREE.BufferGeometry().setAttribute('position',
|
||||||
new THREE.Float32BufferAttribute(Array(3 * 8).fill(-0.001), 3)
|
new THREE.Float32BufferAttribute(Array(3 * 8).fill(-0.001), 3)
|
||||||
),
|
),
|
||||||
lineMaterial.clone()
|
lineMaterial.clone()
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
line = new THREE.LineSegments(
|
||||||
|
new THREE.BufferGeometry().setAttribute('position',
|
||||||
|
new THREE.Float32BufferAttribute(Array((divisions + 2) * 2 * 3).fill(-0.001), 3)
|
||||||
|
),
|
||||||
|
lineMaterial.clone()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const point = new THREE.Points(
|
const point = new THREE.Points(
|
||||||
new THREE.BufferGeometry().setAttribute('position',
|
new THREE.BufferGeometry().setAttribute('position',
|
||||||
|
@ -42,24 +59,19 @@ export async function drawDimension() {
|
||||||
point.layers.enable(2)
|
point.layers.enable(2)
|
||||||
|
|
||||||
|
|
||||||
|
//////////////
|
||||||
|
let dimVal, ptLineOrder;
|
||||||
|
|
||||||
let dist = 0
|
if (cc == 'd') {
|
||||||
let ptLineOrder;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (selection.every(e => e.userData.type == 'point')) {
|
if (selection.every(e => e.userData.type == 'point')) {
|
||||||
for (let i = 0; i < 3; i++) {
|
for (let i = 0; i < 3; i++) {
|
||||||
dist += (selection[0].geometry.attributes.position.array[i] - selection[1].geometry.attributes.position.array[i]) ** 2
|
dimVal += (selection[0].geometry.attributes.position.array[i] - selection[1].geometry.attributes.position.array[i]) ** 2
|
||||||
}
|
}
|
||||||
|
dimVal = Math.sqrt(dimVal)
|
||||||
dist = Math.sqrt(dist)
|
|
||||||
} else {
|
} else {
|
||||||
ptLineOrder = selection[0].userData.type == 'point' ? [0, 1] : [1, 0]
|
ptLineOrder = selection[0].userData.type == 'point' ? [0, 1] : [1, 0]
|
||||||
const ptArr = selection[ptLineOrder[0]].geometry.attributes.position.array
|
const ptArr = selection[ptLineOrder[0]].geometry.attributes.position.array
|
||||||
const lineArr = selection[ptLineOrder[1]].geometry.attributes.position.array
|
const lineArr = selection[ptLineOrder[1]].geometry.attributes.position.array
|
||||||
|
|
||||||
|
|
||||||
p1.set(lineArr[0], lineArr[1])
|
p1.set(lineArr[0], lineArr[1])
|
||||||
p2.set(lineArr[3], lineArr[4])
|
p2.set(lineArr[3], lineArr[4])
|
||||||
p3.set(ptArr[0], ptArr[1])
|
p3.set(ptArr[0], ptArr[1])
|
||||||
|
@ -67,27 +79,34 @@ export async function drawDimension() {
|
||||||
disp = p3.clone().sub(p1)
|
disp = p3.clone().sub(p1)
|
||||||
proj = dir.multiplyScalar(disp.dot(dir))
|
proj = dir.multiplyScalar(disp.dot(dir))
|
||||||
perpOffset = disp.clone().sub(proj)
|
perpOffset = disp.clone().sub(proj)
|
||||||
|
dimVal = Math.sqrt(perpOffset.x ** 2 + perpOffset.y ** 2)
|
||||||
dist = Math.sqrt(perpOffset.x ** 2 + perpOffset.y ** 2)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
dimVal = getAngle(selection)
|
||||||
|
}
|
||||||
|
////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
this.obj3d.children[1].add(line).add(point)
|
this.obj3d.children[1].add(line).add(point)
|
||||||
|
|
||||||
const onMove = this._onMoveDimension(point, line)
|
const onMove = this._onMoveDimension(point, line)
|
||||||
|
|
||||||
|
|
||||||
point.label = document.createElement('div');
|
point.label = document.createElement('div');
|
||||||
point.label.textContent = dist.toFixed(3);
|
point.label.textContent = dimVal.toFixed(3);
|
||||||
point.label.contentEditable = true;
|
point.label.contentEditable = true;
|
||||||
this.labelContainer.append(point.label)
|
this.labelContainer.append(point.label)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let onEnd, onKey;
|
let onEnd, onKey;
|
||||||
let add = await new Promise((res) => {
|
let add = await new Promise((res) => {
|
||||||
onEnd = (e) => res(true)
|
onEnd = (e) => {
|
||||||
|
if (cc == 'd') {
|
||||||
|
point.userData.offset = hyp2.toArray() // save offset vector from hyp2
|
||||||
|
} else {
|
||||||
|
point.userData.offset = vecArr[5].toArray()
|
||||||
|
}
|
||||||
|
res(true)
|
||||||
|
}
|
||||||
onKey = (e) => e.key == 'Escape' && res(false)
|
onKey = (e) => e.key == 'Escape' && res(false)
|
||||||
|
|
||||||
this.canvas.addEventListener('pointermove', onMove)
|
this.canvas.addEventListener('pointermove', onMove)
|
||||||
|
@ -102,21 +121,32 @@ export async function drawDimension() {
|
||||||
line.geometry.computeBoundingSphere()
|
line.geometry.computeBoundingSphere()
|
||||||
|
|
||||||
if (add) {
|
if (add) {
|
||||||
|
if (cc == 'd') {
|
||||||
if (ptLineOrder) {
|
if (ptLineOrder) {
|
||||||
this.constraints.set(++this.c_id, //???
|
this.constraints.set(++this.c_id, //???
|
||||||
[
|
[
|
||||||
'pt_line_distance', dist,
|
'pt_line_distance', dimVal,
|
||||||
[selection[ptLineOrder[0]].name, -1, selection[ptLineOrder[1]].name, -1]
|
[selection[ptLineOrder[0]].name, -1, selection[ptLineOrder[1]].name, -1]
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
this.constraints.set(++this.c_id, //???
|
this.constraints.set(++this.c_id, //???
|
||||||
[
|
[
|
||||||
'pt_pt_distance', dist,
|
'pt_pt_distance', dimVal,
|
||||||
[selection[0].name, selection[1].name, -1, -1]
|
[selection[0].name, selection[1].name, -1, -1]
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
this.constraints.set(++this.c_id,
|
||||||
|
[
|
||||||
|
'angle', dimVal,
|
||||||
|
[-1, -1, selection[0].name, selection[1].name]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
selection[0].userData.constraints.push(this.c_id)
|
selection[0].userData.constraints.push(this.c_id)
|
||||||
selection[1].userData.constraints.push(this.c_id)
|
selection[1].userData.constraints.push(this.c_id)
|
||||||
|
@ -129,11 +159,9 @@ export async function drawDimension() {
|
||||||
point.userData.type = 'dimension'
|
point.userData.type = 'dimension'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
point.label.addEventListener('focus', this.updateDim(this.c_id))
|
point.label.addEventListener('focus', this.updateDim(this.c_id))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
this.obj3d.children[1].children.splice(this.obj3d.children[1].length - 2, 2).forEach(
|
this.obj3d.children[1].children.splice(this.obj3d.children[1].length - 2, 2).forEach(
|
||||||
|
@ -196,16 +224,13 @@ export function _onMoveDimension(point, line) {
|
||||||
point.geometry.attributes.position,
|
point.geometry.attributes.position,
|
||||||
_p1, _p2
|
_p1, _p2
|
||||||
)
|
)
|
||||||
// console.log('heree')
|
|
||||||
console.trace()
|
|
||||||
|
|
||||||
point.userData.offset = hyp2.toArray() // save offset vector from hyp2
|
|
||||||
|
|
||||||
sc.render()
|
sc.render()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function setDimLines() {
|
export function setDimLines() {
|
||||||
|
|
||||||
const restoreLabels = this.labelContainer.childElementCount == 0;
|
const restoreLabels = this.labelContainer.childElementCount == 0;
|
||||||
|
@ -231,26 +256,29 @@ export function setDimLines() {
|
||||||
_p2 = this.obj3d.children[this.objIdx.get(ids[1])].geometry.attributes.position.array
|
_p2 = this.obj3d.children[this.objIdx.get(ids[1])].geometry.attributes.position.array
|
||||||
|
|
||||||
|
|
||||||
const offset = dims[i + 1].userData.offset
|
let offset = dims[i + 1].userData.offset
|
||||||
if (_p1.length < _p2.length) { // corner case when p1 is pt and p2 is line
|
|
||||||
p3.set(_p1[0] + offset[0], _p1[1] + offset[1])
|
|
||||||
} else {
|
|
||||||
p3.set(_p2[0] + offset[0], _p2[1] + offset[1])
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
update(
|
update(
|
||||||
dims[i].geometry.attributes.position,
|
dims[i].geometry.attributes.position,
|
||||||
dims[i + 1].geometry.attributes.position,
|
dims[i + 1].geometry.attributes.position,
|
||||||
_p1,
|
_p1,
|
||||||
_p2
|
_p2,
|
||||||
|
offset
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function onDimMoveEnd(point) {
|
||||||
|
if (hyp2) {
|
||||||
|
point.userData.offset = hyp2.toArray() // save offset vector from hyp2
|
||||||
|
} else {
|
||||||
|
point.userData.offset = vecArr[5].clone().sub(vecArr[2]).toArray()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const p1 = new THREE.Vector2()
|
const p1 = new THREE.Vector2()
|
||||||
let mdpt
|
let mdpt
|
||||||
const p1x = new THREE.Vector2()
|
const p1x = new THREE.Vector2()
|
||||||
|
@ -263,7 +291,16 @@ let p1eArr, p2eArr, p3Arr
|
||||||
let dir, linedir, perpOffset
|
let dir, linedir, perpOffset
|
||||||
let dp1e, dp2e, dp12
|
let dp1e, dp2e, dp12
|
||||||
|
|
||||||
function update(linegeom, pointgeom, _p1, _p2) {
|
function updatex(linegeom, pointgeom, _p1, _p2, offset) {
|
||||||
|
|
||||||
|
if (offset) {
|
||||||
|
if (_p1.length < _p2.length) { // corner case when p1 is pt and p2 is line
|
||||||
|
p3.set(_p1[0] + offset[0], _p1[1] + offset[1])
|
||||||
|
} else {
|
||||||
|
p3.set(_p2[0] + offset[0], _p2[1] + offset[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (_p1.length == _p2.length) {
|
if (_p1.length == _p2.length) {
|
||||||
p1.set(_p1[0], _p1[1])
|
p1.set(_p1[0], _p1[1])
|
||||||
|
@ -352,4 +389,271 @@ function update(linegeom, pointgeom, _p1, _p2) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const divisions = 12
|
||||||
|
export function findIntersection(q, s, p, r) {
|
||||||
|
/*
|
||||||
|
Based on: https://stackoverflow.com/questions/563198/
|
||||||
|
|
||||||
|
q+s p+r
|
||||||
|
\/__________ q+u*s
|
||||||
|
/\
|
||||||
|
/ \
|
||||||
|
p q
|
||||||
|
|
||||||
|
u = (q − p) × r / (r × s)
|
||||||
|
when r × s = 0, the lines are either colinear or parallel
|
||||||
|
|
||||||
|
function returns u
|
||||||
|
for "real" intersection to exist, 0<u<1
|
||||||
|
*/
|
||||||
|
const q_minus_p = q.clone().sub(p);
|
||||||
|
const r_cross_s = r.cross(s);
|
||||||
|
if (r_cross_s === 0) return null; //either colinear or parallel
|
||||||
|
return q_minus_p.cross(r) / r_cross_s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const vecArr = Array(6)
|
||||||
|
for (var i = 0; i < vecArr.length; i++) vecArr[i] = new THREE.Vector2();
|
||||||
|
const a = Array(3)
|
||||||
|
|
||||||
|
function update(linegeom, pointgeom, _l1, _l2, offset) {
|
||||||
|
|
||||||
|
let i = 0;
|
||||||
|
for (; i < 4;) {
|
||||||
|
const arr = i == 0 ? _l1 : _l2
|
||||||
|
vecArr[i++].set(arr[0], arr[1])
|
||||||
|
vecArr[i++].set(arr[3] - arr[0], arr[4] - arr[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
const centerScalar = findIntersection(...vecArr.slice(0, 4))
|
||||||
|
const center = vecArr[4].addVectors(vecArr[0], vecArr[1].clone().multiplyScalar(centerScalar))
|
||||||
|
|
||||||
|
if (offset) {
|
||||||
|
p3.set(center.x + offset[0], center.y + offset[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
vecArr[5].subVectors(p3, center)
|
||||||
|
|
||||||
|
const tagRadius = vecArr[5].length()
|
||||||
|
|
||||||
|
/*
|
||||||
|
if tag is more than 90 deg away from midline, we shift everything by 180
|
||||||
|
|
||||||
|
a: array that describes absolute angular position of angle start, angle end, and tag
|
||||||
|
|
||||||
|
a[2]:
|
||||||
|
tag a[1]:angle end
|
||||||
|
\ | /
|
||||||
|
\ | /
|
||||||
|
___\|/___ a[0]+dA/2:midline
|
||||||
|
/ \
|
||||||
|
/ \
|
||||||
|
/ \
|
||||||
|
a[0]:angle start
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (let j = 1, i = 0; j < vecArr.length; j += 2, i++) {
|
||||||
|
a[i] = Math.atan2(vecArr[j].y, vecArr[j].x)
|
||||||
|
}
|
||||||
|
|
||||||
|
let dA = unreflex(a[1] - a[0])
|
||||||
|
|
||||||
|
|
||||||
|
let tagtoMidline = unreflex(a[2] - (a[0] + dA / 2))
|
||||||
|
|
||||||
|
let shift = Math.abs(tagtoMidline) < Math.PI / 2 ? 0 : Math.PI;
|
||||||
|
|
||||||
|
let tA1 = unreflex(a[2] - (a[0] + shift))
|
||||||
|
let tA2 = unreflex(a[2] - (a[0] + dA + shift))
|
||||||
|
|
||||||
|
|
||||||
|
let a1, deltaAngle;
|
||||||
|
if (dA * tA1 < 0) {
|
||||||
|
a1 = a[0] + tA1 + shift
|
||||||
|
deltaAngle = dA - tA1
|
||||||
|
} else if (dA * tA2 > 0) {
|
||||||
|
a1 = a[0] + shift
|
||||||
|
deltaAngle = dA + tA2
|
||||||
|
} else {
|
||||||
|
a1 = a[0] + shift
|
||||||
|
deltaAngle = dA
|
||||||
|
}
|
||||||
|
|
||||||
|
let points = linegeom.array
|
||||||
|
|
||||||
|
let d = 0;
|
||||||
|
points[d++] = center.x + tagRadius * Math.cos(a1)
|
||||||
|
points[d++] = center.y + tagRadius * Math.sin(a1)
|
||||||
|
d++
|
||||||
|
|
||||||
|
const angle = a1 + (1 / divisions) * deltaAngle
|
||||||
|
points[d++] = center.x + tagRadius * Math.cos(angle)
|
||||||
|
points[d++] = center.y + tagRadius * Math.sin(angle)
|
||||||
|
d++
|
||||||
|
|
||||||
|
for (i = 2; i <= divisions; i++) {
|
||||||
|
points[d++] = points[d - 4]
|
||||||
|
points[d++] = points[d - 4]
|
||||||
|
d++
|
||||||
|
const angle = a1 + (i / divisions) * deltaAngle
|
||||||
|
points[d++] = center.x + tagRadius * Math.cos(angle)
|
||||||
|
points[d++] = center.y + tagRadius * Math.sin(angle)
|
||||||
|
d++
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
points[d++] = vecArr[2 * i].x
|
||||||
|
points[d++] = vecArr[2 * i].y
|
||||||
|
d++
|
||||||
|
points[d++] = center.x + tagRadius * Math.cos(a[i] + shift)
|
||||||
|
points[d++] = center.y + tagRadius * Math.sin(a[i] + shift)
|
||||||
|
d++
|
||||||
|
}
|
||||||
|
|
||||||
|
linegeom.needsUpdate = true;
|
||||||
|
|
||||||
|
pointgeom.array.set(p3.toArray())
|
||||||
|
pointgeom.needsUpdate = true;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const twoPi = Math.PI * 2
|
||||||
|
const negTwoPi = - Math.PI * 2
|
||||||
|
const negPi = - Math.PI
|
||||||
|
|
||||||
|
function unreflex(angle) {
|
||||||
|
if (angle > Math.PI) {
|
||||||
|
angle = negTwoPi + angle
|
||||||
|
} else if (angle < negPi) {
|
||||||
|
angle = twoPi + angle
|
||||||
|
}
|
||||||
|
return angle
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export async function drawAngle() {
|
||||||
|
/////////
|
||||||
|
let selection = await this.awaitSelection({ line: 2 })
|
||||||
|
//////////
|
||||||
|
|
||||||
|
if (selection == null) return;
|
||||||
|
|
||||||
|
const line = new THREE.LineSegments(
|
||||||
|
new THREE.BufferGeometry().setAttribute('position',
|
||||||
|
new THREE.Float32BufferAttribute(Array((divisions + 2) * 2 * 3).fill(-0.001), 3)
|
||||||
|
),
|
||||||
|
lineMaterial.clone()
|
||||||
|
);
|
||||||
|
|
||||||
|
const point = new THREE.Points(
|
||||||
|
new THREE.BufferGeometry().setAttribute('position',
|
||||||
|
new THREE.Float32BufferAttribute(3, 3)
|
||||||
|
),
|
||||||
|
pointMaterial.clone()
|
||||||
|
)
|
||||||
|
|
||||||
|
line.userData.ids = selection.map(e => e.name)
|
||||||
|
|
||||||
|
line.layers.enable(2)
|
||||||
|
point.layers.enable(2)
|
||||||
|
|
||||||
|
|
||||||
|
/////////////
|
||||||
|
let angle = getAngle(selection)
|
||||||
|
//////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
this.obj3d.children[1].add(line).add(point)
|
||||||
|
const onMove = this._onMoveDimension(point, line)
|
||||||
|
|
||||||
|
point.label = document.createElement('div');
|
||||||
|
point.label.textContent = angle.toFixed(3);
|
||||||
|
point.label.contentEditable = true;
|
||||||
|
this.labelContainer.append(point.label)
|
||||||
|
|
||||||
|
let onEnd, onKey;
|
||||||
|
let add = await new Promise((res) => {
|
||||||
|
onEnd = (e) => {
|
||||||
|
point.userData.offset = vecArr[5].toArray()
|
||||||
|
res(true)
|
||||||
|
}
|
||||||
|
onKey = (e) => e.key == 'Escape' && res(false)
|
||||||
|
|
||||||
|
this.canvas.addEventListener('pointermove', onMove)
|
||||||
|
this.canvas.addEventListener('pointerdown', onEnd)
|
||||||
|
window.addEventListener('keydown', onKey)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.canvas.removeEventListener('pointermove', onMove)
|
||||||
|
this.canvas.removeEventListener('pointerdown', onEnd)
|
||||||
|
window.removeEventListener('keydown', onKey)
|
||||||
|
point.geometry.computeBoundingSphere()
|
||||||
|
line.geometry.computeBoundingSphere()
|
||||||
|
|
||||||
|
if (add) {
|
||||||
|
|
||||||
|
this.constraints.set(++this.c_id,
|
||||||
|
[
|
||||||
|
'angle', angle,
|
||||||
|
[-1, -1, selection[0].name, selection[1].name]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
selection[0].userData.constraints.push(this.c_id)
|
||||||
|
selection[1].userData.constraints.push(this.c_id)
|
||||||
|
|
||||||
|
this.updateOtherBuffers()
|
||||||
|
|
||||||
|
line.name = this.c_id
|
||||||
|
line.userData.type = 'dimension'
|
||||||
|
point.name = this.c_id
|
||||||
|
point.userData.type = 'dimension'
|
||||||
|
|
||||||
|
point.label.addEventListener('focus', this.updateAng(this.c_id))
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
this.obj3d.children[1].children.splice(this.obj3d.children[1].length - 2, 2).forEach(
|
||||||
|
e => {
|
||||||
|
e.geometry.dispose()
|
||||||
|
e.material.dispose()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
this.labelContainer.removeChild(this.labelContainer.lastChild);
|
||||||
|
sc.render()
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const getAngle = (Obj3dLines) => {
|
||||||
|
for (let i = 0; i < 2; i++) {
|
||||||
|
const arr = Obj3dLines[i].geometry.attributes.position.array
|
||||||
|
vecArr[2 * i].set(...arr.slice(0, 2))
|
||||||
|
vecArr[2 * i + 1].set(arr[3] - arr[0], arr[4] - arr[1])
|
||||||
|
}
|
||||||
|
const a1 = Math.atan2(vecArr[1].y, vecArr[1].x)
|
||||||
|
const a2 = Math.atan2(vecArr[3].y, vecArr[3].x)
|
||||||
|
|
||||||
|
let deltaAngle = Math.abs(a2 - a1)
|
||||||
|
if (deltaAngle > Math.PI) {
|
||||||
|
deltaAngle = Math.PI * 2 - deltaAngle
|
||||||
|
}
|
||||||
|
return deltaAngle / Math.PI * 180
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
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';
|
||||||
|
import { onDimMoveEnd } from './drawDimension'
|
||||||
|
|
||||||
let ptLoc
|
let ptLoc
|
||||||
|
|
||||||
|
@ -156,8 +156,15 @@ export function onPick(e) {
|
||||||
this.obj3d.children[1].children[idx],
|
this.obj3d.children[1].children[idx],
|
||||||
this.obj3d.children[1].children[idx - 1],
|
this.obj3d.children[1].children[idx - 1],
|
||||||
)
|
)
|
||||||
|
// this.onDragDim = this._onMoveAng(
|
||||||
|
// this.obj3d.children[1].children[idx],
|
||||||
|
// this.obj3d.children[1].children[idx - 1],
|
||||||
|
// )
|
||||||
this.canvas.addEventListener('pointermove', this.onDragDim);
|
this.canvas.addEventListener('pointermove', this.onDragDim);
|
||||||
this.canvas.addEventListener('pointerup', this.onRelease)
|
this.canvas.addEventListener('pointerup', () => {
|
||||||
|
onDimMoveEnd(this.obj3d.children[1].children[idx])
|
||||||
|
this.onRelease()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
draggedLabel = this.obj3d.children[1].children[idx].label
|
draggedLabel = this.obj3d.children[1].children[idx].label
|
||||||
|
@ -196,7 +203,6 @@ export function onDrag(e) {
|
||||||
// this.objIdx.get(obj.name) * 3
|
// this.objIdx.get(obj.name) * 3
|
||||||
// )
|
// )
|
||||||
|
|
||||||
|
|
||||||
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]
|
||||||
this.ptsBuf.set(
|
this.ptsBuf.set(
|
||||||
|
@ -206,7 +212,7 @@ export function onDrag(e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.solve()
|
this.solve()
|
||||||
// this.obj3d.dispatchEvent({ type: 'change' })
|
this.scene.render()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue