extrude not working
parent
ff584e8a21
commit
3dd7d47071
Binary file not shown.
|
@ -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'))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 |
48
src/Scene.js
48
src/Scene.js
|
@ -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)
|
|
||||||
|
|
58
src/app.jsx
58
src/app.jsx
|
@ -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()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 };
|
|
@ -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 }
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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] ///////
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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]
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 }
|
|
@ -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. */
|
||||||
|
|
Loading…
Reference in New Issue