add ordinate dimension and fix tangent
This commit is contained in:
parent
fec6a75aeb
commit
6ef53e5a7c
1
demo_parts/cable-clip.json
Normal file
1
demo_parts/cable-clip.json
Normal file
@ -0,0 +1 @@
|
||||
[0,1,1,{"byId":{},"allIds":[],"tree":{},"order":{},"visible":{}}]
|
1
demo_parts/headphone-stand (copy).json
Normal file
1
demo_parts/headphone-stand (copy).json
Normal file
File diff suppressed because one or more lines are too long
1
demo_parts/headphone-stand.json
Normal file
1
demo_parts/headphone-stand.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,10 +0,0 @@
|
||||
const { merge } = require('webpack-merge');
|
||||
|
||||
const common = require('./webpack.common.js');
|
||||
|
||||
|
||||
module.exports = merge(common, {
|
||||
|
||||
mode: 'production',
|
||||
|
||||
});
|
BIN
dist/solver.wasm
vendored
BIN
dist/solver.wasm
vendored
Binary file not shown.
@ -25,7 +25,7 @@ var TrackballControls = function ( object, domElement ) {
|
||||
|
||||
this.rotateSpeed = 3.0;
|
||||
this.zoomSpeed = 1.2;
|
||||
this.panSpeed = 41.6;
|
||||
this.panSpeed = 2;
|
||||
|
||||
this.noRotate = false;
|
||||
this.noZoom = false;
|
||||
|
12
src/Scene.js
12
src/Scene.js
@ -44,11 +44,11 @@ export class Scene {
|
||||
this.store = store
|
||||
|
||||
const size = 1;
|
||||
const near = 0;
|
||||
const far = 100;
|
||||
const near = -1;
|
||||
const far = 1000;
|
||||
this.camera = new THREE.OrthographicCamera(-size, size, size, -size, near, far);
|
||||
this.camera.zoom = 0.1;
|
||||
const cameraDist = 50
|
||||
this.camera.zoom = 0.008;
|
||||
const cameraDist = 500
|
||||
const xzAngle = 30 * Math.PI / 180
|
||||
this.camera.position.set(
|
||||
cameraDist * Math.sin(xzAngle),
|
||||
@ -94,7 +94,7 @@ export class Scene {
|
||||
this.fptObj = {}
|
||||
|
||||
|
||||
const planeGeom = new THREE.PlaneGeometry(5, 5)
|
||||
const planeGeom = new THREE.PlaneGeometry(50, 50)
|
||||
const pxy = new THREE.Mesh(
|
||||
planeGeom,
|
||||
new THREE.MeshBasicMaterial({
|
||||
@ -128,7 +128,7 @@ export class Scene {
|
||||
helpersGroup.add(this.axes);
|
||||
|
||||
|
||||
const dist = 15
|
||||
const dist = 500
|
||||
const light1 = new THREE.PointLight(color.lighting, 0.7);
|
||||
light1.position.set(dist, dist, dist);
|
||||
helpersGroup.add(light1);
|
||||
|
@ -24,8 +24,8 @@ class Sketch {
|
||||
// [0]:type, [1]:pt1, [2]:pt2, [3]:pt3, [4]:pt4
|
||||
this.linksBuf = new Float32Array(this.max_links * 5).fill(NaN)
|
||||
|
||||
// [0]:type, [1]:val, [2]:pt1, [3]:pt2, [4]:lk1, [5]:lk2
|
||||
this.constraintsBuf = new Float32Array(this.max_constraints * 6).fill(NaN)
|
||||
// [0]:type, [1]:val, [2]:pt1, [3]:pt2, [4]:lk1, [5]:lk2, [6]: other, [7]: other
|
||||
this.constraintsBuf = new Float32Array(this.max_constraints * 8).fill(NaN)
|
||||
|
||||
|
||||
this.plane = new THREE.Plane(new THREE.Vector3(0, 0, 1), 0);
|
||||
@ -401,9 +401,9 @@ class Sketch {
|
||||
this.constraintsBuf.set(
|
||||
[
|
||||
this.constraintNum[obj[0]], obj[1],
|
||||
...obj[2].map(ele => this.objIdx.get(ele) ?? 0),
|
||||
...obj[2].map(ele => this.objIdx.get(ele) ?? 0), obj[3], obj[4]
|
||||
],
|
||||
(i) * 6
|
||||
(i) * 8
|
||||
)
|
||||
i++
|
||||
}
|
||||
@ -587,6 +587,8 @@ Object.assign(Sketch.prototype,
|
||||
where_dragged: 31,
|
||||
curve_curve_tangent: 32,
|
||||
length_difference: 33,
|
||||
h_dist: 34,
|
||||
v_dist: 35,
|
||||
},
|
||||
max_pts: 1000,
|
||||
max_links: 1000,
|
||||
|
@ -9,9 +9,9 @@ class AxesHelper extends THREE.Object3D {
|
||||
super()
|
||||
this.matrixAutoUpdate = false
|
||||
this.initialZoom = initialZoom
|
||||
this.length = [0.55, 1]
|
||||
this.headLength = 0.25
|
||||
this.headWidth = 0.12
|
||||
this.length = [5.5, 10]
|
||||
this.headLength = 2.5
|
||||
this.headWidth = 1.2
|
||||
|
||||
this.dirs = [
|
||||
[1, 0, 0],
|
||||
|
@ -81,24 +81,66 @@ export async function setTangent() {
|
||||
let selection = await this.awaitSelection({ line: 2 })
|
||||
if (selection == null) return;
|
||||
|
||||
let idx = -1
|
||||
const res = {} // this helps us find the relavant coincident constraint connecting the 2 entities
|
||||
let idx = -1 // -1: both are arcs, 0: selection[0] is line, 1 selection[1] is line
|
||||
const others = [] // length 2 arr of the other flag
|
||||
let type, arr
|
||||
|
||||
/**
|
||||
* a this.constraints entry:
|
||||
* [0]: constraint type
|
||||
* [1]: float value, -1 if not needed
|
||||
* [2]: [pointA, pointB, entityA, entityB]
|
||||
* [3]: other
|
||||
* [4]: other2
|
||||
*
|
||||
* a this.linkedObjs entry:
|
||||
* [0]: type: arc or line
|
||||
* [1]: [point1_id, point2_id, line_id]
|
||||
*/
|
||||
|
||||
for (let i = 0; i < 2; i++) {
|
||||
if (selection[i].userData.ccw == undefined) {
|
||||
if (selection[i].userData.ccw == undefined) { // quick dirty way to check if entity is a arc
|
||||
idx = i
|
||||
break
|
||||
}
|
||||
const l_id = selection[i].userData.l_id
|
||||
const ids = this.linkedObjs.get(l_id)[1]
|
||||
for (let j = 0; j < 2; j++) {
|
||||
const constraintsArr = this.obj3d.children[this.objIdx.get(ids[j])].userData.constraints
|
||||
for (let k = 0; k < constraintsArr.length; k++) {
|
||||
const constraint = this.constraints.get(constraintsArr[k])
|
||||
if (constraint[0] == 'points_coincident') {
|
||||
if (res[constraintsArr[k]]) { // if we've seen this constraint already, it means its the relevant constraint
|
||||
for (let m = 0; m < 2; m++) {
|
||||
others[m] = this.obj3d.children[this.objIdx.get(constraint[2][m])].userData.start ? 0 : 1
|
||||
}
|
||||
|
||||
arr = idx == 0 ?
|
||||
[-1, -1, selection[1].name, selection[0].name] :
|
||||
[-1, -1, selection[0].name, selection[1].name];
|
||||
type = idx == -1 ? 'curve_curve_tangent' : 'arc_line_tangent'
|
||||
|
||||
if (
|
||||
(ids.includes(constraint[2][1]) && idx == 0) ||
|
||||
(!ids.includes(constraint[2][1]) && idx != 0)
|
||||
) { // if selection[1] includes the first entitity
|
||||
let temp = others[0]
|
||||
others[0] = others[1]
|
||||
others[1] = temp
|
||||
}
|
||||
break
|
||||
} else {
|
||||
res[constraintsArr[k]] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let arr = idx == 0 ?
|
||||
[-1, -1, selection[1].name, selection[0].name] :
|
||||
[-1, -1, selection[0].name, selection[1].name];
|
||||
|
||||
let type = idx == -1 ? 'curve_curve_tangent' : 'arc_line_tangent'
|
||||
|
||||
this.constraints.set(++this.c_id,
|
||||
[
|
||||
type, -1,
|
||||
arr
|
||||
arr, others[0], others[1]
|
||||
]
|
||||
)
|
||||
selection.forEach(element => {
|
||||
|
@ -106,12 +106,16 @@ export function drawArc4(mouseLoc, toPush) {
|
||||
p2.geometry.attributes.position.array,
|
||||
p3.geometry.attributes.position.array
|
||||
)
|
||||
p1.userData.start = true
|
||||
p2.userData.start = false
|
||||
} else {
|
||||
points = get3PtArc(
|
||||
p2.geometry.attributes.position.array,
|
||||
p1.geometry.attributes.position.array,
|
||||
p3.geometry.attributes.position.array
|
||||
)
|
||||
p2.userData.start = true
|
||||
p1.userData.start = false
|
||||
}
|
||||
|
||||
arc.geometry.attributes.position.set(
|
||||
|
@ -12,12 +12,12 @@ const pointMaterial = new THREE.PointsMaterial({
|
||||
size: 4,
|
||||
})
|
||||
|
||||
|
||||
let dimVal
|
||||
export async function drawDimension() {
|
||||
let selection = await this.awaitSelection({ point: 2 }, { point: 1, line: 1 }, { line: 2 })
|
||||
if (selection == null) return;
|
||||
|
||||
let line, dimVal, constraint, dimType
|
||||
let line, constraint, dimType
|
||||
if (selection.every(e => e.userData.type == 'line')) {
|
||||
line = new THREE.LineSegments(
|
||||
new THREE.BufferGeometry().setAttribute('position',
|
||||
@ -49,6 +49,13 @@ export async function drawDimension() {
|
||||
dimVal += (selection[0].geometry.attributes.position.array[i] - selection[1].geometry.attributes.position.array[i]) ** 2
|
||||
}
|
||||
dimVal = Math.sqrt(dimVal)
|
||||
|
||||
constraint = [
|
||||
'pt_pt_distance', dimVal,
|
||||
// 'smart_dist', dimVal,
|
||||
[selection[0].name, selection[1].name, -1, -1]
|
||||
]
|
||||
|
||||
} else {
|
||||
ptLineOrder = selection[0].userData.type == 'point' ? [0, 1] : [1, 0]
|
||||
const ptArr = selection[ptLineOrder[0]].geometry.attributes.position.array
|
||||
@ -61,19 +68,14 @@ export async function drawDimension() {
|
||||
proj = dir.multiplyScalar(disp.dot(dir))
|
||||
perpOffset = disp.clone().sub(proj)
|
||||
dimVal = Math.sqrt(perpOffset.x ** 2 + perpOffset.y ** 2)
|
||||
}
|
||||
if (ptLineOrder) {
|
||||
|
||||
constraint = [
|
||||
'pt_line_distance', dimVal,
|
||||
[selection[ptLineOrder[0]].name, -1, selection[ptLineOrder[1]].name, -1]
|
||||
]
|
||||
} else {
|
||||
constraint = [
|
||||
'pt_pt_distance', dimVal,
|
||||
[selection[0].name, selection[1].name, -1, -1]
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
dimType = 'd'
|
||||
}
|
||||
|
||||
@ -93,7 +95,7 @@ export async function drawDimension() {
|
||||
point.layers.enable(2)
|
||||
|
||||
this.dimGroup.add(line).add(point)
|
||||
const onMove = this._onMoveDimension(point, line)
|
||||
const onMove = this._onMoveDimension(point, line, true)
|
||||
point.label = document.createElement('div');
|
||||
point.label.textContent = dimVal.toFixed(3);
|
||||
point.label.contentEditable = true;
|
||||
@ -102,10 +104,10 @@ export async function drawDimension() {
|
||||
let onEnd, onKey;
|
||||
let add = await new Promise((res) => {
|
||||
onEnd = () => {
|
||||
if (point.userData.dimType == 'd') {
|
||||
point.userData.offset = hyp2.toArray() // save offset vector from hyp2
|
||||
} else {
|
||||
if (point.userData.dimType == 'a') {
|
||||
point.userData.offset = vecArr[5].toArray()
|
||||
} else {
|
||||
point.userData.offset = hyp2.toArray() // save offset vector from hyp2
|
||||
}
|
||||
res(true)
|
||||
}
|
||||
@ -124,6 +126,17 @@ export async function drawDimension() {
|
||||
|
||||
if (add) {
|
||||
|
||||
|
||||
|
||||
if (line.userData.dimType == 'h') {
|
||||
constraint[0] = 'h_dist'
|
||||
constraint[1] = p2.x - p1.x
|
||||
} else if (line.userData.dimType == 'v') {
|
||||
constraint[0] = 'v_dist'
|
||||
constraint[1] = p2.y - p1.y
|
||||
}
|
||||
|
||||
|
||||
this.constraints.set(++this.c_id, constraint)
|
||||
|
||||
selection[0].userData.constraints.push(this.c_id)
|
||||
@ -147,7 +160,7 @@ export async function drawDimension() {
|
||||
this.labelContainer.removeChild(this.labelContainer.lastChild);
|
||||
sc.render()
|
||||
}
|
||||
if (this.mode=="dimension") {
|
||||
if (this.mode == "dimension") {
|
||||
this.drawDimension()
|
||||
}
|
||||
|
||||
@ -181,7 +194,7 @@ export function updateDim(c_id) {
|
||||
|
||||
const tagPos = new THREE.Vector2()
|
||||
let ids
|
||||
export function _onMoveDimension(point, line) {
|
||||
export function _onMoveDimension(point, line, initial) {
|
||||
|
||||
ids = line.userData.ids
|
||||
|
||||
@ -191,10 +204,10 @@ export function _onMoveDimension(point, line) {
|
||||
let loc;
|
||||
|
||||
let update;
|
||||
if (line.userData.dimType == 'd') {
|
||||
update = updateDistance
|
||||
} else {
|
||||
if (line.userData.dimType == 'a') {
|
||||
update = updateAngle
|
||||
} else {
|
||||
update = updateDistance
|
||||
}
|
||||
|
||||
return (e) => {
|
||||
@ -203,9 +216,9 @@ export function _onMoveDimension(point, line) {
|
||||
tagPos.set(loc.x, loc.y)
|
||||
|
||||
update(
|
||||
line.geometry.attributes.position,
|
||||
point.geometry.attributes.position,
|
||||
_p1, _p2
|
||||
line,
|
||||
point,
|
||||
_p1, _p2, null, initial
|
||||
)
|
||||
sc.render()
|
||||
}
|
||||
@ -214,7 +227,7 @@ export function _onMoveDimension(point, line) {
|
||||
export function setDimLines() {
|
||||
const restoreLabels = this.labelContainer.childElementCount == 0;
|
||||
const dims = this.dimGroup.children
|
||||
let point, dist;
|
||||
let point, dist
|
||||
for (let i = 0; i < dims.length; i += 2) {
|
||||
if (restoreLabels) {
|
||||
point = dims[i + 1] // point node is at i+1
|
||||
@ -232,15 +245,17 @@ export function setDimLines() {
|
||||
let _p2 = this.obj3d.children[this.objIdx.get(ids[1])].geometry.attributes.position.array
|
||||
|
||||
let update;
|
||||
if (dims[i].userData.dimType == 'd') {
|
||||
update = updateDistance
|
||||
} else {
|
||||
if (dims[i].userData.dimType == 'a') {
|
||||
update = updateAngle
|
||||
} else {
|
||||
update = updateDistance
|
||||
}
|
||||
|
||||
update(
|
||||
dims[i].geometry.attributes.position,
|
||||
dims[i + 1].geometry.attributes.position,
|
||||
// dims[i].geometry.attributes.position,
|
||||
// dims[i + 1].geometry.attributes.position,
|
||||
dims[i],
|
||||
dims[i + 1],
|
||||
_p1,
|
||||
_p2,
|
||||
dims[i + 1].userData.offset
|
||||
@ -262,7 +277,11 @@ let p1eArr, p2eArr, tagPosArr
|
||||
let dir, linedir, perpOffset
|
||||
let dp1e, dp2e, dp12
|
||||
|
||||
function updateDistance(linegeom, pointgeom, _p1, _p2, offset) {
|
||||
function updateDistance(line, point, _p1, _p2, offset, initial) {
|
||||
|
||||
const linegeom = line.geometry.attributes.position
|
||||
const pointgeom = point.geometry.attributes.position
|
||||
|
||||
if (offset) {
|
||||
if (_p1.length < _p2.length) { // corner case when p1 is pt and p2 is line
|
||||
tagPos.set(_p1[0] + offset[0], _p1[1] + offset[1])
|
||||
@ -271,29 +290,72 @@ function updateDistance(linegeom, pointgeom, _p1, _p2, offset) {
|
||||
}
|
||||
}
|
||||
|
||||
let phantom = null
|
||||
if (_p1.length == _p2.length) {
|
||||
p1.set(_p1[0], _p1[1])
|
||||
p2.set(_p2[0], _p2[1])
|
||||
|
||||
dir = p2.clone().sub(p1).normalize()
|
||||
hyp2 = tagPos.clone().sub(p2) // note that this value is used to calculate tag-p2 offset
|
||||
proj = dir.multiplyScalar(hyp2.dot(dir))
|
||||
perpOffset = hyp2.clone().sub(proj)
|
||||
if (initial) {
|
||||
if (
|
||||
(tagPos.x - p1.x) * (tagPos.x - p2.x) > 0 &&
|
||||
(tagPos.y - p1.y) * (tagPos.y - p2.y) < 0
|
||||
) {
|
||||
line.userData.dimType = 'v'
|
||||
point.userData.dimType = 'v'
|
||||
// point.label.textContent = Math.abs(p1.y - p2.y).toFixed(3);
|
||||
point.label.textContent = (p2.y - p1.y).toFixed(3);
|
||||
} else if (
|
||||
(tagPos.x - p1.x) * (tagPos.x - p2.x) < 0 &&
|
||||
(tagPos.y - p1.y) * (tagPos.y - p2.y) > 0
|
||||
) {
|
||||
line.userData.dimType = 'h'
|
||||
point.userData.dimType = 'h'
|
||||
// point.label.textContent = Math.abs(p1.x - p2.x).toFixed(3);
|
||||
point.label.textContent = (p2.x - p1.x).toFixed(3);
|
||||
} else {
|
||||
line.userData.dimType = 'd'
|
||||
point.userData.dimType = 'd'
|
||||
point.label.textContent = dimVal.toFixed(3);
|
||||
}
|
||||
}
|
||||
|
||||
p1e = p1.clone().add(perpOffset)
|
||||
p1eArr = p1e.toArray()
|
||||
p2e = p2.clone().add(perpOffset)
|
||||
p2eArr = p2e.toArray()
|
||||
tagPosArr = tagPos.toArray()
|
||||
|
||||
dp1e = p1e.distanceToSquared(tagPos)
|
||||
dp2e = p2e.distanceToSquared(tagPos)
|
||||
dp12 = p1e.distanceToSquared(p2e)
|
||||
switch (line.userData.dimType) {
|
||||
case 'v':
|
||||
phantom = [_p1[0] + 1, _p1[1]]
|
||||
break;
|
||||
case 'h':
|
||||
phantom = [_p1[0], _p1[1] + 1]
|
||||
break;
|
||||
default:
|
||||
dir = p2.clone().sub(p1).normalize()
|
||||
hyp2 = tagPos.clone().sub(p2) // note that this value is used to calculate tag-p2 offset
|
||||
proj = dir.multiplyScalar(hyp2.dot(dir))
|
||||
perpOffset = hyp2.clone().sub(proj)
|
||||
|
||||
linegeom.array.set(p1.toArray(), 0)
|
||||
p1e = p1.clone().add(perpOffset)
|
||||
p1eArr = p1e.toArray()
|
||||
p2e = p2.clone().add(perpOffset)
|
||||
p2eArr = p2e.toArray()
|
||||
tagPosArr = tagPos.toArray()
|
||||
|
||||
} else {
|
||||
if (_p1.length > _p2.length) { // when p1 is line, p2 is point
|
||||
dp1e = p1e.distanceToSquared(tagPos)
|
||||
dp2e = p2e.distanceToSquared(tagPos)
|
||||
dp12 = p1e.distanceToSquared(p2e)
|
||||
linegeom.array.set(p1.toArray(), 0)
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (_p1.length != _p2.length || phantom) {
|
||||
if (phantom) {
|
||||
p1.set(_p1[0], _p1[1])
|
||||
p1x.set(...phantom)
|
||||
p2.set(_p2[0], _p2[1])
|
||||
} else if (_p1.length > _p2.length) { // when p1 is line, p2 is point
|
||||
p1.set(_p1[0], _p1[1])
|
||||
p1x.set(_p1[3], _p1[4])
|
||||
p2.set(_p2[0], _p2[1])
|
||||
@ -431,7 +493,7 @@ function updateAngle(linegeom, pointgeom, _l1, _l2, offset) {
|
||||
tA1 = unreflex(a[2] - (a[0] + shift))
|
||||
tA2 = unreflex(a[2] - (a[0] + dA + shift))
|
||||
|
||||
if (dA * tA1 < 0) {
|
||||
if (dA * tA1 < 0) { // if dA and tA1 are not the same sign
|
||||
a1 = a[0] + tA1 + shift
|
||||
deltaAngle = dA - tA1
|
||||
} else if (dA * tA2 > 0) {
|
||||
@ -506,9 +568,9 @@ const getAngle = (Obj3dLines) => {
|
||||
|
||||
|
||||
export function onDimMoveEnd(point) {
|
||||
if (point.userData.dimType == 'd') {
|
||||
point.userData.offset = hyp2.toArray() // save offset vector from hyp2
|
||||
} else {
|
||||
if (point.userData.dimType == 'a') {
|
||||
point.userData.offset = vecArr[5].toArray()
|
||||
} else {
|
||||
point.userData.offset = hyp2.toArray() // save offset vector from hyp2
|
||||
}
|
||||
}
|
@ -47,6 +47,35 @@ export const NavBar = () => {
|
||||
forceUpdate()
|
||||
}
|
||||
|
||||
// const mirror = (plane) => {
|
||||
// if (sc.selected.length != 2 || ) {
|
||||
// alert('please first select two bodies for boolean operation')
|
||||
// return
|
||||
// }
|
||||
// const [m1, m2] = sc.selected
|
||||
|
||||
// const mesh = sc.boolOp(m1, m2, code)
|
||||
|
||||
// sc.obj3d.add(mesh)
|
||||
|
||||
// dispatch({
|
||||
// type: 'set-entry-visibility', obj: {
|
||||
// [m1.name]: false,
|
||||
// [m2.name]: false,
|
||||
// [mesh.name]: true,
|
||||
// }
|
||||
// })
|
||||
|
||||
// dispatch({
|
||||
// type: 'rx-boolean', mesh, deps: [m1.name, m2.name]
|
||||
// })
|
||||
|
||||
|
||||
// sc.render()
|
||||
// forceUpdate()
|
||||
|
||||
// }
|
||||
|
||||
const addSketch = () => {
|
||||
const sketch = sc.addSketch()
|
||||
if (!sketch) {
|
||||
|
@ -11,7 +11,7 @@ export const Tree = () => {
|
||||
const fileHandle = useSelector(state => state.ui.fileHandle)
|
||||
|
||||
return <div className='sideNav flex flex-col bg-gray-800'>
|
||||
<div className='w-16 text-gray-50 h-9 text-lg mx-1 border-0 flex items-center focus:outline-none bg-transparent'>
|
||||
<div className='w-full text-gray-50 h-9 text-lg mx-1 border-0 flex items-center focus:outline-none bg-transparent'>
|
||||
{fileHandle ? fileHandle.name.replace(/\.[^/.]+$/, "") : 'untitled'}
|
||||
</div>
|
||||
{treeEntries.allIds.map((entId, idx) => (
|
||||
|
@ -7,8 +7,8 @@ const _vec3 = new THREE.Vector3()
|
||||
|
||||
|
||||
const raycaster = new THREE.Raycaster();
|
||||
raycaster.params.Line.threshold = 0.1;
|
||||
raycaster.params.Points.threshold = 0.1;
|
||||
raycaster.params.Line.threshold = 1;
|
||||
raycaster.params.Points.threshold = 1;
|
||||
|
||||
|
||||
const color = {
|
||||
|
4
todo.txt
4
todo.txt
@ -38,6 +38,10 @@ file save, stl export// done
|
||||
seperate scene from init logic only init cam and rendere // not an issue , ended up just splicing (1)
|
||||
add download button, different from save button // done
|
||||
|
||||
- dimension to origin vs ordinate dimensioninging
|
||||
- increased design payload handling
|
||||
|
||||
|
||||
-unable cancel out of new sketches //fixed seemingly
|
||||
-unable to delete arc // fixed seemingly
|
||||
|
||||
|
29
wasm/slvs.h
29
wasm/slvs.h
@ -397,6 +397,35 @@ static inline Slvs_Constraint Slvs_MakeConstraint(Slvs_hConstraint h,
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static inline Slvs_Constraint Slvs_MakeConstraint_Alt(Slvs_hConstraint h,
|
||||
Slvs_hGroup group,
|
||||
int type,
|
||||
Slvs_hEntity wrkpl,
|
||||
double valA,
|
||||
Slvs_hEntity ptA,
|
||||
Slvs_hEntity ptB,
|
||||
Slvs_hEntity entityA,
|
||||
Slvs_hEntity entityB,
|
||||
int other, int other2
|
||||
)
|
||||
{
|
||||
Slvs_Constraint r;
|
||||
memset(&r, 0, sizeof(r));
|
||||
r.h = h;
|
||||
r.group = group;
|
||||
r.type = type;
|
||||
r.wrkpl = wrkpl;
|
||||
r.valA = valA;
|
||||
r.ptA = ptA;
|
||||
r.ptB = ptB;
|
||||
r.entityA = entityA;
|
||||
r.entityB = entityB;
|
||||
r.other = other;
|
||||
r.other2 = other2;
|
||||
return r;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -3,7 +3,7 @@
|
||||
* initial guesses for their positions, and then constrain them. The solver
|
||||
* calculates their new positions, in order to satisfy the constraints.
|
||||
*
|
||||
* Copyright 2008-2013 Jonathan Westhues.
|
||||
* Copyright -2008-2013 Jonathan Westhues.
|
||||
*---------------------------------------------------------------------------*/
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
@ -43,9 +43,9 @@ int solver(int nPts, float *p_ptr, int nConst, float *c_ptr, int nLinks, float *
|
||||
/* First, we create our workplane. Its origin corresponds to the origin
|
||||
* of our base frame (x y z) = (0 0 0) */
|
||||
sys.param[sys.params++] = Slvs_MakeParam(1, g, 0.0);
|
||||
sys.param[sys.params++] = Slvs_MakeParam(2, g, 0.0);
|
||||
sys.param[sys.params++] = Slvs_MakeParam(3, g, 0.0);
|
||||
sys.entity[sys.entities++] = Slvs_MakePoint3d(101, g, 1, 2, 3);
|
||||
sys.param[sys.params++] = Slvs_MakeParam(2, g, 1.0);
|
||||
sys.param[sys.params++] = Slvs_MakeParam(3, g, -1.0);
|
||||
sys.entity[sys.entities++] = Slvs_MakePoint3d(-101, g, 1, 1, 1);
|
||||
/* and it is parallel to the xy plane, so it has basis vectors (1 0 0)
|
||||
* and (0 1 0). */
|
||||
Slvs_MakeQuaternion(1, 0, 0,
|
||||
@ -54,9 +54,9 @@ int solver(int nPts, float *p_ptr, int nConst, float *c_ptr, int nLinks, float *
|
||||
sys.param[sys.params++] = Slvs_MakeParam(5, g, qx);
|
||||
sys.param[sys.params++] = Slvs_MakeParam(6, g, qy);
|
||||
sys.param[sys.params++] = Slvs_MakeParam(7, g, qz);
|
||||
sys.entity[sys.entities++] = Slvs_MakeNormal3d(102, g, 4, 5, 6, 7);
|
||||
sys.entity[sys.entities++] = Slvs_MakeNormal3d(-102, g, 4, 5, 6, 7);
|
||||
|
||||
sys.entity[sys.entities++] = Slvs_MakeWorkplane(200, g, 101, 102);
|
||||
sys.entity[sys.entities++] = Slvs_MakeWorkplane(-200, g, -101, -102);
|
||||
|
||||
/* Now create a second group. We'll solve group 2, while leaving group 1
|
||||
* constant; so the workplane that we've created will be locked down,
|
||||
@ -65,9 +65,15 @@ int solver(int nPts, float *p_ptr, int nConst, float *c_ptr, int nLinks, float *
|
||||
/* These points are represented by their coordinates (u v) within the
|
||||
* workplane, so they need only two parameters each. */
|
||||
|
||||
sys.entity[sys.entities++] = Slvs_MakePoint2d(-103, g, -200, 1, 1);
|
||||
sys.entity[sys.entities++] = Slvs_MakePoint2d(-104, g, -200, 1, 3);
|
||||
sys.entity[sys.entities++] = Slvs_MakePoint2d(-105, g, -200, 3, 1);
|
||||
sys.entity[sys.entities++] = Slvs_MakeLineSegment(-106, g,
|
||||
-200, -103, -104); //y-axis
|
||||
sys.entity[sys.entities++] = Slvs_MakeLineSegment(-107, g,
|
||||
-200, -103, -105); //x-axis
|
||||
|
||||
Slvs_hParam ph = 11;
|
||||
Slvs_hParam vh = 301, vh_s = 301;
|
||||
Slvs_hParam lh = 400, lh_s = 400;
|
||||
|
||||
float *buf_pt_start = p_ptr;
|
||||
int p_start = sys.params;
|
||||
@ -81,7 +87,7 @@ int solver(int nPts, float *p_ptr, int nConst, float *c_ptr, int nLinks, float *
|
||||
|
||||
sys.param[sys.params++] = Slvs_MakeParam(ph++, g, (float)*p_ptr++);
|
||||
sys.param[sys.params++] = Slvs_MakeParam(ph++, g, (float)*p_ptr++);
|
||||
sys.entity[sys.entities++] = Slvs_MakePoint2d(i, g, 200, ph - 1, ph - 2);
|
||||
sys.entity[sys.entities++] = Slvs_MakePoint2d(i, g, -200, ph - 1, ph - 2);
|
||||
p_ptr += 1;
|
||||
}
|
||||
|
||||
@ -92,10 +98,10 @@ int solver(int nPts, float *p_ptr, int nConst, float *c_ptr, int nLinks, float *
|
||||
{
|
||||
case 0:
|
||||
sys.entity[sys.entities++] = Slvs_MakeLineSegment((int)*(l_ptr + 2), g,
|
||||
200, (int)*l_ptr, (int)*(l_ptr + 1));
|
||||
-200, (int)*l_ptr, (int)*(l_ptr + 1));
|
||||
break;
|
||||
case 1:
|
||||
sys.entity[sys.entities++] = Slvs_MakeArcOfCircle((int)*(l_ptr + 3), g, 200, 102,
|
||||
sys.entity[sys.entities++] = Slvs_MakeArcOfCircle((int)*(l_ptr + 3), g, -200, -102,
|
||||
(int)*(l_ptr + 2), (int)*(l_ptr), (int)*(l_ptr + 1));
|
||||
break;
|
||||
default:
|
||||
@ -109,19 +115,30 @@ int solver(int nPts, float *p_ptr, int nConst, float *c_ptr, int nLinks, float *
|
||||
sys.constraint[sys.constraints++] = Slvs_MakeConstraint(
|
||||
c_pre++, 2,
|
||||
SLVS_C_POINTS_COINCIDENT,
|
||||
200,
|
||||
-200,
|
||||
-1,
|
||||
101, geomStartIdx, -1, -1);
|
||||
-101, geomStartIdx, -1, -1);
|
||||
|
||||
|
||||
for (int c_id=c_pre; c_id < c_pre + nConst; c_id++, c_ptr += 6)
|
||||
for (int c_id = c_pre; c_id < c_pre + nConst; c_id++, c_ptr += 8)
|
||||
{
|
||||
sys.constraint[sys.constraints++] = Slvs_MakeConstraint(
|
||||
c_id, g,
|
||||
(int)*c_ptr + 100000,
|
||||
200,
|
||||
*(c_ptr + 1),
|
||||
(int)*(c_ptr + 2), (int)*(c_ptr + 3), (int)*(c_ptr + 4), (int)*(c_ptr + 5));
|
||||
if ((int)*c_ptr >= 34)
|
||||
{
|
||||
sys.constraint[sys.constraints++] = Slvs_MakeConstraint_Alt(
|
||||
c_id, g,
|
||||
30 + 100000,
|
||||
-200,
|
||||
*(c_ptr + 1),
|
||||
(int)*(c_ptr + 2), (int)*(c_ptr + 3), (int)*c_ptr == 34 ? -106: -107, (int)*(c_ptr + 5), (int)*(c_ptr + 6), (int)*(c_ptr + 7));
|
||||
}
|
||||
else
|
||||
{
|
||||
sys.constraint[sys.constraints++] = Slvs_MakeConstraint_Alt(
|
||||
c_id, g,
|
||||
(int)*c_ptr + 100000,
|
||||
-200,
|
||||
*(c_ptr + 1),
|
||||
(int)*(c_ptr + 2), (int)*(c_ptr + 3), (int)*(c_ptr + 4), (int)*(c_ptr + 5), (int)*(c_ptr + 6), (int)*(c_ptr + 7));
|
||||
}
|
||||
}
|
||||
|
||||
/* And solve. */
|
||||
@ -174,7 +191,6 @@ int main(int argc, char *argv[])
|
||||
sys.failed = CheckMalloc(500 * sizeof(sys.failed[0]));
|
||||
sys.faileds = 500;
|
||||
|
||||
|
||||
// printf("hello\n");
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user