mirror of
https://github.com/xibyte/jsketcher
synced 2026-01-06 15:54:39 +01:00
implement editing
This commit is contained in:
parent
ec6ff0e739
commit
6e28eb2ed5
5 changed files with 189 additions and 95 deletions
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
TCAD.UI = function() {
|
||||
TCAD.UI = function(viewer) {
|
||||
this.viewer = viewer;
|
||||
this.dat = new dat.GUI();
|
||||
var gui = this.dat;
|
||||
|
||||
|
|
@ -7,17 +8,24 @@ TCAD.UI = function() {
|
|||
gui.TEXT_OPEN = 'Open FFF';
|
||||
|
||||
var actionsF = gui.addFolder('Add Object');
|
||||
actionsF.add(this.actions.add, 'box');
|
||||
var actions = new TCAD.UI.Actions(this);
|
||||
actionsF.add(actions.tools, 'polygon');
|
||||
actionsF.add(actions.tools, 'commit');
|
||||
actionsF.open();
|
||||
|
||||
// var propsF = gui.addFolder('Properties');
|
||||
// propsF.add(object3DProto.position, 'x');
|
||||
}
|
||||
};
|
||||
|
||||
TCAD.UI.prototype.actions = {
|
||||
add : {
|
||||
box : function() {
|
||||
alert("got it!");
|
||||
TCAD.UI.Actions = function(scope) {
|
||||
|
||||
this.tools = {
|
||||
polygon : function() {
|
||||
scope.viewer.toolMgr.tool = new TCAD.PolygonTool(scope.viewer.selectionMgr.selection[0]);
|
||||
},
|
||||
|
||||
commit : function() {
|
||||
scope.viewer.toolMgr.commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -26,12 +26,35 @@ TCAD.utils.checkPolygon = function(poly) {
|
|||
}
|
||||
};
|
||||
|
||||
TCAD.utils.fixCCW = function(shell) {
|
||||
if (!TCAD.geom.isCCW(shell)) {
|
||||
shell = shell.slice(0);
|
||||
shell.reverse();
|
||||
TCAD.utils.createPoint = function() {
|
||||
var g = new THREE.PlaneGeometry(0.05, 0.05);
|
||||
var m = new THREE.MeshBasicMaterial({color: 0x0000ff, side: THREE.DoubleSide});
|
||||
return new THREE.Mesh(g, m);
|
||||
};
|
||||
|
||||
TCAD.utils.createSolid = function(faces) {
|
||||
var geometry = new TCAD.Solid(faces);
|
||||
geometry.dynamic = true; //true by default
|
||||
var material = new THREE.MeshPhongMaterial({
|
||||
vertexColors: THREE.FaceColors,
|
||||
color: '#B0C4DE',
|
||||
shininess: 0
|
||||
});
|
||||
return new THREE.Mesh( geometry, material );
|
||||
};
|
||||
|
||||
TCAD.utils.fixCCW = function(path, normal) {
|
||||
var _2DTransformation = new TCAD.Matrix().setBasis(TCAD.geom.someBasis(path, normal)).invert();
|
||||
var path2D = [];
|
||||
for (var i = 0; i < path.length; ++i) {
|
||||
path2D[i] = _2DTransformation.apply(path[i]);
|
||||
}
|
||||
return shell;
|
||||
|
||||
if (!TCAD.geom.isCCW(path2D)) {
|
||||
path = path.slice(0);
|
||||
path.reverse();
|
||||
}
|
||||
return path;
|
||||
};
|
||||
|
||||
TCAD.TOLERANCE = 0.000001;
|
||||
|
|
@ -55,6 +78,17 @@ TCAD.utils.equal = function(v1, v2) {
|
|||
};
|
||||
|
||||
TCAD.geom = {};
|
||||
|
||||
TCAD.geom.someBasis = function(twoPointsOnPlane, normal) {
|
||||
var a = twoPointsOnPlane[0];
|
||||
var b = twoPointsOnPlane[1];
|
||||
|
||||
var x = b.minus(a).normalize();
|
||||
var y = normal.cross(x).normalize();
|
||||
|
||||
return [x, y, normal];
|
||||
};
|
||||
|
||||
TCAD.geom.normalOfCCWSeq = function(ccwSequence) {
|
||||
var a = ccwSequence[0];
|
||||
var b = ccwSequence[1];
|
||||
|
|
@ -82,8 +116,8 @@ TCAD.geom.area = function (contour) {
|
|||
return a * 0.5;
|
||||
};
|
||||
|
||||
TCAD.geom.isCCW = function(vertices) {
|
||||
return TCAD.geom.area(vertices) >= 0;
|
||||
TCAD.geom.isCCW = function(path2D) {
|
||||
return TCAD.geom.area(path2D) >= 0;
|
||||
};
|
||||
|
||||
TCAD.geom.extrude = function(source, target) {
|
||||
|
|
@ -100,14 +134,16 @@ TCAD.geom.extrude = function(source, target) {
|
|||
|
||||
var lid = source.shift(target).flip();
|
||||
poly.push(lid);
|
||||
|
||||
var lidShell = lid.shell.slice(0);
|
||||
lidShell.reverse();
|
||||
|
||||
var n = source.shell.length;
|
||||
for ( var p = n - 1, i = 0; i < n; p = i ++ ) {
|
||||
var face = new TCAD.Polygon([
|
||||
source.shell[p],
|
||||
source.shell[i],
|
||||
lid.shell[i],
|
||||
lid.shell[p]
|
||||
source.shell[p],
|
||||
lidShell[p],
|
||||
lidShell[i]
|
||||
]);
|
||||
poly.push(face);
|
||||
}
|
||||
|
|
@ -134,7 +170,7 @@ TCAD.Solid = function(polygons) {
|
|||
for ( var h = 0; h < poly.holes; ++ h ) {
|
||||
pushVertices(poly.holes[ h ]);
|
||||
}
|
||||
var polyFace = {faces : [], polygon : poly};
|
||||
var polyFace = {faces : [], polygon : poly, sketch : null};
|
||||
|
||||
for ( var i = 0; i < faces.length; ++ i ) {
|
||||
|
||||
|
|
@ -183,7 +219,7 @@ TCAD.Polygon = function(shell, holes, normal) {
|
|||
if (normal === undefined) {
|
||||
normal = TCAD.geom.normalOfCCWSeq(shell);
|
||||
} else {
|
||||
shell = TCAD.utils.fixCCW(shell);
|
||||
shell = TCAD.utils.fixCCW(shell, normal);
|
||||
}
|
||||
|
||||
this.normal = normal;
|
||||
|
|
@ -191,16 +227,6 @@ TCAD.Polygon = function(shell, holes, normal) {
|
|||
this.holes = holes;
|
||||
};
|
||||
|
||||
TCAD.Polygon.prototype.someBasis = function() {
|
||||
var a = this.shell[0];
|
||||
var b = this.shell[1];
|
||||
|
||||
var x = b.minus(a).normalize();
|
||||
var y = this.normal.cross(x).normalize();
|
||||
|
||||
return [x, y, this.normal];
|
||||
};
|
||||
|
||||
TCAD.Polygon.prototype.reverse = function(triangle) {
|
||||
var first = triangle[0];
|
||||
triangle[0] = triangle[2];
|
||||
|
|
@ -230,7 +256,7 @@ TCAD.Polygon.prototype.shift = function(target) {
|
|||
|
||||
TCAD.Polygon.prototype.triangulate = function() {
|
||||
|
||||
var _3dTransformation = new TCAD.Matrix().setBasis(this.someBasis());
|
||||
var _3dTransformation = new TCAD.Matrix().setBasis(TCAD.geom.someBasis(this.shell, this.normal));
|
||||
var _2dTransformation = _3dTransformation.invert();
|
||||
|
||||
var i, h;
|
||||
|
|
@ -247,3 +273,8 @@ TCAD.Polygon.prototype.triangulate = function() {
|
|||
}
|
||||
return THREE.Shape.Utils.triangulateShape( shell, holes );
|
||||
};
|
||||
|
||||
|
||||
TCAD.Sketch = function() {
|
||||
this.group = new THREE.Object3D();
|
||||
};
|
||||
|
|
@ -3,6 +3,6 @@ TCAD = {};
|
|||
TCAD.App = function() {
|
||||
|
||||
this.viewer = new TCAD.Viewer();
|
||||
this.ui = new TCAD.UI();
|
||||
this.ui = new TCAD.UI(this.viewer);
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,12 +10,21 @@ TCAD.Vector.prototype.set = function(x, y, z) {
|
|||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
return this;
|
||||
};
|
||||
|
||||
TCAD.Vector.prototype.set3 = function(data) {
|
||||
this.x = data[0];
|
||||
this.y = data[1];
|
||||
this.z = data[2];
|
||||
return this;
|
||||
};
|
||||
|
||||
TCAD.Vector.prototype.setV = function(data) {
|
||||
this.x = data.x;
|
||||
this.y = data.y;
|
||||
this.z = data.z;
|
||||
return this;
|
||||
};
|
||||
|
||||
TCAD.Vector.prototype.multiply = function(factor) {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ TCAD.Viewer = function() {
|
|||
|
||||
var scene = new THREE.Scene();
|
||||
var camera = new THREE.PerspectiveCamera( 75, aspect(), 0.1, 1000 );
|
||||
camera.position.z = 5;
|
||||
|
||||
var light = new THREE.PointLight( 0xffffff);
|
||||
light.position.set( 10, 10, 10 );
|
||||
|
|
@ -25,7 +26,12 @@ TCAD.Viewer = function() {
|
|||
renderer.setClearColor(0x808080, 1);
|
||||
renderer.setSize( window.innerWidth, window.innerHeight );
|
||||
document.body.appendChild( renderer.domElement );
|
||||
|
||||
function render() {
|
||||
// console.log("render");
|
||||
light.position.set(camera.position.x, camera.position.y, camera.position.z);
|
||||
renderer.render(scene, camera);
|
||||
}
|
||||
this.render = render;
|
||||
|
||||
function onWindowResize() {
|
||||
camera.aspect = aspect();
|
||||
|
|
@ -37,56 +43,18 @@ TCAD.Viewer = function() {
|
|||
|
||||
|
||||
// var geometry = new THREE.BoxGeometry(1,1,1);
|
||||
|
||||
// var geometry = new TCAD.Solid([TCAD.utils.createSquare(1)]);
|
||||
var geometry = new TCAD.Solid(TCAD.utils.createBox(1));
|
||||
|
||||
|
||||
var material = new THREE.MeshPhongMaterial( new THREE.MeshPhongMaterial({
|
||||
|
||||
vertexColors: THREE.FaceColors,
|
||||
// light
|
||||
// specular: '#a9fcff',
|
||||
// intermediate
|
||||
color: '#B0C4DE',
|
||||
// dark
|
||||
// emissive: '#006063',
|
||||
shininess: 0
|
||||
}));
|
||||
// material = new THREE.MeshNormalMaterial( { shading: THREE.FlatShading, color: '#B0C4DE' } );
|
||||
// material = new THREE.MeshBasicMaterial( { color: 0x00ff00, wireframe : false, vertexColors: THREE.FaceColors } );
|
||||
|
||||
// var shader = THREE.ShaderLib['normal'];
|
||||
// material = new THREE.ShaderMaterial( {
|
||||
// uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
|
||||
// vertexShader: shader.vertexShader,
|
||||
// fragmentShader: shader.fragmentShader.replace(/gl_FragColor.+\n/, 'gl_FragColor = vec4( 0.5, opacity );')
|
||||
// });
|
||||
|
||||
|
||||
// material = new THREE.ShaderMaterial({
|
||||
// fragmentShader: "void main() { \n" +
|
||||
// "gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0); \n" +
|
||||
// "}"
|
||||
// });
|
||||
|
||||
|
||||
var cube = new THREE.Mesh( geometry, material );
|
||||
// cube.dynamic = true;
|
||||
scene.add( cube );
|
||||
|
||||
camera.position.z = 5;
|
||||
|
||||
cube.rotation.x += 1;
|
||||
cube.rotation.y += 1;
|
||||
|
||||
|
||||
var box = TCAD.utils.createSolid(TCAD.utils.createBox(1));
|
||||
scene.add( box );
|
||||
|
||||
|
||||
/**
|
||||
* CONTROLS
|
||||
**/
|
||||
|
||||
// controls = new THREE.OrbitControls( camera , renderer.domElement);
|
||||
controls = new THREE.TrackballControls( camera , renderer.domElement);
|
||||
var controls = new THREE.TrackballControls( camera , renderer.domElement);
|
||||
|
||||
// document.addEventListener( 'mousemove', function(){
|
||||
|
||||
|
|
@ -107,21 +75,25 @@ TCAD.Viewer = function() {
|
|||
controls.addEventListener( 'change', render );
|
||||
|
||||
|
||||
/**
|
||||
* TOOLS
|
||||
**/
|
||||
|
||||
this.toolMgr = new TCAD.ToolManager(this);
|
||||
|
||||
|
||||
/**
|
||||
* FACE SELECTING
|
||||
**/
|
||||
|
||||
|
||||
var selectionMgr = new TCAD.FaceSelectionManager( 0xFAFAD2, 0xB0C4DE)
|
||||
this.selectionMgr = new TCAD.FaceSelectionManager( 0xFAFAD2, 0xB0C4DE);
|
||||
|
||||
var projector = new THREE.Projector();
|
||||
var raycaster = new THREE.Raycaster();
|
||||
var mouse = new THREE.Vector3(0, 0, 0);
|
||||
|
||||
raycaster.ray.direction.set(0, -1, 0);
|
||||
var pickReq = { };
|
||||
|
||||
function pick(event) {
|
||||
this.raycast = function(event) {
|
||||
|
||||
var x = ( event.clientX / window.innerWidth ) * 2 - 1;
|
||||
var y = - ( event.clientY / window.innerHeight ) * 2 + 1;
|
||||
|
|
@ -130,24 +102,44 @@ TCAD.Viewer = function() {
|
|||
var ray = projector.pickingRay(mouse.clone(), camera);
|
||||
var intersects = ray.intersectObjects( scene.children );
|
||||
if (intersects.length > 0) {
|
||||
var picked = intersects[0];
|
||||
if (picked.face.__TCAD_polyFace !== undefined) {
|
||||
var poly = picked.face.__TCAD_polyFace;
|
||||
selectionMgr.select(poly);
|
||||
picked.object.geometry.colorsNeedUpdate = true;
|
||||
var pickResult = intersects[0];
|
||||
if (pickResult.face.__TCAD_polyFace !== undefined) {
|
||||
var poly = pickResult.face.__TCAD_polyFace;
|
||||
if (this.selectionMgr.contains(poly)) {
|
||||
this.toolMgr.handle(poly, pickResult);
|
||||
} else {
|
||||
this.selectionMgr.select(poly);
|
||||
pickResult.object.geometry.colorsNeedUpdate = true;
|
||||
}
|
||||
}
|
||||
render();
|
||||
}
|
||||
}
|
||||
renderer.domElement.addEventListener('mousedown', pick, false);
|
||||
};
|
||||
|
||||
var scope = this;
|
||||
|
||||
var mouseState = {
|
||||
moved : false
|
||||
};
|
||||
|
||||
|
||||
function render() {
|
||||
// console.log("render");
|
||||
light.position.set(camera.position.x, camera.position.y, camera.position.z);
|
||||
renderer.render(scene, camera);
|
||||
function onMove() {
|
||||
mouseState.moved = true;
|
||||
}
|
||||
|
||||
renderer.domElement.addEventListener('mousedown',
|
||||
function() {
|
||||
mouseState.moved = false;
|
||||
renderer.domElement.addEventListener('mousemove', onMove, false);
|
||||
}, false);
|
||||
|
||||
renderer.domElement.addEventListener('mouseup',
|
||||
function(e) {
|
||||
renderer.domElement.removeEventListener('mousemove', onMove);
|
||||
if (!mouseState.moved) {
|
||||
scope.raycast(e);
|
||||
}
|
||||
} , false);
|
||||
|
||||
function animate() {
|
||||
// console.log("animate");
|
||||
requestAnimationFrame( animate );
|
||||
|
|
@ -170,9 +162,63 @@ TCAD.FaceSelectionManager.prototype.select = function(polyFace) {
|
|||
TCAD.view.setFaceColor(polyFace, this.selectionColor);
|
||||
};
|
||||
|
||||
TCAD.FaceSelectionManager.prototype.contains = function(polyFace) {
|
||||
return this.selection.indexOf(polyFace) != -1;
|
||||
};
|
||||
|
||||
TCAD.FaceSelectionManager.prototype.clear = function() {
|
||||
for (var i = 0; i < this.selection.length; ++ i) {
|
||||
TCAD.view.setFaceColor(this.selection[i], this.defaultColor);
|
||||
}
|
||||
this.selection.length = 0;
|
||||
};
|
||||
};
|
||||
|
||||
TCAD.ToolManager = function(viewer) {
|
||||
this.viewer = viewer;
|
||||
this.tool = null;
|
||||
};
|
||||
|
||||
TCAD.ToolManager.prototype.handle = function(face, pickResult) {
|
||||
if (this.tool == null) {
|
||||
return;
|
||||
}
|
||||
if (this.tool.workArea != face) {
|
||||
return;
|
||||
}
|
||||
if (this.tool.workArea.sketch == null) {
|
||||
this.tool.workArea.sketch = new TCAD.Sketch();
|
||||
pickResult.object.parent.add(this.tool.workArea.sketch.group);
|
||||
}
|
||||
this.tool.handle(face, pickResult);
|
||||
};
|
||||
|
||||
TCAD.ToolManager.prototype.commit = function() {
|
||||
if (this.tool == null) {
|
||||
return;
|
||||
}
|
||||
this.tool.commit();
|
||||
this.viewer.render();
|
||||
};
|
||||
|
||||
TCAD.PolygonTool = function(workArea) {
|
||||
this.workArea = workArea;
|
||||
this.poly = {shell : [], holes : []};
|
||||
};
|
||||
|
||||
TCAD.PolygonTool.prototype.handle = function(face, pickResult) {
|
||||
this.poly.shell.push(new TCAD.Vector().setV(pickResult.point));
|
||||
var point = TCAD.utils.createPoint();
|
||||
point.position.x = pickResult.point.x;
|
||||
point.position.y = pickResult.point.y;
|
||||
point.position.z = pickResult.point.z;
|
||||
this.workArea.sketch.group.add(point);
|
||||
};
|
||||
|
||||
TCAD.PolygonTool.prototype.commit = function() {
|
||||
var n = this.workArea.polygon.normal;
|
||||
var _2d = new TCAD.Polygon(this.poly.shell, this.poly.holes, n);
|
||||
|
||||
var solid = TCAD.utils.createSolid(TCAD.geom.extrude(_2d, n.multiply(1.1)));
|
||||
this.workArea.sketch.group.parent.add(solid);
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue