three.cad/src/sketcher/drawDimension.js

242 lines
5.6 KiB
JavaScript
Raw Normal View History

2021-04-03 03:33:09 +08:00
import * as THREE from '../../node_modules/three/src/Three';
2021-04-05 11:52:17 +08:00
import { color } from '../utils/shared'
2021-04-03 12:05:28 +08:00
const lineMaterial = new THREE.LineBasicMaterial({
linewidth: 2,
2021-04-05 11:52:17 +08:00
color: color.dimension,
2021-04-03 12:05:28 +08:00
})
const pointMaterial = new THREE.PointsMaterial({
2021-04-05 11:52:17 +08:00
color: color.dimension,
2021-04-03 12:05:28 +08:00
size: 4,
})
2021-04-04 08:59:14 +08:00
export async function drawDimension() {
2021-04-05 11:52:17 +08:00
let pts = await this.awaitPts({ point: 2 })
2021-04-03 03:33:09 +08:00
2021-04-04 17:36:41 +08:00
if (pts == null) return;
2021-04-03 03:33:09 +08:00
2021-04-04 08:59:14 +08:00
const line = new THREE.LineSegments(
new THREE.BufferGeometry().setAttribute('position',
2021-04-04 10:08:19 +08:00
new THREE.Float32BufferAttribute(3 * 8, 3)
2021-04-04 08:59:14 +08:00
),
lineMaterial.clone()
);
const point = new THREE.Points(
new THREE.BufferGeometry().setAttribute('position',
2021-04-04 10:08:19 +08:00
new THREE.Float32BufferAttribute(3, 3)
2021-04-04 08:59:14 +08:00
),
pointMaterial.clone()
2021-04-03 03:33:09 +08:00
)
2021-04-04 17:36:41 +08:00
line.userData.nids = pts.map(e => e.name)
2021-04-04 10:08:19 +08:00
2021-04-05 11:52:17 +08:00
2021-04-05 16:05:53 +08:00
let dist = 0
for (let i = 0; i < 3; i++) {
dist += (pts[0].geometry.attributes.position.array[i] - pts[1].geometry.attributes.position.array[i]) ** 2
}
dist = Math.sqrt(dist)
this.obj3d.children[1].add(line).add(point)
2021-04-04 10:08:19 +08:00
2021-04-05 11:52:17 +08:00
const onMove = this._onMoveDimension(point, line)
point.label = document.createElement('div');
2021-04-05 16:05:53 +08:00
point.label.textContent = dist.toFixed(3);
point.label.contentEditable = true;
2021-04-05 11:52:17 +08:00
this.labelContainer.append(point.label)
2021-04-03 03:33:09 +08:00
2021-04-03 12:05:28 +08:00
2021-04-05 11:52:17 +08:00
let onEnd, onKey;
2021-04-04 10:08:19 +08:00
let add = await new Promise((res) => {
2021-04-04 12:54:27 +08:00
onEnd = (e) => res(true)
onKey = (e) => e.key == 'Escape' && res(false)
2021-04-04 08:59:14 +08:00
this.canvas.addEventListener('pointermove', onMove)
this.canvas.addEventListener('pointerdown', onEnd)
window.addEventListener('keydown', onKey)
})
2021-04-03 03:33:09 +08:00
2021-04-04 08:59:14 +08:00
this.canvas.removeEventListener('pointermove', onMove)
this.canvas.removeEventListener('pointerdown', onEnd)
2021-04-04 12:54:27 +08:00
window.removeEventListener('keydown', onKey)
2021-04-05 11:52:17 +08:00
point.geometry.computeBoundingSphere()
line.geometry.computeBoundingSphere()
2021-04-04 10:08:19 +08:00
if (add) {
this.constraints.set(++this.c_id, //???
[
2021-04-05 16:05:53 +08:00
'pt_pt_distance', dist,
2021-04-04 10:08:19 +08:00
[pts[0].name, pts[1].name, -1, -1]
]
)
pts[0].userData.constraints.push(this.c_id)
pts[1].userData.constraints.push(this.c_id)
2021-04-04 12:54:27 +08:00
2021-04-04 10:08:19 +08:00
this.updateOtherBuffers()
line.name = this.c_id
2021-04-05 11:52:17 +08:00
line.userData.type = 'dimension'
2021-04-04 10:08:19 +08:00
point.name = this.c_id
2021-04-05 11:52:17 +08:00
point.userData.type = 'dimension'
2021-04-05 16:05:53 +08:00
2021-04-06 12:52:19 +08:00
point.label.addEventListener('focus', this.updateDim(this.c_id))
2021-04-05 16:05:53 +08:00
2021-04-04 10:08:19 +08:00
} else {
2021-04-05 16:05:53 +08:00
this.obj3d.children[1].children.splice(this.obj3d.children[1].length - 2, 2).forEach(
2021-04-04 10:08:19 +08:00
e => {
e.geometry.dispose()
e.material.dispose()
}
)
2021-04-05 16:05:53 +08:00
this.labelContainer.removeChild(this.labelContainer.lastChild);
2021-04-04 10:08:19 +08:00
sc.render()
}
2021-04-03 03:33:09 +08:00
2021-04-03 12:05:28 +08:00
return
2021-04-03 03:33:09 +08:00
}
2021-04-05 11:52:17 +08:00
const p1 = new THREE.Vector2()
const p2 = new THREE.Vector2()
const p3 = new THREE.Vector2()
2021-04-05 16:05:53 +08:00
let dir, hyp, proj, perp, p1e, p2e, nids, _p1, _p2;
2021-04-04 12:54:27 +08:00
2021-04-06 12:52:19 +08:00
export function updateDim(c_id) {
return (ev_focus) => {
const value = ev_focus.target.textContent
document.addEventListener('keydown', (e) => {
if (e.key == 'Enter') {
e.preventDefault()
const ent = this.constraints.get(c_id)
ent[1] = parseFloat(ev_focus.target.textContent)
this.constraints.set(c_id, ent)
this.updateOtherBuffers()
this.solve()
sc.render()
ev_focus.target.blur()
this.updateBoundingSpheres()
} else if (e.key == 'Escape') {
ev_focus.target.textContent = value
getSelection().empty()
ev_focus.target.blur()
}
})
}
}
2021-04-05 11:52:17 +08:00
export function _onMoveDimension(point, line) {
2021-04-04 12:54:27 +08:00
2021-04-05 11:52:17 +08:00
nids = line.userData.nids
2021-04-04 17:36:41 +08:00
2021-04-06 12:52:19 +08:00
_p1 = this.obj3d.children[this.objIdx.get(nids[0])].geometry.attributes.position.array
_p2 = this.obj3d.children[this.objIdx.get(nids[1])].geometry.attributes.position.array
2021-04-05 11:52:17 +08:00
p1.set(_p1[0], _p1[1])
p2.set(_p2[0], _p2[1])
let loc;
2021-04-04 12:54:27 +08:00
return (e) => {
loc = this.getLocation(e)
2021-04-04 17:36:41 +08:00
2021-04-04 12:54:27 +08:00
p3.set(loc.x, loc.y)
2021-04-05 11:52:17 +08:00
update(
line.geometry.attributes.position,
point.geometry.attributes.position
)
2021-04-04 17:36:41 +08:00
point.userData.offset = hyp.toArray()
2021-04-04 12:54:27 +08:00
sc.render()
}
2021-04-04 17:36:41 +08:00
}
2021-04-05 16:05:53 +08:00
export function setDimLines() {
const restoreLabels = this.labelContainer.childElementCount == 0;
const dims = this.obj3d.children[1].children
2021-04-04 17:36:41 +08:00
2021-04-05 16:05:53 +08:00
let point, dist;
for (let i = 0; i < dims.length; i += 2) {
2021-04-04 17:36:41 +08:00
2021-04-05 16:05:53 +08:00
if (restoreLabels) {
point = dims[i + 1] // point node is at i+1
dist = this.constraints.get(point.name)[1]
point.label = document.createElement('div');
point.label.textContent = dist.toFixed(3);
point.label.contentEditable = true;
this.labelContainer.append(point.label)
2021-04-06 12:52:19 +08:00
point.label.addEventListener('focus', this.updateDim(this.c_id))
2021-04-05 16:05:53 +08:00
}
nids = dims[i].userData.nids
2021-04-04 17:36:41 +08:00
2021-04-06 12:52:19 +08:00
_p1 = this.obj3d.children[this.objIdx.get(nids[0])].geometry.attributes.position.array
_p2 = this.obj3d.children[this.objIdx.get(nids[1])].geometry.attributes.position.array
2021-04-05 16:05:53 +08:00
const offset = dims[i + 1].userData.offset
2021-04-04 17:36:41 +08:00
p1.set(_p1[0], _p1[1])
p2.set(_p2[0], _p2[1])
p3.set(_p1[0] + offset[0], _p1[1] + offset[1])
2021-04-05 11:52:17 +08:00
update(
2021-04-05 16:05:53 +08:00
dims[i].geometry.attributes.position,
dims[i + 1].geometry.attributes.position
2021-04-05 11:52:17 +08:00
)
}
2021-04-04 17:36:41 +08:00
2021-04-05 11:52:17 +08:00
}
2021-04-04 17:36:41 +08:00
2021-04-05 11:52:17 +08:00
function update(linegeom, pointgeom) {
dir = p2.clone().sub(p1).normalize()
hyp = p3.clone().sub(p1)
proj = dir.multiplyScalar(hyp.dot(dir))
perp = hyp.clone().sub(proj)
2021-04-04 17:36:41 +08:00
2021-04-05 11:52:17 +08:00
p1e = p1.clone().add(perp).toArray()
p2e = p2.clone().add(perp).toArray()
2021-04-04 17:36:41 +08:00
2021-04-05 11:52:17 +08:00
linegeom.array.set(p1.toArray(), 0)
linegeom.array.set(p1e, 3)
2021-04-04 17:36:41 +08:00
2021-04-05 11:52:17 +08:00
linegeom.array.set(p1e, 6)
linegeom.array.set(p2e, 9)
2021-04-04 17:36:41 +08:00
2021-04-05 11:52:17 +08:00
linegeom.array.set(p2e, 12)
linegeom.array.set(p2.toArray(), 15)
2021-04-04 17:36:41 +08:00
2021-04-05 11:52:17 +08:00
linegeom.array.set(p1e, 18)
linegeom.array.set(p3.toArray(), 21)
2021-04-04 17:36:41 +08:00
2021-04-05 11:52:17 +08:00
linegeom.needsUpdate = true;
2021-04-04 17:36:41 +08:00
2021-04-05 11:52:17 +08:00
pointgeom.array.set(p3.toArray())
pointgeom.needsUpdate = true;
2021-04-05 16:05:53 +08:00
}