diff --git a/web/app/ctrl.js b/web/app/ctrl.js
index 3a4422dc..766018ba 100644
--- a/web/app/ctrl.js
+++ b/web/app/ctrl.js
@@ -10,9 +10,8 @@ TCAD.UI = function(app) {
var actionsF = gui.addFolder('Add Object');
var actions = new TCAD.UI.Actions(this);
- actionsF.add(actions.tools, 'polygon');
- actionsF.add(actions.tools, 'line');
- actionsF.add(actions.tools, 'commit');
+ actionsF.add(actions.tools, 'extrude');
+ actionsF.add(actions.tools, 'cut');
actionsF.add(actions.tools, 'edit');
actionsF.open();
@@ -23,21 +22,18 @@ TCAD.UI = function(app) {
TCAD.UI.Actions = function(scope) {
this.tools = {
- polygon : function() {
- scope.viewer.toolMgr.tool = new TCAD.PolygonTool(scope.viewer.selectionMgr.selection[0], scope.viewer);
+
+ extrude : function() {
+ scope.app.extrude();
},
- line : function() {
- scope.viewer.toolMgr.tool = new TCAD.LineTool(scope.viewer.selectionMgr.selection[0]);
- },
-
- commit : function() {
- scope.viewer.toolMgr.commit();
+ cut : function() {
+
},
edit : function() {
scope.app.sketchFace();
}
- }
+ };
};
diff --git a/web/app/engine.js b/web/app/engine.js
index 626853d7..c0d48dc0 100644
--- a/web/app/engine.js
+++ b/web/app/engine.js
@@ -77,7 +77,7 @@ TCAD.utils.createLine = function (a, b, color) {
return new THREE.Segment(geometry, material);
};
-TCAD.utils.createSolid = function(faces) {
+TCAD.utils.createSolidMesh = function(faces) {
var geometry = new TCAD.Solid(faces);
geometry.dynamic = true; //true by default
var material = new THREE.MeshPhongMaterial({
@@ -85,7 +85,8 @@ TCAD.utils.createSolid = function(faces) {
color: '#B0C4DE',
shininess: 0
});
- return new THREE.Mesh( geometry, material );
+ geometry.meshObject = new THREE.Mesh(geometry, material);
+ return geometry.meshObject;
};
TCAD.utils.fixCCW = function(path, normal) {
@@ -122,6 +123,82 @@ TCAD.utils.equal = function(v1, v2) {
return TCAD.utils.areEqual(v1, v2, TCAD.TOLERANCE);
};
+TCAD.utils.sketchToPolygons = function(geom) {
+
+ var dict = {};
+ var points = {};
+ var lines = geom.lines;
+
+ function memDir(a, b) {
+ var dirs = dict[a];
+ if (!dirs) {
+ dirs = [];
+ dict[a] = dirs;
+ }
+ dirs.push(b);
+ }
+
+ for (var i = 0; i < lines.length; i++) {
+ var a = lines[i][0];
+ var b = lines[i][1];
+ points[a] = true;
+ points[b] = true;
+ memDir(a, b);
+ memDir(b, a);
+ }
+
+ var visited = {};
+ var polygons = [];
+
+ function ar_eq(arr1, arr2) {
+ return arr1 + "" === arr2 + "";
+ }
+
+ function go(p, poly, closePoints) {
+ var closePoint = null;
+ for (;;) {
+ var next = dict[p];
+ if (!!visited[p] || next.length == 0) {
+ break;
+ }
+ poly.push(p);
+ visited[p] = true;
+ p = next[0];
+
+ if (!!closePoints[p]) {
+ closePoint = p;
+ break;
+ }
+ if (next.length > 1) {
+ //ramification
+ for (var ni = 1; ni < next.length; ni++) {
+ var n = next[ni];
+ var _v = {};
+ _v[p] = true;
+ go(n, [p], _v);
+ }
+ closePoints[p] = true;
+ }
+ if (closePoint != null) {
+ var toCutOff = 0;
+ for (var i = 0; i < poly.length; i++) {
+ var p = poly[i];
+ if (ar_eq(p, closePoint)) {
+ toCutOff = i;
+ break;
+ }
+ }
+ poly.splice(0, toCutOff);
+ if (poly.length > 2) polygons.push(poly);
+ }
+ }
+ }
+
+ for (var p in points) {
+ go(p, [], [p]);
+ }
+ return polygons;
+};
TCAD.geom = {};
@@ -218,7 +295,7 @@ TCAD.Solid = function(polygons) {
for ( var h = 0; h < poly.holes; ++ h ) {
pushVertices(poly.holes[ h ]);
}
- var polyFace = new TCAD.SketchFace(poly);
+ var polyFace = new TCAD.SketchFace(this, poly);
this.polyFaces.push(polyFace);
for ( var i = 0; i < faces.length; ++ i ) {
@@ -252,12 +329,14 @@ TCAD.Solid = function(polygons) {
TCAD.Solid.prototype = Object.create( THREE.Geometry.prototype );
-TCAD.SketchFace = function(poly) {
+TCAD.SketchFace = function(solid, poly) {
this.id = TCAD.geom.FACE_COUNTER++;
+ this.solid = solid;
this.polygon = poly;
this.faces = [];
this.geom = null;
this.sketch3DGroup = null;
+ this.sketchGeom = null;
};
TCAD.SketchFace.prototype.SKETCH_MATERIAL = new THREE.LineBasicMaterial({
@@ -292,6 +371,8 @@ TCAD.SketchFace.prototype.syncSketches = function(geom) {
var line = new THREE.Segment(lg, this.SKETCH_MATERIAL);
this.sketch3DGroup.add(line);
}
+ this.sketchGeom = geom;
+ this.sketchGeom.depth = depth;
};
/**
diff --git a/web/app/main.js b/web/app/main.js
index 67f8aca6..0f71ed73 100644
--- a/web/app/main.js
+++ b/web/app/main.js
@@ -5,9 +5,10 @@ TCAD.App = function() {
this.id = "DEFAULT";
this.viewer = new TCAD.Viewer();
this.ui = new TCAD.UI(this);
+ this.craft = new TCAD.Craft(this);
- var box = TCAD.utils.createSolid(TCAD.utils.createBox(500));
+ var box = TCAD.utils.createSolidMesh(TCAD.utils.createBox(500));
this.viewer.scene.add( box );
for (var i = 0; i < box.geometry.polyFaces.length; i++) {
var sketchFace = box.geometry.polyFaces[i];
@@ -33,7 +34,7 @@ TCAD.App = function() {
var prefix = "TCAD.projects."+app.id+".sketch.";
if (evt.key.indexOf(prefix) < 0) return;
- sketchFaceId = evt.key.substring(prefix.length);
+ var sketchFaceId = evt.key.substring(prefix.length);
for (var oi = 0; oi < viewer.scene.children.length; ++oi) {
var obj = viewer.scene.children[oi];
@@ -77,3 +78,21 @@ TCAD.App.prototype.sketchFace = function() {
window.open("canvas.html#" + faceStorageKey.substring(14), "Edit Sketch", "height=900,width=1200");
};
+
+TCAD.App.prototype.extrude = function() {
+
+ if (this.viewer.selectionMgr.selection.length == 0) {
+ return;
+ }
+ var polyFace = this.viewer.selectionMgr.selection[0];
+ var height = prompt("Height", "50");
+
+ var app = this;
+ this.craft.modify(polyFace.solid, function() {
+ return TCAD.craft.extrude(app, polyFace, height);
+ });
+};
+
+TCAD.App.prototype.cut = function(face, depth) {
+
+};
diff --git a/web/app/viewer.js b/web/app/viewer.js
index dae9e04c..936cd081 100644
--- a/web/app/viewer.js
+++ b/web/app/viewer.js
@@ -229,7 +229,7 @@ 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)));
+ var solid = TCAD.utils.createSolidMesh(TCAD.geom.extrude(_2d, n.multiply(1.1)));
this.workArea.sketch.group.parent.add(solid);
};
@@ -268,6 +268,6 @@ TCAD.LineTool.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)));
+// var solid = TCAD.utils.createSolidMesh(TCAD.geom.extrude(_2d, n.multiply(1.1)));
// this.workArea.sketch.group.parent.add(solid);
};
diff --git a/web/app/workbench.js b/web/app/workbench.js
index f7879b8e..0ebcd0aa 100644
--- a/web/app/workbench.js
+++ b/web/app/workbench.js
@@ -7,6 +7,7 @@ TCAD.workbench.readSketchGeom = function(sketch) {
for (var i = 0; i < sketch.layers[l].length; ++i) {
var obj = sketch.layers[l][i];
if (obj.edge !== undefined) continue;
+ if (!!obj.aux) continue;
if (obj._class === 'TCAD.TWO.Segment') {
out.lines.push([
obj.points[0][1][1], obj.points[0][2][1], //x,y
@@ -19,4 +20,63 @@ TCAD.workbench.readSketchGeom = function(sketch) {
}
return out;
}
-};
\ No newline at end of file
+};
+
+TCAD.craft = {};
+
+TCAD.craft.extrude = function(app, face, height) {
+
+ var savedFace = localStorage.getItem(app.faceStorageKey(face.id));
+ if (savedFace == null) return;
+
+ var geom = TCAD.workbench.readSketchGeom(JSON.parse(savedFace));
+ var polygons2D = TCAD.utils.sketchToPolygons(geom);
+ var solid = face.solid;
+
+ var normal = face.polygon.normal;
+ var depth = null;
+ var sketchedPolygons = [];
+ for (var i = 0; i < polygons2D.length; i++) {
+ var poly2D = polygons2D[i];
+ if (poly2D.length < 3) continue;
+
+ if (depth == null) {
+ var _3dTransformation = new TCAD.Matrix().setBasis(TCAD.geom.someBasis(this.polygon.shell, normal));
+ //we lost depth or z off in 2d sketch, calculate it again
+ depth = normal.dot(face.polygon.shell[0]);
+ }
+
+ var shell = [];
+ for (var m = 0; m < poly2D.length; ++m) {
+ var a = _3dTransformation.apply(new TCAD.Vector(poly2D[m][0], poly2D[m][1], depth));
+ shell.push(a)
+ }
+ sketchedPolygons.push(new TCAD.Polygon(shell));
+ }
+ var newSolidFaces = [];
+ for (var i = 0; i < sketchedPolygons.length; i++) {
+ var extruded = TCAD.geom.extrude(sketchedPolygons[i], normal.multiply(height));
+ newSolidFaces = newSolidFaces.concat(newSolidFaces, extruded);
+ }
+
+ for (var i = 0; i < solid.polyFaces.length; i++) {
+ newSolidFaces.push(solid.polyFaces[i].polygon);
+ }
+ return newSolidFaces;
+};
+
+TCAD.Craft = function(app) {
+ this.app = app;
+ this.history = [];
+};
+
+TCAD.Craft.prototype.current = function() {
+ return this.history[this.history.length - 1];
+};
+
+TCAD.Craft.prototype.modify = function(solid, modification) {
+ var faces = modification();
+ this.app.viewer.scene.remove( solid.meshObject );
+ this.app.viewer.scene.add( TCAD.utils.createSolidMesh(faces) );
+ this.app.viewer.render();
+};
diff --git a/web/canvas.html b/web/canvas.html
index 07149274..f0f96509 100644
--- a/web/canvas.html
+++ b/web/canvas.html
@@ -31,6 +31,7 @@
+