checkpt
parent
b6bc0cb2e0
commit
c7457f9c58
58
src/Scene.js
58
src/Scene.js
|
@ -14,6 +14,7 @@ import { onHover, onPick } from './utils/mouseEvents';
|
|||
import { _vec2, _vec3, color, awaitPts } from './utils/shared'
|
||||
import { Vector3 } from 'three/src/Three';
|
||||
import { AxesHelper } from './utils/axes'
|
||||
import { Patch } from './utils/patch'
|
||||
|
||||
import CSG from "./utils/three-csg.js"
|
||||
|
||||
|
@ -37,13 +38,18 @@ export class Scene {
|
|||
this.canvas = document.querySelector('#c');
|
||||
this.renderer = new THREE.WebGLRenderer({ canvas: this.canvas });
|
||||
|
||||
|
||||
const size = 1;
|
||||
const near = 0;
|
||||
const far = 100;
|
||||
this.camera = new THREE.OrthographicCamera(-size, size, size, -size, near, far);
|
||||
this.camera.zoom = 0.1;
|
||||
this.camera.position.set(50, 50, 50);
|
||||
const cameraDist = 50
|
||||
const xzAngle = 30 * Math.PI / 180
|
||||
this.camera.position.set(
|
||||
cameraDist * Math.sin(xzAngle),
|
||||
cameraDist * Math.tan(30 * Math.PI / 180),
|
||||
cameraDist * Math.cos(xzAngle)
|
||||
);
|
||||
|
||||
// const controls = new OrbitControls(camera, view1Elem);
|
||||
const controls = new TrackballControls(this.camera, this.canvas);
|
||||
|
@ -52,19 +58,27 @@ export class Scene {
|
|||
|
||||
this.obj3d = new THREE.Scene()
|
||||
|
||||
this.obj3d.background = new THREE.Color(0x888888);
|
||||
this.obj3d.background = new THREE.Color(color.background);
|
||||
const helpersGroup = new THREE.Group();
|
||||
helpersGroup.name = "helpersGroup";
|
||||
this.obj3d.add(helpersGroup);
|
||||
const axesHelper = new AxesHelper(0.4);
|
||||
helpersGroup.add(axesHelper);
|
||||
|
||||
// console.log(color)
|
||||
// const axesHelper = new AxesHelper(0.4);
|
||||
// helpersGroup.add(axesHelper);
|
||||
|
||||
|
||||
const patch = new Patch(0.5);
|
||||
helpersGroup.add(patch);
|
||||
|
||||
|
||||
|
||||
const planeGeom = new THREE.PlaneGeometry(5, 5)
|
||||
|
||||
const pxy = new THREE.Mesh(
|
||||
new THREE.PlaneGeometry(5, 5),
|
||||
planeGeom,
|
||||
new THREE.MeshBasicMaterial({
|
||||
color: color.plane,
|
||||
opacity: 0.2,
|
||||
opacity: 0.05,
|
||||
side: THREE.DoubleSide,
|
||||
transparent: true,
|
||||
depthWrite: false,
|
||||
|
@ -72,16 +86,22 @@ export class Scene {
|
|||
})
|
||||
);
|
||||
|
||||
pxy.name = 'd' + nid++
|
||||
pxy.userData.type = 'plane'
|
||||
helpersGroup.add(pxy);
|
||||
|
||||
pxy.add(
|
||||
new THREE.LineSegments(
|
||||
new THREE.EdgesGeometry(planeGeom),
|
||||
new THREE.LineBasicMaterial({ color: color.planeBorder })
|
||||
)
|
||||
)
|
||||
|
||||
const pyz = pxy.clone().rotateY(Math.PI / 2);
|
||||
pyz.material = pyz.material.clone();
|
||||
|
||||
const pxz = pxy.clone().rotateX(-Math.PI / 2);
|
||||
pxz.material = pxz.material.clone();
|
||||
|
||||
|
||||
helpersGroup.add(pxy);
|
||||
helpersGroup.add(pyz);
|
||||
helpersGroup.add(pxz);
|
||||
|
||||
|
@ -173,6 +193,20 @@ export class Scene {
|
|||
this.store.dispatch({ type: 'restore-state', state })
|
||||
}
|
||||
|
||||
clearSelection() {
|
||||
for (let x = 0; x < this.selected.length; x++) {
|
||||
const obj = this.selected[x]
|
||||
obj.material.color.set(color[obj.userData.type])
|
||||
}
|
||||
for (let x = 0; x < this.hovered.length; x++) {
|
||||
const obj = this.selected[x]
|
||||
obj.material.color.set(color[obj.userData.type])
|
||||
}
|
||||
this.obj3d.dispatchEvent({ type: 'change' })
|
||||
this.selected = []
|
||||
console.log('fireed')
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -249,7 +283,7 @@ async function addSketch() {
|
|||
}
|
||||
|
||||
|
||||
|
||||
this.clearSelection()
|
||||
|
||||
sketch.activate()
|
||||
this.activeSketch = sketch
|
||||
|
|
10
src/app.jsx
10
src/app.jsx
|
@ -66,8 +66,9 @@ const App = () => {
|
|||
|
||||
const [_, forceUpdate] = useReducer(x => x + 1, 0);
|
||||
|
||||
return <div className=''>
|
||||
<div className='absolute flex'>
|
||||
return <>
|
||||
<div className='absolute flex ml-auto mr-auto left-0 right-0 justify-center'>
|
||||
{/* <div className='absolute flex justify-center'> */}
|
||||
{
|
||||
btnz.map(([Icon, fcn, txt], idx) => (
|
||||
<div className="btn flex items-center justify-start p-1 text-lg" key={idx}
|
||||
|
@ -80,13 +81,13 @@ const App = () => {
|
|||
}
|
||||
</div>
|
||||
|
||||
<div className='absolute left-0 top-10 w-40 flex flex-col'>
|
||||
<div className='absolute left-0 top-36 w-40 flex flex-col'>
|
||||
{treeEntries.allIds.map((entId, idx) => (
|
||||
<TreeEntry key={idx} entId={entId} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</>
|
||||
|
||||
}
|
||||
|
||||
|
@ -142,6 +143,7 @@ const TreeEntry = ({ entId }) => {
|
|||
onClick={() => {
|
||||
activeSketchId && treeEntries[activeSketchId].deactivate()
|
||||
entry.activate()
|
||||
sc.clearSelection()
|
||||
sc.activeSketch = entry;
|
||||
}}
|
||||
>
|
||||
|
|
|
@ -8,7 +8,7 @@ import { addDimension, setCoincident } from './constraintEvents'
|
|||
import { get3PtArc } from './drawArc'
|
||||
import { _vec2, _vec3, raycaster, awaitPts } from '../utils/shared'
|
||||
import { replacer, reviver } from '../utils/mapJSONReplacer'
|
||||
import { AxesHelper } from '../utils/axes'
|
||||
import { AxesHelper } from '../utils/sketchAxes'
|
||||
import { drawDimension, _onMoveDimension, setDimLines, updateDim } from './drawDimension';
|
||||
|
||||
|
||||
|
@ -48,7 +48,7 @@ class Sketch {
|
|||
this.constraints = new Map()
|
||||
this.c_id = 0;
|
||||
|
||||
this.obj3d.add(new THREE.Group().add(new AxesHelper(2)));
|
||||
this.obj3d.add(new THREE.Group().add(new AxesHelper(0.5)));
|
||||
this.obj3d.add(new THREE.Group());
|
||||
this.obj3d.add(new THREE.Group());
|
||||
|
||||
|
@ -134,6 +134,7 @@ class Sketch {
|
|||
this.canvas.addEventListener('pointermove', this.onHover)
|
||||
this.store.dispatch({ type: 'set-active-sketch', sketch: this.obj3d.name })
|
||||
|
||||
|
||||
this.setDimLines()
|
||||
|
||||
window.sketcher = this
|
||||
|
|
|
@ -1,212 +0,0 @@
|
|||
|
||||
|
||||
attribute float size;
|
||||
attribute vec3 customColor;
|
||||
|
||||
varying vec3 vColor;
|
||||
|
||||
void main() {
|
||||
|
||||
vColor = customColor;
|
||||
|
||||
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
|
||||
|
||||
gl_PointSize = size * ( 300.0 / -mvPosition.z );
|
||||
|
||||
gl_Position = projectionMatrix * mvPosition;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
uniform vec3 color;
|
||||
uniform sampler2D pointTexture;
|
||||
|
||||
varying vec3 vColor;
|
||||
|
||||
void main() {
|
||||
|
||||
gl_FragColor = vec4( color * vColor, 1.0 );
|
||||
|
||||
gl_FragColor = gl_FragColor * texture2D( pointTexture, gl_PointCoord );
|
||||
|
||||
if ( gl_FragColor.a < ALPHATEST ) discard;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
import * as THREE from '../build/three.module.js';
|
||||
|
||||
import Stats from './jsm/libs/stats.module.js';
|
||||
|
||||
import { BufferGeometryUtils } from './jsm/utils/BufferGeometryUtils.js';
|
||||
|
||||
let renderer, scene, camera, stats;
|
||||
|
||||
let particles;
|
||||
|
||||
const PARTICLE_SIZE = 20;
|
||||
|
||||
let raycaster, intersects;
|
||||
let pointer, INTERSECTED;
|
||||
|
||||
init();
|
||||
animate();
|
||||
|
||||
function init() {
|
||||
|
||||
const container = document.getElementById( 'container' );
|
||||
|
||||
scene = new THREE.Scene();
|
||||
|
||||
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );
|
||||
camera.position.z = 250;
|
||||
|
||||
//
|
||||
|
||||
let boxGeometry = new THREE.BoxGeometry( 200, 200, 200, 16, 16, 16 );
|
||||
|
||||
// if normal and uv attributes are not removed, mergeVertices() can't consolidate indentical vertices with different normal/uv data
|
||||
|
||||
boxGeometry.deleteAttribute( 'normal' );
|
||||
boxGeometry.deleteAttribute( 'uv' );
|
||||
|
||||
boxGeometry = BufferGeometryUtils.mergeVertices( boxGeometry );
|
||||
|
||||
//
|
||||
|
||||
const positionAttribute = boxGeometry.getAttribute( 'position' );
|
||||
|
||||
const colors = [];
|
||||
const sizes = [];
|
||||
|
||||
const color = new THREE.Color();
|
||||
|
||||
for ( let i = 0, l = positionAttribute.count; i < l; i ++ ) {
|
||||
|
||||
color.setHSL( 0.01 + 0.1 * ( i / l ), 1.0, 0.5 );
|
||||
color.toArray( colors, i * 3 );
|
||||
|
||||
sizes[ i ] = PARTICLE_SIZE * 0.5;
|
||||
|
||||
}
|
||||
|
||||
const geometry = new THREE.BufferGeometry();
|
||||
geometry.setAttribute( 'position', positionAttribute );
|
||||
geometry.setAttribute( 'customColor', new THREE.Float32BufferAttribute( colors, 3 ) );
|
||||
geometry.setAttribute( 'size', new THREE.Float32BufferAttribute( sizes, 1 ) );
|
||||
|
||||
//
|
||||
|
||||
const material = new THREE.ShaderMaterial( {
|
||||
|
||||
uniforms: {
|
||||
color: { value: new THREE.Color( 0xffffff ) },
|
||||
pointTexture: { value: new THREE.TextureLoader().load( 'textures/sprites/disc.png' ) }
|
||||
},
|
||||
vertexShader: document.getElementById( 'vertexshader' ).textContent,
|
||||
fragmentShader: document.getElementById( 'fragmentshader' ).textContent,
|
||||
|
||||
alphaTest: 0.9
|
||||
|
||||
} );
|
||||
|
||||
//
|
||||
|
||||
particles = new THREE.Points( geometry, material );
|
||||
scene.add( particles );
|
||||
|
||||
//
|
||||
|
||||
renderer = new THREE.WebGLRenderer();
|
||||
renderer.setPixelRatio( window.devicePixelRatio );
|
||||
renderer.setSize( window.innerWidth, window.innerHeight );
|
||||
container.appendChild( renderer.domElement );
|
||||
|
||||
//
|
||||
|
||||
raycaster = new THREE.Raycaster();
|
||||
pointer = new THREE.Vector2();
|
||||
|
||||
//
|
||||
|
||||
stats = new Stats();
|
||||
container.appendChild( stats.dom );
|
||||
|
||||
//
|
||||
|
||||
window.addEventListener( 'resize', onWindowResize );
|
||||
document.addEventListener( 'pointermove', onPointerMove );
|
||||
|
||||
}
|
||||
|
||||
function onPointerMove( event ) {
|
||||
|
||||
pointer.x = ( event.clientX / window.innerWidth ) * 2 - 1;
|
||||
pointer.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
|
||||
|
||||
}
|
||||
|
||||
function onWindowResize() {
|
||||
|
||||
camera.aspect = window.innerWidth / window.innerHeight;
|
||||
camera.updateProjectionMatrix();
|
||||
|
||||
renderer.setSize( window.innerWidth, window.innerHeight );
|
||||
|
||||
}
|
||||
|
||||
function animate() {
|
||||
|
||||
requestAnimationFrame( animate );
|
||||
|
||||
render();
|
||||
stats.update();
|
||||
|
||||
}
|
||||
|
||||
function render() {
|
||||
|
||||
particles.rotation.x += 0.0005;
|
||||
particles.rotation.y += 0.001;
|
||||
|
||||
const geometry = particles.geometry;
|
||||
const attributes = geometry.attributes;
|
||||
|
||||
raycaster.setFromCamera( pointer, camera );
|
||||
|
||||
intersects = raycaster.intersectObject( particles );
|
||||
|
||||
if ( intersects.length > 0 ) {
|
||||
|
||||
if ( INTERSECTED != intersects[ 0 ].index ) {
|
||||
|
||||
attributes.size.array[ INTERSECTED ] = PARTICLE_SIZE;
|
||||
|
||||
INTERSECTED = intersects[ 0 ].index;
|
||||
|
||||
attributes.size.array[ INTERSECTED ] = PARTICLE_SIZE * 1.25;
|
||||
attributes.size.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
} else if ( INTERSECTED !== null ) {
|
||||
|
||||
attributes.size.array[ INTERSECTED ] = PARTICLE_SIZE;
|
||||
attributes.size.needsUpdate = true;
|
||||
INTERSECTED = null;
|
||||
|
||||
}
|
||||
|
||||
renderer.render( scene, camera );
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import * as THREE from 'three/src/Three';
|
||||
import { raycaster, color } from './shared';
|
||||
import { raycaster, color, hoverColor } from './shared';
|
||||
|
||||
export function onHover(e) {
|
||||
if (this.mode || e.buttons) return
|
||||
|
@ -38,19 +38,25 @@ export function onHover(e) {
|
|||
// hoverPts = raycaster.intersectObjects(this.obj3d.children)
|
||||
hoverPts = raycaster.intersectObjects(this.obj3d.children, true)
|
||||
|
||||
|
||||
// for (let i = 0; i < hoverPts.length; i++) {
|
||||
// const obj = hoverPts[i].object
|
||||
// if (obj.userData.type == "mesh" && obj.visible || obj.userData.type == "plane") {
|
||||
// idx.push(i)
|
||||
// }
|
||||
// }
|
||||
if (hoverPts.length) {
|
||||
// console.log(hoverPts)
|
||||
if (!idx.length) idx.push(0)
|
||||
for (let i = 0; i < hoverPts.length; i++) {
|
||||
const obj = hoverPts[i].object
|
||||
if (['point', 'plane'].includes(obj.userData.type)) {
|
||||
idx.push(i)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!idx.length) {
|
||||
const obj = hoverPts[0].object
|
||||
if (obj.userData.type == "mesh" && obj.visible) {
|
||||
idx.push(0)
|
||||
} else {
|
||||
idx.push(0)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -72,7 +78,7 @@ export function onHover(e) {
|
|||
|
||||
for (let x = 0; x < idx.length; x++) {
|
||||
const obj = hoverPts[idx[x]].object
|
||||
obj.material.color.set(color.hover)
|
||||
obj.material.color.set(hoverColor[obj.userData.type])
|
||||
this.hovered.push(obj)
|
||||
}
|
||||
|
||||
|
@ -81,7 +87,6 @@ export function onHover(e) {
|
|||
}
|
||||
} else { // no hovered object after filtering
|
||||
if (this.hovered.length) { // if previously something was hovered, then we need to clear it
|
||||
|
||||
for (let x = 0; x < this.hovered.length; x++) {
|
||||
const obj = this.hovered[x]
|
||||
// console.log(obj, 'here')
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
// import { LineSegments } from '../objects/LineSegments.js';
|
||||
// import { LineBasicMaterial } from '../materials/LineBasicMaterial.js';
|
||||
// import { Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
// import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
|
||||
import { LineSegments, MeshBasicMaterial, Float32BufferAttribute, BufferGeometry, Mesh, DoubleSide } from 'three/src/Three'
|
||||
|
||||
class Patch extends Mesh {
|
||||
|
||||
constructor(s = 1) {
|
||||
|
||||
const positions = [
|
||||
0.5 * s, 0, 0,
|
||||
0.3 * s, 0.08*s, 0,
|
||||
0.3 * s, -0.08*s, 0
|
||||
];
|
||||
|
||||
const geometry = new BufferGeometry();
|
||||
geometry.setAttribute('position', new Float32BufferAttribute(positions, 3));
|
||||
|
||||
|
||||
super(
|
||||
geometry,
|
||||
new MeshBasicMaterial({
|
||||
color: 0x0000ff,
|
||||
opacity: 0.2,
|
||||
side: DoubleSide,
|
||||
transparent: true,
|
||||
depthWrite: false,
|
||||
toneMapped: false
|
||||
})
|
||||
)
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { Patch };
|
|
@ -12,16 +12,30 @@ raycaster.params.Points.threshold = 0.6;
|
|||
|
||||
|
||||
const color = {
|
||||
hover: 0x00ff00,
|
||||
background:0xbbbbbb,
|
||||
lighting: 0xFFFFFF,
|
||||
emissive: 0x072534,
|
||||
|
||||
hover: 0x00ff00,
|
||||
point: 0x555555, //points
|
||||
line: 0x555555, //lines
|
||||
mesh: 0x156289, //mesh:
|
||||
dimension: 0x891d15, //
|
||||
plane: 0x891d15, //
|
||||
|
||||
plane: 0xdaacac, //
|
||||
planeBorder: 0xc59797, //
|
||||
}
|
||||
|
||||
const hoverColor = {
|
||||
hover: 0x00ff00,
|
||||
point: 0x00ff00, //points
|
||||
line: 0x00ff00, //lines
|
||||
mesh: 0x00ff00, //mesh:
|
||||
dimension: 0x00ff00, //
|
||||
plane: 0xff0000, //
|
||||
}
|
||||
|
||||
|
||||
const lineMaterial = new THREE.LineBasicMaterial({
|
||||
linewidth: 2,
|
||||
color: color.line,
|
||||
|
@ -129,4 +143,4 @@ async function awaitPts(...criteria) {
|
|||
|
||||
|
||||
|
||||
export { lineMaterial, pointMaterial, _vec2, _vec3, raycaster, color, ptObj, lineObj, awaitPts }
|
||||
export { lineMaterial, pointMaterial, _vec2, _vec3, raycaster, color, hoverColor, ptObj, lineObj, awaitPts }
|
|
@ -0,0 +1,34 @@
|
|||
// import { LineSegments } from '../objects/LineSegments.js';
|
||||
// import { LineBasicMaterial } from '../materials/LineBasicMaterial.js';
|
||||
// import { Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
// import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
|
||||
import { LineSegments, LineBasicMaterial, Float32BufferAttribute, BufferGeometry } from 'three/src/Three'
|
||||
|
||||
class AxesHelper extends LineSegments {
|
||||
|
||||
constructor(s = 1) {
|
||||
|
||||
const vertices = [
|
||||
0, 0, 0, 0.5 * s, 0, 0,
|
||||
0.5 * s, 0, 0, 0.35 * s, 0.08*s, 0,
|
||||
|
||||
0, 0, 0, 0, s, 0,
|
||||
];
|
||||
|
||||
|
||||
const geometry = new BufferGeometry();
|
||||
geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3));
|
||||
|
||||
const material = new LineBasicMaterial({ color: 0xff0000, toneMapped: false });
|
||||
|
||||
super(geometry, material);
|
||||
|
||||
// this.type = 'AxesHelper';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { AxesHelper };
|
11
todo.txt
11
todo.txt
|
@ -1,10 +1,16 @@
|
|||
fix css on design tree (a lot of work) \
|
||||
clear dim on exit exit sketch / rehydrate when back or after loading \\\ done
|
||||
|
||||
boolean flesh out refresh / replace mesh / delete mesh
|
||||
|
||||
|
||||
- select sketch for extrusion
|
||||
reattaching sketch
|
||||
- need to auto hide ( consume) when new boolean created \\
|
||||
- create derived part using relationship as name \\ done
|
||||
- sensible default names, like extrude 1, sketch 1, leverage react for this
|
||||
|
||||
|
||||
boolean flesh out refresh / replace mesh / delete mesh
|
||||
- create derived part using relationship as name \\ done
|
||||
- hidden bodies messes up hover highlight \\ fixed
|
||||
- add for union and intersect
|
||||
- auto update
|
||||
|
@ -17,7 +23,6 @@ fix extrusion loop find
|
|||
|
||||
dimension to origin
|
||||
|
||||
reattaching sketch
|
||||
file save
|
||||
stl export
|
||||
|
||||
|
|
Loading…
Reference in New Issue