extrude not working

master
howard 2021-04-02 12:33:09 -07:00
parent ff584e8a21
commit 3dd7d47071
15 changed files with 578 additions and 79 deletions

BIN
dist/solver.wasm vendored

Binary file not shown.

View File

@ -17,7 +17,10 @@ try {
let name = file.split('.')[0] let name = file.split('.')[0]
name = name[0].toUpperCase() + name.slice(1) name = name[0].toUpperCase() + name.slice(1)
names.push(name) names.push(name)
const jsx = await svgr(res, { icon: true, plugins: ['@svgr/plugin-svgo', '@svgr/plugin-jsx', '@svgr/plugin-prettier'] }, { componentName: name }) const jsx = await svgr(res, { icon: true,
plugins: ['@svgr/plugin-svgo', '@svgr/plugin-jsx', '@svgr/plugin-prettier'],
replaceAttrValues: { '#000': 'currentColor' }
}, { componentName: name })
const split = jsx.split('\n') const split = jsx.split('\n')
output.push(split.slice(1,split.length-2).join('\n')) output.push(split.slice(1,split.length-2).join('\n'))
} }

182
icon/svgr_raw/dimension.svg Normal file
View File

@ -0,0 +1,182 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
height="16"
fill="currentColor"
class="bi bi-intersect"
viewBox="0 0 16 16"
version="1.1"
id="svg4"
sodipodi:docname="dimension.svg"
inkscape:version="1.0.2 (1.0.2+r75+1)">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8">
<marker
style="overflow:visible"
id="TriangleInS"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="TriangleInS"
inkscape:isstock="true">
<path
transform="scale(-0.2)"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z "
id="path2009" />
</marker>
<marker
style="overflow:visible"
id="marker2364"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="TriangleOutS"
inkscape:isstock="true">
<path
transform="scale(0.2)"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z "
id="path2362" />
</marker>
<marker
style="overflow:visible"
id="StopS"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="StopS"
inkscape:isstock="true">
<path
transform="scale(0.2)"
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
d="M 0.0,5.65 L 0.0,-5.65"
id="path2045" />
</marker>
<marker
style="overflow:visible;"
id="marker2268"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow2Send"
inkscape:isstock="true">
<path
transform="scale(0.3) rotate(180) translate(-2.3,0)"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
id="path2266" />
</marker>
<marker
style="overflow:visible"
id="TriangleOutS"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="TriangleOutS"
inkscape:isstock="true">
<path
transform="scale(0.2)"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z "
id="path2018" />
</marker>
<marker
style="overflow:visible;"
id="Arrow2Send"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow2Send"
inkscape:isstock="true">
<path
transform="scale(0.3) rotate(180) translate(-2.3,0)"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
id="path1903" />
</marker>
<marker
style="overflow:visible;"
id="Arrow1Send"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow1Send"
inkscape:isstock="true">
<path
transform="scale(0.2) rotate(180) translate(6,0)"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
id="path1885" />
</marker>
<marker
style="overflow:visible"
id="Arrow1Lstart"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow1Lstart"
inkscape:isstock="true">
<path
transform="scale(0.8) translate(12.5,0)"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
id="path1870" />
</marker>
</defs>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1514"
inkscape:window-height="1169"
id="namedview6"
showgrid="false"
inkscape:zoom="21.968944"
inkscape:cx="7.5922599"
inkscape:cy="7.4906679"
inkscape:window-x="713"
inkscape:window-y="134"
inkscape:window-maximized="0"
inkscape:current-layer="svg4"
inkscape:document-rotation="0" />
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#TriangleInS);marker-end:url(#marker2364)"
d="M 4.0087912,10.008791 10.008791,4.0087913"
id="path1868"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.893;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 15.484723,4.5157231 -4,-3.99999992"
id="path2524-2"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.893;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 4.5157232,15.484723 -4.00000002,-4"
id="path2524-2-0"
sodipodi:nodetypes="cc" />
</svg>

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -11,12 +11,14 @@ import Stats from './utils/stats.module.js';
import { add3DPoint } from './datums' import { add3DPoint } from './datums'
import { extrude } from './extrude' import { extrude } from './extrude'
import { onHover, onPick } from './utils/mouseEvents'; import { onHover, onPick } from './utils/mouseEvents';
import { _vec2, _vec3, color } from './utils/static' import { _vec2, _vec3, color, awaitPts } from './utils/shared'
import { Vector3 } from 'three/src/Three'; import { Vector3 } from 'three/src/Three';
import {AxesHelper} from './utils/axes' import {AxesHelper} from './utils/axes'
import CSG from "./utils/three-csg.js" import CSG from "./utils/three-csg.js"
window.BoolOp = CSG
const eq = (a1, a2) => { const eq = (a1, a2) => {
if (a1.length != a2.length) return false if (a1.length != a2.length) return false
for (let i = 0; i < a1.length; i++) { for (let i = 0; i < a1.length; i++) {
@ -102,6 +104,7 @@ export class Scene {
this.extrude = extrude.bind(this); this.extrude = extrude.bind(this);
this.onHover = onHover.bind(this); this.onHover = onHover.bind(this);
this.onPick = onPick.bind(this); this.onPick = onPick.bind(this);
this.awaitPts = awaitPts.bind(this);
this.obj3d.addEventListener('change', this.render); this.obj3d.addEventListener('change', this.render);
controls.addEventListener('change', this.render); controls.addEventListener('change', this.render);
@ -183,33 +186,11 @@ function render() {
async function addSketch() { async function addSketch() {
let references = this.selected.slice()
if (references.length == 0) { let references = await this.awaitPts(3)
while (references.length < 3) {
let pt;
try {
pt = await new Promise((res, rej) => {
this.canvas.addEventListener('pointerdown', () => res(this.hovered[0]), { once: true })
window.addEventListener('keydown', (e) => rej(e), { once: true })
})
if (pt.name[0] == 'p') {
references.push(pt)
} else if (pt.name[0] == 'd') {
references = [pt]
break;
}
} catch (e) {
if (e.key == 'Escape') {
console.log('cancelled')
return;
}
}
}
}
const sketch = new Sketch(this.camera, this.canvas, this.store) const sketch = new Sketch(this.camera, this.canvas, this.store)
@ -240,7 +221,7 @@ async function addSketch() {
} }
window.sc = new Scene(store) window.sc = new Scene(store)
sc.loadState() // sc.loadState()
@ -248,17 +229,4 @@ sc.loadState()
// //Create a bsp tree from each of the meshes
// let bspA = CSG.fromMesh( mm[0] )
// let bspB = CSG.fromMesh( mm[2] )
// // 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 = CSG.toMesh( bspResult, mm[0].matrix, mm[0].material )
// sc.add(meshResult)

View File

@ -7,8 +7,8 @@ import { Provider, useDispatch, useSelector } from 'react-redux'
import { FaCube, FaEdit } from 'react-icons/fa' import { FaCube, FaEdit } from 'react-icons/fa'
import { MdEdit, MdDone, MdVisibilityOff, MdVisibility } from 'react-icons/md' import { MdEdit, MdDone, MdVisibilityOff, MdVisibility } from 'react-icons/md'
import { RiShape2Fill } from 'react-icons/ri' import { RiShape2Fill } from 'react-icons/ri'
import { Union, Subtract, Intersect, Line, Arc } from './icons' import * as Icon from "./icons";
import { color } from './utils/static' import { color } from './utils/shared'
export const Root = ({ store }) => ( export const Root = ({ store }) => (
<Provider store={store}> <Provider store={store}>
@ -48,11 +48,12 @@ const App = () => {
[FaEdit, sc.addSketch, 'Sketch'] [FaEdit, sc.addSketch, 'Sketch']
, ,
[FaCube, () => sc.extrude(treeEntries.byNid[activeSketchNid]), 'Extrude'], [FaCube, () => sc.extrude(treeEntries.byNid[activeSketchNid]), 'Extrude'],
[Union, () => sc.extrude(treeEntries.byNid[activeSketchNid]), 'Union'], [Icon.Union, () => sc.extrude(treeEntries.byNid[activeSketchNid]), 'Union'],
[Subtract, () => sc.extrude(treeEntries.byNid[activeSketchNid]), 'Subtract'], [Icon.Subtract, subtract, 'Subtract'],
[Intersect, () => sc.extrude(treeEntries.byNid[activeSketchNid]), 'Intersect'], [Icon.Intersect, () => sc.extrude(treeEntries.byNid[activeSketchNid]), 'Intersect'],
[Line, () => sc.extrude(treeEntries.byNid[activeSketchNid]), 'Line'], [Icon.Dimension, () => sc.extrude(treeEntries.byNid[activeSketchNid]), 'Dimension'],
[Arc, () => sc.extrude(treeEntries.byNid[activeSketchNid]), 'Arc'], [Icon.Line, () => sc.extrude(treeEntries.byNid[activeSketchNid]), 'Line'],
[Icon.Arc, () => sc.extrude(treeEntries.byNid[activeSketchNid]), 'Arc'],
] ]
return <div className='absolute left-0 w-1/6 flex flex-col'> return <div className='absolute left-0 w-1/6 flex flex-col'>
@ -83,16 +84,19 @@ const TreeEntry = ({ entId }) => {
const activeSketchNid = useSelector(state => state.activeSketchNid) const activeSketchNid = useSelector(state => state.activeSketchNid)
let entry; let obj3d, entry;
if (entId[0]=="s") {
entry = treeEntries[entId].obj3d entry = treeEntries[entId]
if (entId[0] == "s") {
obj3d = treeEntries[entId].obj3d
} else { } else {
entry = treeEntries[entId] obj3d = treeEntries[entId]
} }
const [_, forceUpdate] = useReducer(x => x + 1, 0); const [_, forceUpdate] = useReducer(x => x + 1, 0);
const vis = entry.visible const vis = obj3d.visible
return <div className='bg-gray-50 flex justify-between'> return <div className='bg-gray-50 flex justify-between'>
<div className='btn' <div className='btn'
@ -108,7 +112,7 @@ const TreeEntry = ({ entId }) => {
vis ? vis ?
<div className='btn' <div className='btn'
onClick={() => { onClick={() => {
entry.visible = false; obj3d.visible = false;
sc.render() sc.render()
forceUpdate() forceUpdate()
}} }}
@ -118,7 +122,7 @@ const TreeEntry = ({ entId }) => {
: :
<div className='btn' <div className='btn'
onClick={() => { onClick={() => {
entry.visible = true; obj3d.visible = true;
sc.render() sc.render()
forceUpdate() forceUpdate()
}} }}
@ -156,6 +160,28 @@ const TreeEntry = ({ entId }) => {
} }
const DesignLeaf = () => { const subtract = () => {
// //Create a bsp tree from each of the meshes
console.log(sc.selected.length !=2 || !sc.selected.every(e=>e.name && e.name[0]=='m'),"wtf")
if (sc.selected.length !=2 || !sc.selected.every(e=>e.name && e.name[0]=='m')) return
console.log('here')
const [m1, m2] = sc.selected
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 )
sc.obj3d.add(meshResult)
sc.render()
}
}

View File

@ -1,5 +1,5 @@
import * as THREE from 'three/src/Three'; import * as THREE from 'three/src/Three';
import { color, ptObj } from './utils/static' import { color, ptObj } from './utils/shared'
export function extrude(sketch) { export function extrude(sketch) {
let constraints = sketch.constraints; let constraints = sketch.constraints;

View File

@ -23,6 +23,67 @@ function Arc(props) {
); );
} }
function Dimension(props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
fill="currentColor"
className="prefix__bi prefix__bi-intersect"
viewBox="0 0 16 16"
{...props}
>
<defs>
<marker
id="prefix__a"
refX={0}
refY={0}
orient="auto"
overflow="visible"
>
<path
d="M-1.154 0l1.73-1v2l-1.73-1z"
fillRule="evenodd"
stroke="currentColor"
strokeWidth=".2pt"
fill="currentColor"
/>
</marker>
<marker
id="prefix__b"
refX={0}
refY={0}
orient="auto"
overflow="visible"
>
<path
d="M1.154 0l-1.73 1v-2l1.73 1z"
fillRule="evenodd"
stroke="currentColor"
strokeWidth=".2pt"
fill="currentColor"
/>
</marker>
</defs>
<path
d="M4.009 10.009l6-6"
fill="none"
stroke="currentColor"
strokeWidth={2}
markerStart="url(#prefix__a)"
markerEnd="url(#prefix__b)"
/>
<path
d="M15.485 4.516l-4-4M4.516 15.485l-4-4"
fill="none"
stroke="currentColor"
strokeWidth={0.893}
/>
</svg>
);
}
function Intersect(props) { function Intersect(props) {
return ( return (
<svg <svg
@ -171,4 +232,4 @@ function Union(props) {
</svg> </svg>
); );
} }
export { Arc, Intersect, Line, Subtract, Union }; export { Arc, Dimension, Intersect, Line, Subtract, Union };

View File

@ -6,10 +6,10 @@ import { drawOnClick1, drawOnClick2, drawPreClick2, drawClear } from './drawEven
import { onHover, onDrag, onPick, onRelease } from '../utils/mouseEvents' import { onHover, onDrag, onPick, onRelease } from '../utils/mouseEvents'
import { addDimension, setCoincident } from './constraintEvents' import { addDimension, setCoincident } from './constraintEvents'
import { get3PtArc } from './drawArc' import { get3PtArc } from './drawArc'
import { _vec2, _vec3, raycaster } from '../utils/static' import { _vec2, _vec3, raycaster, awaitPts } from '../utils/shared'
import { replacer, reviver } from '../utils/mapJSONReplacer' import { replacer, reviver } from '../utils/mapJSONReplacer'
import {AxesHelper} from '../utils/axes' import { AxesHelper } from '../utils/axes'
import { drawDimensionPre } from './drawDimension'
@ -108,6 +108,9 @@ class Sketch {
this.drawPreClick2 = drawPreClick2.bind(this); this.drawPreClick2 = drawPreClick2.bind(this);
this.drawOnClick2 = drawOnClick2.bind(this); this.drawOnClick2 = drawOnClick2.bind(this);
this.awaitPts = awaitPts.bind(this);
this.drawDimensionPre = drawDimensionPre.bind(this);
this.onHover = onHover.bind(this); this.onHover = onHover.bind(this);
this.onPick = onPick.bind(this); this.onPick = onPick.bind(this);
this.onDrag = onDrag.bind(this); this.onDrag = onDrag.bind(this);
@ -176,6 +179,10 @@ class Sketch {
this.canvas.addEventListener('pointerdown', this.drawOnClick1) this.canvas.addEventListener('pointerdown', this.drawOnClick1)
this.mode = "arc" this.mode = "arc"
break; break;
case 'd':
this.drawDimensionPre()
this.mode = "arc"
break;
case 'x': case 'x':
this.deleteSelected() this.deleteSelected()
break; break;
@ -333,7 +340,7 @@ class Sketch {
*/ */
for (let i = 1, ptr = (pts_buffer >> 2) + 3; i < this.obj3d.children.length; i += 1, ptr += 3) { for (let i = 1, ptr = (pts_buffer >> 2) + 3; i < this.obj3d.children.length; i += 1, ptr += 3) {
// for (let i = 0, ptr = (pts_buffer >> 2) + 3; i < this.obj3d.children.length; i += 1, ptr += 3) { // for (let i = 0, ptr = (pts_buffer >> 2) + 3; i < this.obj3d.children.length; i += 1, ptr += 3) {
const pos = this.obj3d.children[i].geometry.attributes.position; const pos = this.obj3d.children[i].geometry.attributes.position;
if (isNaN(Module.HEAPF32[ptr])) { if (isNaN(Module.HEAPF32[ptr])) {
@ -393,8 +400,40 @@ Object.assign(Sketch.prototype,
'arc': 1 'arc': 1
}, },
constraintNum: { constraintNum: {
'coincident': 0, points_coincident: 0,
'distance': 1 pt_pt_distance: 1,
pt_plane_distance: 2,
pt_line_distance: 3,
pt_face_distance: 4,
pt_in_plane: 5,
pt_on_line: 6,
pt_on_face: 7,
equal_length_lines: 8,
length_ratio: 9,
eq_len_pt_line_d: 10,
eq_pt_ln_distances: 11,
equal_angle: 12,
equal_line_arc_len: 13,
symmetric: 14,
symmetric_horiz: 15,
symmetric_vert: 16,
symmetric_line: 17,
at_midpoint: 18,
horizontal: 19,
vertical: 20,
diameter: 21,
pt_on_circle: 22,
same_orientation: 23,
angle: 24,
parallel: 25,
perpendicular: 26,
arc_line_tangent: 27,
cubic_line_tangent: 28,
equal_radius: 29,
proj_pt_distance: 30,
where_dragged: 31,
curve_curve_tangent: 32,
length_difference: 33,
}, },
max_pts: 1000, max_pts: 1000,
max_links: 1000, max_links: 1000,
@ -404,4 +443,6 @@ Object.assign(Sketch.prototype,
export { Sketch } export { Sketch }

View File

@ -31,7 +31,7 @@ export function setCoincident() {
for (let i = 1; i < toComb.length; i++) { for (let i = 1; i < toComb.length; i++) {
this.constraints.set(++this.c_id, this.constraints.set(++this.c_id,
[ [
'coincident', -1, 'points_coincident', -1,
[toComb[i - 1].name, toComb[i].name, -1, -1] /////// [toComb[i - 1].name, toComb[i].name, -1, -1] ///////
] ]
) )

View File

@ -1,8 +1,8 @@
import * as THREE from '../../node_modules/three/src/Three'; import * as THREE from '../../node_modules/three/src/Three';
import {lineMaterial, pointMaterial} from '../utils/static' import {lineMaterial, pointMaterial} from '../utils/shared'
import {ptObj, lineObj} from '../utils/static' import {ptObj, lineObj} from '../utils/shared'
const n = 30 const n = 30

View File

@ -0,0 +1,160 @@
import * as THREE from '../../node_modules/three/src/Three';
import { ptObj, lineObj, awaitPts } from '../utils/shared'
const DptObj = (n) => {
const ret = new THREE.Points(
new THREE.BufferGeometry().setAttribute('position',
new THREE.Float32BufferAttribute(n || 3, 3)
),
pointMaterial.clone()
);
ret.name = 'p' + nid++
ret.matrixAutoUpdate = false;
ret.userData.constraints = []
return ret
}
const DlineObj = (n = 1) => {
const ret = new THREE.Line(
new THREE.BufferGeometry().setAttribute('position',
new THREE.Float32BufferAttribute(3 * (n + 1), 3)
),
lineMaterial.clone()
);
ret.name = 'l' + nid++
ret.matrixAutoUpdate = false;
ret.userData.constraints = []
return ret
}
export async function drawDimensionPre() {
let [p1, p2] = await this.awaitPts(2)
const lines = [
DlineObj(), // 0:
DlineObj(), // 1:
DlineObj(), // 2:
]
const points = [
p1, // 0:
DptObj(), // 1: |
DptObj(), // 2: |
DptObj(), // 3: |
DptObj(), // 4: |
DptObj(), // 5: |
DptObj(), // 6: |
p2, // 7:
]
this.constraints.set(++this.c_id, //???
[
'pt_pt_distance', 10,
[p1.name, p2.name, -1, -1]
]
)
p1.userData.constraints.push(this.c_id)
p2.userData.constraints.push(this.c_id)
for (let i = 1; i++; i < points.length) {
if (i % 2) {
this.constraints.set(++this.c_id, //??? increment investigation
[
'coincident', -1,
[points[i - 1].name, points[i].name, -1, -1]
]
)
points[i - 1].userData.constraints.push(this.c_id)
points[i].userData.constraints.push(this.c_id)
} else {
const toPush = [...points.slice(i - 2, i), lines[i / 2 - 1]]
this.linkedObjs.set(this.l_id, ['line', toPush.map(e => e.name)])
for (let obj of toPush) {
obj.userData.l_id = this.l_id
}
this.l_id += 1
if (i == 4 || i == 6) {
this.constraints.set(++this.c_id, //???
[
'perpendicular', -1,
[-1, -1, lines[i / 2 - 2].name, lines[i / 2 - 1].name]
]
)
lines[i / 2 - 2].userData.constraints.push(this.c_id)
lines[i / 2 - 1].userData.constraints.push(this.c_id)
}
}
}
// line[1].geometry.attributes.position.set(p1.geometry.attributes.position.array)
// line[1].geometry.attributes.position.set(p1.geometry.attributes.position.array, 3)
// line[0].geometry.attributes.position.set(p1.geometry.attributes.position.array)
// line[0].geometry.attributes.position.set(p2.geometry.attributes.position.array, 3)
// line[2].geometry.attributes.position.set(p2.geometry.attributes.position.array)
// line[2].geometry.attributes.position.set(p2.geometry.attributes.position.array, 3)
return [p1, p2, line];
}
export function drawLine(mouseLoc) {
line.geometry.attributes.position.set(mouseLoc)
p1.geometry.attributes.position.set(mouseLoc)
if (this.subsequent) {
this.constraints.set(++this.c_id,
[
'coincident', -1,
[this.obj3d.children[this.obj3d.children.length - 2].name, p1.name, -1, -1]
]
)
p1.userData.constraints.push(this.c_id)
this.obj3d.children[this.obj3d.children.length - 2].userData.constraints.push(this.c_id)
}
return [p1, p2, line];
}
export function drawLine2(mouseLoc, toPush) {
const [p1, p2, line] = toPush
p2.geometry.attributes.position.set(mouseLoc);
p2.geometry.attributes.position.needsUpdate = true;
p2.geometry.computeBoundingSphere();
line.geometry.attributes.position.set(mouseLoc, 3)
line.geometry.attributes.position.needsUpdate = true;
}

View File

@ -1,5 +1,5 @@
import * as THREE from '../../node_modules/three/src/Three'; import * as THREE from '../../node_modules/three/src/Three';
import {ptObj, lineObj} from '../utils/static' import {ptObj, lineObj} from '../utils/shared'
export function drawLine(mouseLoc) { export function drawLine(mouseLoc) {
@ -23,9 +23,9 @@ export function drawLine(mouseLoc) {
if (this.subsequent) { if (this.subsequent) {
this.constraints.set(++this.c_id, this.constraints.set(++this.c_id, //??? why incremennt before not after
[ [
'coincident', -1, 'points_coincident', -1,
[this.obj3d.children[this.obj3d.children.length - 2].name, p1.name, -1, -1] [this.obj3d.children[this.obj3d.children.length - 2].name, p1.name, -1, -1]
] ]
) )

View File

@ -1,5 +1,5 @@
import * as THREE from 'three/src/Three'; import * as THREE from 'three/src/Three';
import { raycaster, color } from './static'; import { raycaster, color } from './shared';
export function onHover(e) { export function onHover(e) {
if (this.mode || e.buttons) return if (this.mode || e.buttons) return

View File

@ -1,4 +1,4 @@
import * as THREE from '../../node_modules/three/src/Three'; import * as THREE from 'three/src/Three';
@ -56,4 +56,36 @@ const lineObj = (n = 1) => {
} }
export { lineMaterial, pointMaterial, _vec2, _vec3, raycaster, color, ptObj, lineObj } async function awaitPts(n) {
let references = this.selected.slice()
if (references.length == 0) {
while (references.length < n) {
let pt;
try {
pt = await new Promise((res, rej) => {
this.canvas.addEventListener('pointerdown', () => res(this.hovered[0]), { once: true })
window.addEventListener('keydown', (e) => rej(e), { once: true })
})
if (pt.name[0] == 'p') {
references.push(pt)
} else if (pt.name[0] == 'd') {
references = [pt]
break;
}
} catch (e) {
if (e.key == 'Escape') {
console.log('cancelled')
return;
}
}
}
}
return references
}
export { lineMaterial, pointMaterial, _vec2, _vec3, raycaster, color, ptObj, lineObj, awaitPts }

View File

@ -110,8 +110,12 @@ int solver(int nPts, float *p_ptr, int nConst, float *c_ptr, int nLinks, float *
for (int i = 0; i < nConst; i++) for (int i = 0; i < nConst; i++)
{ {
if ((int)*c_ptr == 0)
switch ((int)*c_ptr + 100000)
{ {
case SLVS_C_POINTS_COINCIDENT:
c_ptr += 2; c_ptr += 2;
sys.constraint[sys.constraints++] = Slvs_MakeConstraint( sys.constraint[sys.constraints++] = Slvs_MakeConstraint(
con_id++, g, con_id++, g,
@ -121,11 +125,33 @@ int solver(int nPts, float *p_ptr, int nConst, float *c_ptr, int nLinks, float *
(int)*c_ptr, (int)*(c_ptr + 1), 0, 0); (int)*c_ptr, (int)*(c_ptr + 1), 0, 0);
c_ptr += 4; c_ptr += 4;
} break;
else case 1:
{
break;
default:
c_ptr += 6; c_ptr += 6;
break;
} }
// if ((int)*c_ptr + 100000 == SLVS_C_POINTS_COINCIDENT)
// {
// c_ptr += 2;
// sys.constraint[sys.constraints++] = Slvs_MakeConstraint(
// con_id++, g,
// SLVS_C_POINTS_COINCIDENT,
// 200,
// 0.0,
// (int)*c_ptr, (int)*(c_ptr + 1), 0, 0);
// c_ptr += 4;
// }
// else
// {
// c_ptr += 6;
// }
} }
/* And solve. */ /* And solve. */