remove redux logger for production
parent
662ced6edd
commit
4a3c0bd1e4
Binary file not shown.
|
@ -0,0 +1,209 @@
|
|||
import {
|
||||
Vector3
|
||||
} from '../../../build/three.module.js';
|
||||
|
||||
/**
|
||||
* Usage:
|
||||
* var exporter = new STLExporter();
|
||||
*
|
||||
* // second argument is a list of options
|
||||
* var data = exporter.parse( mesh, { binary: true } );
|
||||
*
|
||||
*/
|
||||
|
||||
var STLExporter = function () {};
|
||||
|
||||
STLExporter.prototype = {
|
||||
|
||||
constructor: STLExporter,
|
||||
|
||||
parse: function ( scene, options ) {
|
||||
|
||||
if ( options === undefined ) options = {};
|
||||
|
||||
var binary = options.binary !== undefined ? options.binary : false;
|
||||
|
||||
//
|
||||
|
||||
var objects = [];
|
||||
var triangles = 0;
|
||||
|
||||
scene.traverse( function ( object ) {
|
||||
|
||||
if ( object.isMesh ) {
|
||||
|
||||
var geometry = object.geometry;
|
||||
|
||||
if ( geometry.isBufferGeometry !== true ) {
|
||||
|
||||
throw new Error( 'THREE.STLExporter: Geometry is not of type THREE.BufferGeometry.' );
|
||||
|
||||
}
|
||||
|
||||
var index = geometry.index;
|
||||
var positionAttribute = geometry.getAttribute( 'position' );
|
||||
|
||||
triangles += ( index !== null ) ? ( index.count / 3 ) : ( positionAttribute.count / 3 );
|
||||
|
||||
objects.push( {
|
||||
object3d: object,
|
||||
geometry: geometry
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
var output;
|
||||
var offset = 80; // skip header
|
||||
|
||||
if ( binary === true ) {
|
||||
|
||||
var bufferLength = triangles * 2 + triangles * 3 * 4 * 4 + 80 + 4;
|
||||
var arrayBuffer = new ArrayBuffer( bufferLength );
|
||||
output = new DataView( arrayBuffer );
|
||||
output.setUint32( offset, triangles, true ); offset += 4;
|
||||
|
||||
} else {
|
||||
|
||||
output = '';
|
||||
output += 'solid exported\n';
|
||||
|
||||
}
|
||||
|
||||
var vA = new Vector3();
|
||||
var vB = new Vector3();
|
||||
var vC = new Vector3();
|
||||
var cb = new Vector3();
|
||||
var ab = new Vector3();
|
||||
var normal = new Vector3();
|
||||
|
||||
for ( var i = 0, il = objects.length; i < il; i ++ ) {
|
||||
|
||||
var object = objects[ i ].object3d;
|
||||
var geometry = objects[ i ].geometry;
|
||||
|
||||
var index = geometry.index;
|
||||
var positionAttribute = geometry.getAttribute( 'position' );
|
||||
|
||||
if ( index !== null ) {
|
||||
|
||||
// indexed geometry
|
||||
|
||||
for ( var j = 0; j < index.count; j += 3 ) {
|
||||
|
||||
var a = index.getX( j + 0 );
|
||||
var b = index.getX( j + 1 );
|
||||
var c = index.getX( j + 2 );
|
||||
|
||||
writeFace( a, b, c, positionAttribute, object );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// non-indexed geometry
|
||||
|
||||
for ( var j = 0; j < positionAttribute.count; j += 3 ) {
|
||||
|
||||
var a = j + 0;
|
||||
var b = j + 1;
|
||||
var c = j + 2;
|
||||
|
||||
writeFace( a, b, c, positionAttribute, object );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( binary === false ) {
|
||||
|
||||
output += 'endsolid exported\n';
|
||||
|
||||
}
|
||||
|
||||
return output;
|
||||
|
||||
function writeFace( a, b, c, positionAttribute, object ) {
|
||||
|
||||
vA.fromBufferAttribute( positionAttribute, a );
|
||||
vB.fromBufferAttribute( positionAttribute, b );
|
||||
vC.fromBufferAttribute( positionAttribute, c );
|
||||
|
||||
if ( object.isSkinnedMesh === true ) {
|
||||
|
||||
object.boneTransform( a, vA );
|
||||
object.boneTransform( b, vB );
|
||||
object.boneTransform( c, vC );
|
||||
|
||||
}
|
||||
|
||||
vA.applyMatrix4( object.matrixWorld );
|
||||
vB.applyMatrix4( object.matrixWorld );
|
||||
vC.applyMatrix4( object.matrixWorld );
|
||||
|
||||
writeNormal( vA, vB, vC );
|
||||
|
||||
writeVertex( vA );
|
||||
writeVertex( vB );
|
||||
writeVertex( vC );
|
||||
|
||||
if ( binary === true ) {
|
||||
|
||||
output.setUint16( offset, 0, true ); offset += 2;
|
||||
|
||||
} else {
|
||||
|
||||
output += '\t\tendloop\n';
|
||||
output += '\tendfacet\n';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function writeNormal( vA, vB, vC ) {
|
||||
|
||||
cb.subVectors( vC, vB );
|
||||
ab.subVectors( vA, vB );
|
||||
cb.cross( ab ).normalize();
|
||||
|
||||
normal.copy( cb ).normalize();
|
||||
|
||||
if ( binary === true ) {
|
||||
|
||||
output.setFloat32( offset, normal.x, true ); offset += 4;
|
||||
output.setFloat32( offset, normal.y, true ); offset += 4;
|
||||
output.setFloat32( offset, normal.z, true ); offset += 4;
|
||||
|
||||
} else {
|
||||
|
||||
output += '\tfacet normal ' + normal.x + ' ' + normal.y + ' ' + normal.z + '\n';
|
||||
output += '\t\touter loop\n';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function writeVertex( vertex ) {
|
||||
|
||||
if ( binary === true ) {
|
||||
|
||||
output.setFloat32( offset, vertex.x, true ); offset += 4;
|
||||
output.setFloat32( offset, vertex.y, true ); offset += 4;
|
||||
output.setFloat32( offset, vertex.z, true ); offset += 4;
|
||||
|
||||
} else {
|
||||
|
||||
output += '\t\t\tvertex ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export { STLExporter };
|
|
@ -0,0 +1,209 @@
|
|||
import {
|
||||
Vector3
|
||||
} from '../node_modules/three/src/Three';
|
||||
|
||||
/**
|
||||
* Usage:
|
||||
* var exporter = new STLExporter();
|
||||
*
|
||||
* // second argument is a list of options
|
||||
* var data = exporter.parse( mesh, { binary: true } );
|
||||
*
|
||||
*/
|
||||
|
||||
var STLExporter = function () {};
|
||||
|
||||
STLExporter.prototype = {
|
||||
|
||||
constructor: STLExporter,
|
||||
|
||||
parse: function ( scene, options ) {
|
||||
|
||||
if ( options === undefined ) options = {};
|
||||
|
||||
var binary = options.binary !== undefined ? options.binary : false;
|
||||
|
||||
//
|
||||
|
||||
var objects = [];
|
||||
var triangles = 0;
|
||||
|
||||
scene.traverse( function ( object ) {
|
||||
|
||||
if ( object.isMesh ) {
|
||||
|
||||
var geometry = object.geometry;
|
||||
|
||||
if ( geometry.isBufferGeometry !== true ) {
|
||||
|
||||
throw new Error( 'THREE.STLExporter: Geometry is not of type THREE.BufferGeometry.' );
|
||||
|
||||
}
|
||||
|
||||
var index = geometry.index;
|
||||
var positionAttribute = geometry.getAttribute( 'position' );
|
||||
|
||||
triangles += ( index !== null ) ? ( index.count / 3 ) : ( positionAttribute.count / 3 );
|
||||
|
||||
objects.push( {
|
||||
object3d: object,
|
||||
geometry: geometry
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
var output;
|
||||
var offset = 80; // skip header
|
||||
|
||||
if ( binary === true ) {
|
||||
|
||||
var bufferLength = triangles * 2 + triangles * 3 * 4 * 4 + 80 + 4;
|
||||
var arrayBuffer = new ArrayBuffer( bufferLength );
|
||||
output = new DataView( arrayBuffer );
|
||||
output.setUint32( offset, triangles, true ); offset += 4;
|
||||
|
||||
} else {
|
||||
|
||||
output = '';
|
||||
output += 'solid exported\n';
|
||||
|
||||
}
|
||||
|
||||
var vA = new Vector3();
|
||||
var vB = new Vector3();
|
||||
var vC = new Vector3();
|
||||
var cb = new Vector3();
|
||||
var ab = new Vector3();
|
||||
var normal = new Vector3();
|
||||
|
||||
for ( var i = 0, il = objects.length; i < il; i ++ ) {
|
||||
|
||||
var object = objects[ i ].object3d;
|
||||
var geometry = objects[ i ].geometry;
|
||||
|
||||
var index = geometry.index;
|
||||
var positionAttribute = geometry.getAttribute( 'position' );
|
||||
|
||||
if ( index !== null ) {
|
||||
|
||||
// indexed geometry
|
||||
|
||||
for ( var j = 0; j < index.count; j += 3 ) {
|
||||
|
||||
var a = index.getX( j + 0 );
|
||||
var b = index.getX( j + 1 );
|
||||
var c = index.getX( j + 2 );
|
||||
|
||||
writeFace( a, b, c, positionAttribute, object );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// non-indexed geometry
|
||||
|
||||
for ( var j = 0; j < positionAttribute.count; j += 3 ) {
|
||||
|
||||
var a = j + 0;
|
||||
var b = j + 1;
|
||||
var c = j + 2;
|
||||
|
||||
writeFace( a, b, c, positionAttribute, object );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( binary === false ) {
|
||||
|
||||
output += 'endsolid exported\n';
|
||||
|
||||
}
|
||||
|
||||
return output;
|
||||
|
||||
function writeFace( a, b, c, positionAttribute, object ) {
|
||||
|
||||
vA.fromBufferAttribute( positionAttribute, a );
|
||||
vB.fromBufferAttribute( positionAttribute, b );
|
||||
vC.fromBufferAttribute( positionAttribute, c );
|
||||
|
||||
if ( object.isSkinnedMesh === true ) {
|
||||
|
||||
object.boneTransform( a, vA );
|
||||
object.boneTransform( b, vB );
|
||||
object.boneTransform( c, vC );
|
||||
|
||||
}
|
||||
|
||||
vA.applyMatrix4( object.matrixWorld );
|
||||
vB.applyMatrix4( object.matrixWorld );
|
||||
vC.applyMatrix4( object.matrixWorld );
|
||||
|
||||
writeNormal( vA, vB, vC );
|
||||
|
||||
writeVertex( vA );
|
||||
writeVertex( vB );
|
||||
writeVertex( vC );
|
||||
|
||||
if ( binary === true ) {
|
||||
|
||||
output.setUint16( offset, 0, true ); offset += 2;
|
||||
|
||||
} else {
|
||||
|
||||
output += '\t\tendloop\n';
|
||||
output += '\tendfacet\n';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function writeNormal( vA, vB, vC ) {
|
||||
|
||||
cb.subVectors( vC, vB );
|
||||
ab.subVectors( vA, vB );
|
||||
cb.cross( ab ).normalize();
|
||||
|
||||
normal.copy( cb ).normalize();
|
||||
|
||||
if ( binary === true ) {
|
||||
|
||||
output.setFloat32( offset, normal.x, true ); offset += 4;
|
||||
output.setFloat32( offset, normal.y, true ); offset += 4;
|
||||
output.setFloat32( offset, normal.z, true ); offset += 4;
|
||||
|
||||
} else {
|
||||
|
||||
output += '\tfacet normal ' + normal.x + ' ' + normal.y + ' ' + normal.z + '\n';
|
||||
output += '\t\touter loop\n';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function writeVertex( vertex ) {
|
||||
|
||||
if ( binary === true ) {
|
||||
|
||||
output.setFloat32( offset, vertex.x, true ); offset += 4;
|
||||
output.setFloat32( offset, vertex.y, true ); offset += 4;
|
||||
output.setFloat32( offset, vertex.z, true ); offset += 4;
|
||||
|
||||
} else {
|
||||
|
||||
output += '\t\t\tvertex ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export { STLExporter };
|
43
src/Scene.js
43
src/Scene.js
|
@ -1,22 +1,16 @@
|
|||
|
||||
|
||||
|
||||
import * as THREE from '../node_modules/three/src/Three';
|
||||
import { TrackballControls } from '../lib/trackball'
|
||||
import { Sketch } from './Sketch'
|
||||
import Stats from '../lib/stats.module.js';
|
||||
|
||||
import { Sketch } from './Sketch'
|
||||
import { extrude, flipBufferGeometryNormals } from './extrude'
|
||||
import { onHover, onPick, clearSelection } from './mouseEvents';
|
||||
import { _vec2, _vec3, color, awaitSelection, ptObj, setHover } from './shared'
|
||||
|
||||
import { AxesHelper } from './axes'
|
||||
|
||||
|
||||
import { TrackballControls } from '../lib/trackball'
|
||||
import CSG from "../lib/three-csg"
|
||||
|
||||
import { STLExporter } from '../node_modules/three/examples/jsm/exporters/STLExporter'
|
||||
|
||||
import { STLExporter } from '../lib/stl'
|
||||
import Stats from '../lib/stats.module.js';
|
||||
|
||||
|
||||
|
||||
|
@ -376,37 +370,34 @@ function render() {
|
|||
}
|
||||
|
||||
|
||||
async function addSketch() {
|
||||
function addSketch() {
|
||||
|
||||
let sketch;
|
||||
|
||||
const references = await this.awaitSelection({ selpoint: 3 }, { plane: 1 });
|
||||
|
||||
if (!references) return;
|
||||
|
||||
if (references[0].userData.type == 'plane') {
|
||||
sketch = new Sketch(this)
|
||||
sketch.obj3d.matrix = references[0].matrix
|
||||
sketch.plane.applyMatrix4(sketch.obj3d.matrix)
|
||||
sketch.obj3d.inverse = sketch.obj3d.matrix.clone().invert()
|
||||
this.obj3d.add(sketch.obj3d)
|
||||
} else {
|
||||
if (this.selected.length == 3 && this.selected.every(e=>e.userData.type == 'selpoint')) {
|
||||
sketch = new Sketch(this)
|
||||
this.obj3d.add(sketch.obj3d)
|
||||
sketch.align(
|
||||
...references.map(
|
||||
...this.selected.map(
|
||||
el => new THREE.Vector3(...el.geometry.attributes.position.array).applyMatrix4(el.matrixWorld)
|
||||
)
|
||||
)
|
||||
} else if (this.selected.length && this.selected[0].userData.type == 'plane') {
|
||||
sketch = new Sketch(this)
|
||||
sketch.obj3d.matrix = this.selected[0].matrix
|
||||
sketch.plane.applyMatrix4(sketch.obj3d.matrix)
|
||||
sketch.obj3d.inverse = sketch.obj3d.matrix.clone().invert()
|
||||
this.obj3d.add(sketch.obj3d)
|
||||
|
||||
} else {
|
||||
return
|
||||
}
|
||||
|
||||
this.newSketch = true
|
||||
|
||||
this.clearSelection()
|
||||
|
||||
sketch.obj3d.addEventListener('change', this.render);
|
||||
|
||||
return sketch
|
||||
|
||||
}
|
||||
|
||||
window.sc = new Scene(store)
|
||||
|
|
|
@ -5,7 +5,7 @@ import * as THREE from '../node_modules/three/src/Three';
|
|||
import { _vec2, _vec3, raycaster, awaitSelection, ptObj, setHover } from './shared'
|
||||
|
||||
import { drawOnClick1, drawOnClick2, drawPreClick2, drawOnClick3, drawPreClick3, drawClear, drawPoint } from './drawEvents'
|
||||
import { onHover, onDrag, onPick, onRelease, clearSelection} from './mouseEvents'
|
||||
import { onHover, onDrag, onPick, onRelease, clearSelection } from './mouseEvents'
|
||||
import { setCoincident, setOrdinate, setTangent } from './constraintEvents'
|
||||
import { get3PtArc } from './drawArc'
|
||||
import { replacer, reviver } from './utils'
|
||||
|
@ -197,6 +197,9 @@ class Sketch {
|
|||
this.obj3d.traverse(e => e.layers.disable(2))
|
||||
this.scene.axes.visible = false
|
||||
this.scene.activeSketch = null
|
||||
if (this.scene.newSketch) {
|
||||
this.scene.newSketch = false
|
||||
}
|
||||
|
||||
this.clearSelection()
|
||||
|
||||
|
@ -255,8 +258,11 @@ class Sketch {
|
|||
this.canvas.addEventListener('pointerdown', this.drawOnClick1, { once: true })
|
||||
break;
|
||||
case 'd':
|
||||
drawClear.call(this)
|
||||
this.drawDimension()
|
||||
if (this.mode != 'dimension') {
|
||||
drawClear.call(this)
|
||||
this.mode = "dimension"
|
||||
this.drawDimension()
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
drawClear.call(this)
|
||||
|
@ -284,6 +290,7 @@ class Sketch {
|
|||
console.log('undo would be nice')
|
||||
break;
|
||||
}
|
||||
// console.log('this mode:', this.mode)
|
||||
}
|
||||
|
||||
deleteSelected() {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
|
||||
|
||||
import { Vector2 } from 'three';
|
||||
import {
|
||||
Vector2
|
||||
} from '../node_modules/three/src/Three';
|
||||
import { ptObj, lineObj } from './shared'
|
||||
|
||||
const n = 30
|
||||
|
|
|
@ -138,7 +138,7 @@ export async function drawDimension() {
|
|||
|
||||
} else {
|
||||
|
||||
this.dimGroup.children.splice(this.dimGroup.length - 2, 2).forEach(
|
||||
this.dimGroup.children.splice(this.dimGroup.children.length - 2, 2).forEach(
|
||||
e => {
|
||||
e.geometry.dispose()
|
||||
e.material.dispose()
|
||||
|
@ -147,6 +147,10 @@ export async function drawDimension() {
|
|||
this.labelContainer.removeChild(this.labelContainer.lastChild);
|
||||
sc.render()
|
||||
}
|
||||
if (this.mode=="dimension") {
|
||||
this.drawDimension()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import { onDimMoveEnd } from './drawDimension'
|
|||
let ptLoc
|
||||
|
||||
export function onHover(e) {
|
||||
if (this.mode || e.buttons) return
|
||||
if (( this.mode && this.mode!='dimension') || e.buttons) return
|
||||
|
||||
raycaster.setFromCamera(
|
||||
new THREE.Vector2(
|
||||
|
@ -114,7 +114,7 @@ export function onHover(e) {
|
|||
|
||||
let draggedLabel;
|
||||
export function onPick(e) {
|
||||
if (this.mode || e.buttons != 1) return
|
||||
if (( this.mode && this.mode!='dimension') || e.buttons != 1) return
|
||||
// if (this.mode || e.buttons != 1 || e.ctrlKey || e.metaKey) return
|
||||
|
||||
if (this.hovered.length) {
|
||||
|
|
|
@ -57,6 +57,13 @@ body {
|
|||
hover:bg-gray-500 hover:text-gray-200;
|
||||
}
|
||||
|
||||
.active-btn {
|
||||
cursor: pointer;
|
||||
@apply fill-current
|
||||
bg-green-400 text-gray-200
|
||||
}
|
||||
|
||||
|
||||
|
||||
.btn-green {
|
||||
cursor: pointer;
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
|
||||
import ReactDOM from 'react-dom'
|
||||
import React, { } from 'react'
|
||||
import React from 'react'
|
||||
|
||||
import { createStore, applyMiddleware } from 'redux'
|
||||
import { Provider, useSelector } from 'react-redux'
|
||||
import { Provider } from 'react-redux'
|
||||
import { reducer } from './reducer'
|
||||
import logger from 'redux-logger'
|
||||
|
||||
|
@ -11,27 +10,19 @@ import { Tree } from './tree'
|
|||
import { NavBar } from './navBar'
|
||||
import { ToolTip } from './toolTip'
|
||||
|
||||
|
||||
import './app.css'
|
||||
|
||||
const preloadedState = {
|
||||
treeEntries: {
|
||||
byId: {},
|
||||
allIds: [],
|
||||
tree: {},
|
||||
order: {},
|
||||
visible: {},
|
||||
activeSketchId: ""
|
||||
},
|
||||
|
||||
|
||||
|
||||
let store
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
store = createStore(reducer)
|
||||
} else {
|
||||
const { logger } = require(`redux-logger`);
|
||||
store = createStore(reducer, {}, applyMiddleware(logger))
|
||||
}
|
||||
|
||||
// const store = createStore(reducer, preloadedState, applyMiddleware(logger))
|
||||
|
||||
|
||||
const store = createStore(reducer, {}, applyMiddleware(logger))
|
||||
// const store = createStore(reducer, sc.loadState(), applyMiddleware(logger))
|
||||
|
||||
|
||||
const App = ({ store }) => {
|
||||
return <Provider store={store}>
|
||||
<NavBar />
|
||||
|
|
|
@ -111,8 +111,12 @@ export const Dialog = () => {
|
|||
|| sc.activeSketch.idOnActivate != id
|
||||
|| sc.activeSketch.c_idOnActivate != sc.activeSketch.c_id
|
||||
) {
|
||||
dispatch({ type: "restore-sketch" })
|
||||
// dispatch({ type: 'set-modified', status: false })
|
||||
if (sc.newSketch) {
|
||||
dispatch({ type: 'delete-node', id: sc.activeSketch.obj3d.name })
|
||||
sc.sid -= 1
|
||||
} else {
|
||||
dispatch({ type: "restore-sketch" })
|
||||
}
|
||||
}
|
||||
|
||||
dispatch({ type: 'finish-sketch' })
|
||||
|
|
|
@ -15,16 +15,12 @@ var tzoffset = (new Date()).getTimezoneOffset() * 60000;
|
|||
|
||||
|
||||
export function STLExport(filename) {
|
||||
if (sc.selected[0] && sc.selected[0].userData.type == 'mesh') {
|
||||
|
||||
const result = STLexp.parse(sc.selected[0], { binary: true });
|
||||
const result = STLexp.parse(sc.selected[0], { binary: true });
|
||||
|
||||
const time = (new Date(Date.now() - tzoffset)).toISOString().slice(0, -5).replace(/:/g, '-');
|
||||
const time = (new Date(Date.now() - tzoffset)).toISOString().slice(0, -5).replace(/:/g, '-');
|
||||
|
||||
saveLegacy(new Blob([result], { type: 'model/stl' }), `${filename}_${time}.stl`);
|
||||
} else {
|
||||
alert('please select one body to export')
|
||||
}
|
||||
saveLegacy(new Blob([result], { type: 'model/stl' }), `${filename}_${time}.stl`);
|
||||
}
|
||||
|
||||
|
||||
|
@ -41,7 +37,6 @@ export async function saveFile(fileHandle, file, dispatch) {
|
|||
console.error(msg, ex);
|
||||
alert(msg);
|
||||
}
|
||||
// app.setFocus();
|
||||
};
|
||||
|
||||
export async function saveFileAs(file, dispatch) {
|
||||
|
@ -83,16 +78,11 @@ export async function saveFileAs(file, dispatch) {
|
|||
alert(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
// app.setFocus();
|
||||
};
|
||||
|
||||
|
||||
|
||||
export async function openFile(dispatch) {
|
||||
// if (!app.confirmDiscard()) {
|
||||
// return;
|
||||
// }
|
||||
let fileHandle
|
||||
|
||||
// If a fileHandle is provided, verify we have permission to read/write it,
|
||||
|
@ -143,7 +133,7 @@ export function confirmDiscard(modified) {
|
|||
|
||||
export async function verifyPermission(fileHandle) {
|
||||
const opts = {
|
||||
mode:'readwrite'
|
||||
mode: 'readwrite'
|
||||
};
|
||||
|
||||
// Check if we already have permission, if so, return true.
|
||||
|
|
|
@ -4,16 +4,13 @@ import React, { useEffect, useReducer } from 'react';
|
|||
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
|
||||
import { FaEdit } from 'react-icons/fa'
|
||||
import { FaEdit, FaLinkedin, FaGithub } from 'react-icons/fa'
|
||||
import { MdSave, MdFolder, MdInsertDriveFile } from 'react-icons/md'
|
||||
|
||||
import * as Icon from "./icons";
|
||||
import { Dialog } from './dialog'
|
||||
import { STLExport, saveFile, openFile, verifyPermission } from './fileHelpers'
|
||||
|
||||
|
||||
|
||||
|
||||
export const NavBar = () => {
|
||||
const dispatch = useDispatch()
|
||||
const sketchActive = useSelector(state => state.ui.sketchActive)
|
||||
|
@ -22,7 +19,10 @@ export const NavBar = () => {
|
|||
const modified = useSelector(state => state.ui.modified)
|
||||
|
||||
const boolOp = (code) => {
|
||||
if (sc.selected.length != 2 || !sc.selected.every(e => e.userData.type == 'mesh')) return
|
||||
if (sc.selected.length != 2 || !sc.selected.every(e => e.userData.type == 'mesh')) {
|
||||
alert('please first select two bodies for boolean operation')
|
||||
return
|
||||
}
|
||||
const [m1, m2] = sc.selected
|
||||
|
||||
const mesh = sc.boolOp(m1, m2, code)
|
||||
|
@ -46,8 +46,12 @@ export const NavBar = () => {
|
|||
forceUpdate()
|
||||
}
|
||||
|
||||
const addSketch = async () => {
|
||||
const sketch = await sc.addSketch()
|
||||
const addSketch = () => {
|
||||
const sketch = sc.addSketch()
|
||||
if (!sketch) {
|
||||
alert('please select a plane or 3 points to define sketch plane')
|
||||
return
|
||||
}
|
||||
|
||||
dispatch({ type: 'rx-sketch', obj: sketch })
|
||||
|
||||
|
@ -100,16 +104,16 @@ export const NavBar = () => {
|
|||
dispatch({ type: 'set-dialog', action: 'extrude', target: sc.activeSketch })
|
||||
|
||||
}, 'Extrude [e]'],
|
||||
[Icon.Dimension, () => sc.activeSketch.command('d'), 'Dimension [d]'],
|
||||
[Icon.Line, () => sc.activeSketch.command('l'), 'Line [l]'],
|
||||
[Icon.Arc, () => sc.activeSketch.command('a'), 'Arc [a]'],
|
||||
[Icon.Coincident, () => sc.activeSketch.command('c'), 'Coincident [c]'],
|
||||
[Icon.Vertical, () => sc.activeSketch.command('v'), 'Vertical [v]'],
|
||||
[Icon.Horizontal, () => sc.activeSketch.command('h'), 'Horizontal [h]'],
|
||||
[Icon.Tangent, () => sc.activeSketch.command('t'), 'Tangent [t]'],
|
||||
[Icon.Dimension, () => sc.activeSketch.command('d'), 'Dimension [D]'],
|
||||
[Icon.Line, () => sc.activeSketch.command('l'), 'Line [L]'],
|
||||
[Icon.Arc, () => sc.activeSketch.command('a'), 'Arc [A]'],
|
||||
[Icon.Coincident, () => sc.activeSketch.command('c'), 'Coincident [C]'],
|
||||
[Icon.Vertical, () => sc.activeSketch.command('v'), 'Vertical [V]'],
|
||||
[Icon.Horizontal, () => sc.activeSketch.command('h'), 'Horizontal [H]'],
|
||||
[Icon.Tangent, () => sc.activeSketch.command('t'), 'Tangent [T]'],
|
||||
[MdSave,
|
||||
async () => {
|
||||
if(await verifyPermission(fileHandle) === false) return
|
||||
if (await verifyPermission(fileHandle) === false) return
|
||||
sc.refreshNode(sc.activeSketch.obj3d.name, treeEntries)
|
||||
sc.activeSketch.clearSelection()
|
||||
saveFile(fileHandle, JSON.stringify([id, sc.sid, sc.mid, treeEntries]), dispatch)
|
||||
|
@ -121,9 +125,14 @@ export const NavBar = () => {
|
|||
|
||||
|
||||
const partModeButtons = [
|
||||
[FaEdit, addSketch, 'Sketch [s]'],
|
||||
[FaEdit, addSketch, 'Sketch'],
|
||||
[Icon.Extrude, () => {
|
||||
dispatch({ type: 'set-dialog', action: 'extrude', target: treeEntries.byId[sc.selected[0].name] })
|
||||
if (sc.selected[0] && treeEntries.byId[sc.selected[0].name].userData.type == 'sketch') {
|
||||
dispatch({ type: 'set-dialog', action: 'extrude', target: treeEntries.byId[sc.selected[0].name] })
|
||||
} else {
|
||||
alert('please select a sketch from the left pane extrude')
|
||||
}
|
||||
|
||||
}, 'Extrude'],
|
||||
|
||||
[Icon.Union, () => boolOp('u'), 'Union'],
|
||||
|
@ -147,9 +156,12 @@ export const NavBar = () => {
|
|||
)
|
||||
}, 'Open'],
|
||||
[Icon.Stl, () => {
|
||||
STLExport('box')
|
||||
},
|
||||
, 'Export STL'],
|
||||
if (sc.selected[0] && sc.selected[0].userData.type == 'mesh') {
|
||||
STLExport(fileHandle ? fileHandle.name.replace(/\.[^/.]+$/, "") : 'untitled')
|
||||
} else {
|
||||
alert('please first select one body to export')
|
||||
}
|
||||
}, 'Export to STL'],
|
||||
]
|
||||
|
||||
const [_, forceUpdate] = useReducer(x => x + 1, 0);
|
||||
|
@ -175,30 +187,16 @@ export const NavBar = () => {
|
|||
))
|
||||
}
|
||||
</div>
|
||||
<div className='w-auto h-full flex-1 items-center'>
|
||||
<div className='w-auto h-full flex-1 items-center flex justify-end'>
|
||||
<a href='https://github.com/twpride/threeCAD' className='h-full w=auto'>
|
||||
<FaGithub className="btn-green w-auto h-full p-3.5"></FaGithub>
|
||||
</a>
|
||||
<a href='https://www.linkedin.com/in/howard-hwang-b3000335' className='h-full w=auto'>
|
||||
<FaLinkedin className="btn-green w-auto h-full p-3.5"></FaLinkedin>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
// app.saveFile = async () => {
|
||||
// try {
|
||||
// if (!app.file.handle) {
|
||||
// return await app.saveFileAs();
|
||||
// }
|
||||
// gaEvent('FileAction', 'Save');
|
||||
// await writeFile(app.file.handle, app.getText());
|
||||
// app.setModified(false);
|
||||
// } catch (ex) {
|
||||
// gaEvent('Error', 'FileSave', ex.name);
|
||||
// const msg = 'Unable to save file';
|
||||
// console.error(msg, ex);
|
||||
// alert(msg);
|
||||
// }
|
||||
// app.setFocus();
|
||||
// };
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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-7 mx-1 border-0 focus:outline-none bg-transparent'>
|
||||
<div className='w-16 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) => (
|
||||
|
|
|
@ -128,6 +128,7 @@ async function awaitSelection(...criteria) {
|
|||
|
||||
references.push(pt)
|
||||
const type = pt.userData.type
|
||||
|
||||
if (counter[type]) {
|
||||
counter[type] += 1;
|
||||
} else {
|
||||
|
@ -144,7 +145,7 @@ async function awaitSelection(...criteria) {
|
|||
window.removeEventListener('keydown', onKey)
|
||||
}
|
||||
|
||||
console.log('fail')
|
||||
// console.log('fail')
|
||||
return null
|
||||
}
|
||||
|
||||
|
|
27
todo.txt
27
todo.txt
|
@ -35,48 +35,49 @@ dim tag delete //resolved
|
|||
auto update extrude // done
|
||||
extrude edit dialog // done
|
||||
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
|
||||
|
||||
-unable cancel out of new sketches //fixed seemingly
|
||||
-unable to delete arc // fixed seemingly
|
||||
|
||||
-sometimes unable to hit return and change dimensionk
|
||||
-unable to delete arc
|
||||
hover not clearing sometimes in sketch
|
||||
0.000 artifact
|
||||
lighting messed up
|
||||
|
||||
seperate scene from init logic only init cam and rendere
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
reattach sketch
|
||||
auto snap
|
||||
|
||||
vertical and horzontal baseline to dimension to / or just smart ordinate dir dimenensing
|
||||
highlight button to indicate active mode
|
||||
|
||||
|
||||
|
||||
add cancle soft button for line arc
|
||||
|
||||
|
||||
constraint labels,equal
|
||||
|
||||
add download button, different from save button
|
||||
parallel // need to add antoher button to feature ,or empty placeholder
|
||||
|
||||
|
||||
tree relation tool tip
|
||||
tree ent renaming
|
||||
vertical and horzontal baseline to dimension to
|
||||
|
||||
|
||||
|
||||
|
||||
set pieces
|
||||
|
||||
wasm data structure
|
||||
|
||||
hover state for sketch
|
||||
await selection
|
||||
3 point arc implementation
|
||||
|
||||
local file save and mark dirty
|
||||
saerch tree for loop finding // need dev effor
|
||||
|
||||
dep tree for biuidling design treee
|
||||
|
||||
|
||||
|
|
|
@ -174,8 +174,7 @@ int main(int argc, char *argv[])
|
|||
sys.failed = CheckMalloc(500 * sizeof(sys.failed[0]));
|
||||
sys.faileds = 500;
|
||||
|
||||
// Example2d(150.0);
|
||||
|
||||
printf("hello\n");
|
||||
// printf("hello\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
const { merge } = require('webpack-merge');
|
||||
|
||||
const common = require('./webpack.common.js');
|
||||
|
||||
const webpack = require('webpack')
|
||||
|
||||
module.exports = merge(common, {
|
||||
|
||||
mode: 'production',
|
||||
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
// 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
|
||||
'process.env.NODE_ENV': 'production'
|
||||
}),
|
||||
new webpack.IgnorePlugin(/redux-logger/)
|
||||
]
|
||||
});
|
Loading…
Reference in New Issue