diff --git a/web/app/3d/ctrl.js b/web/app/3d/ctrl.js
index 49f4f986..a9b6ea03 100644
--- a/web/app/3d/ctrl.js
+++ b/web/app/3d/ctrl.js
@@ -2,6 +2,27 @@
TCAD.UI = function(app) {
this.app = app;
this.viewer = app.viewer;
+
+ var box = new TCAD.toolkit.Box();
+ var propFolder = new TCAD.toolkit.Folder("Solid's Properties");
+ var cameraFolder = new TCAD.toolkit.Folder("Camera");
+ var objectsFolder = new TCAD.toolkit.Folder("Objects");
+ var modificationsFolder = new TCAD.toolkit.Folder("Modifications");
+ TCAD.toolkit.add(box, propFolder);
+ TCAD.toolkit.add(propFolder, new TCAD.toolkit.Button("Extrude"));
+ TCAD.toolkit.add(propFolder, new TCAD.toolkit.Button("Cut"));
+ TCAD.toolkit.add(propFolder, new TCAD.toolkit.Button("Edit"));
+ TCAD.toolkit.add(propFolder, new TCAD.toolkit.Button("Refresh Sketches"));
+ TCAD.toolkit.add(propFolder, new TCAD.toolkit.Text("Message"));
+ TCAD.toolkit.add(box, cameraFolder);
+ TCAD.toolkit.add(cameraFolder, new TCAD.toolkit.Number("x"));
+ TCAD.toolkit.add(cameraFolder, new TCAD.toolkit.Number("y"));
+ TCAD.toolkit.add(cameraFolder, new TCAD.toolkit.Number("z"));
+ TCAD.toolkit.add(box, objectsFolder);
+ TCAD.toolkit.add(box, modificationsFolder);
+ this.modificationsTreeComp = new TCAD.toolkit.Tree();
+ TCAD.toolkit.add(cameraFolder, this.modificationsTreeComp);
+
this.dat = new dat.GUI();
var ui = this;
var gui = this.dat;
diff --git a/web/app/3d/main.js b/web/app/3d/main.js
index d527df48..06866b5b 100644
--- a/web/app/3d/main.js
+++ b/web/app/3d/main.js
@@ -156,10 +156,15 @@ TCAD.App.prototype.extrude = function() {
}
var polyFace = this.viewer.selectionMgr.selection[0];
var height = prompt("Height", "50");
-
+ if (!height) return;
+
var app = this;
- this.craft.modify(polyFace.solid, function() {
- return TCAD.craft.extrude(app, polyFace, polyFace.solid.polyFaces, height);
+ var solids = [polyFace.solid];
+ this.craft.modify({
+ type: 'PAD',
+ solids : solids,
+ face : polyFace,
+ height : height
});
};
@@ -170,12 +175,16 @@ TCAD.App.prototype.cut = function() {
}
var polyFace = this.viewer.selectionMgr.selection[0];
var depth = prompt("Depth", "50");
+ if (!depth) return;
var app = this;
- this.craft.modify(polyFace.solid, function() {
- return TCAD.craft.cut(app, polyFace, polyFace.solid.polyFaces, depth);
+ var solids = [polyFace.solid];
+ this.craft.modify({
+ type: 'CUT',
+ solids : solids,
+ face : polyFace,
+ depth : depth
});
-
};
TCAD.App.prototype.refreshSketches = function() {
diff --git a/web/app/engine.js b/web/app/engine.js
index 331ecfc9..66eb323f 100644
--- a/web/app/engine.js
+++ b/web/app/engine.js
@@ -107,6 +107,12 @@ TCAD.utils.fixCCW = function(path, normal) {
return path;
};
+TCAD.utils.addAll = function(arr, arrToAdd) {
+ for (var i = 0; i < arrToAdd.length; i++) {
+ arr.push(arrToAdd[i]);
+ }
+};
+
TCAD.TOLERANCE = 1E-6;
TCAD.utils.areEqual = function(v1, v2, tolerance) {
@@ -320,7 +326,7 @@ TCAD.geom.extrude = function(source, target) {
return poly;
};
-TCAD.geom.FACE_COUNTER = 0;
+TCAD.geom.SOLID_COUNTER = 0;
/** @constructor */
TCAD.Solid = function(polygons, material) {
@@ -329,6 +335,9 @@ TCAD.Solid = function(polygons, material) {
this.meshObject = new THREE.Mesh(this, material);
+ this.id = TCAD.geom.SOLID_COUNTER ++;
+ this.faceCounter = 0;
+
this.polyFaces = [];
var scope = this;
function pushVertices(vertices) {
@@ -423,7 +432,7 @@ TCAD.SketchFace = function(solid, poly) {
var proto = poly.__face;
poly.__face = this;
if (proto === undefined) {
- this.id = TCAD.geom.FACE_COUNTER++;
+ this.id = solid.id + ":" + (solid.faceCounter++);
this.sketchGeom = null;
} else {
this.id = proto.id;
diff --git a/web/app/ui/toolkit.js b/web/app/ui/toolkit.js
new file mode 100644
index 00000000..f79ba70a
--- /dev/null
+++ b/web/app/ui/toolkit.js
@@ -0,0 +1,62 @@
+TCAD.toolkit = {};
+
+TCAD.toolkit.add = function(parent, child) {
+ parent.content.append(child.root);
+};
+
+TCAD.toolkit.Box = function() {
+ this.root = this.content = $('
');
+ this.root.addClass('tc-box');
+ this.root.appendTo('body');
+};
+
+TCAD.toolkit.Folder = function(title) {
+ this.root = $('', {class: 'tc-folder'});
+ this.content = $('', {class: 'tc-scroll'});
+ this.root.append($('', {text: title, class: 'tc-row tc-title'}));
+ this.root.append(this.content);
+};
+
+TCAD.toolkit.Button = function(title) {
+ this.root = $('',
+ {class: 'tc-row tc-ctrl tc-ctrl-btn', text: title});
+};
+
+TCAD.toolkit.propLayout = function(root, name, valueEl) {
+ root.append($('', {class: 'tc-prop-name', text: name}))
+ .append($('', {class: 'tc-prop-value'})
+ .append(valueEl));
+};
+
+TCAD.toolkit.Number = function(name) {
+ this.root = $('', {class: 'tc-row tc-ctrl tc-ctrl-number'});
+ TCAD.toolkit.propLayout(this.root, name, $(''))
+};
+
+TCAD.toolkit.Text = function(name) {
+ this.root = $('', {class: 'tc-row tc-ctrl tc-ctrl-text'});
+ TCAD.toolkit.propLayout(this.root, name, $(''))
+};
+
+TCAD.toolkit.Tree = function() {
+ this.root = $('', {class: 'tc-tree'});
+};
+
+TCAD.toolkit.Tree.prototype.set = function(data) {
+ this.root.empty();
+ this._fill(this.root, data.children);
+};
+
+TCAD.toolkit.Tree.prototype._fill = function(parent, data) {
+ parent.append($('', {text : data.name}));
+ if (data.children !== undefined && data.children.length !== 0) {
+ var ul = $('');
+ parent.append(ul);
+ for (var i = 0; i < data.children.length; i++) {
+ var li = $('');
+ ul.append(li);
+ var child = data.children[i];
+ this._fill(li, child);
+ }
+ }
+};
diff --git a/web/app/workbench.js b/web/app/workbench.js
index 7eb19b10..4a532765 100644
--- a/web/app/workbench.js
+++ b/web/app/workbench.js
@@ -72,38 +72,6 @@ TCAD.workbench.serializeSolid = function(solid) {
return data;
};
-TCAD.workbench.applyHistory = function(history) {
-
- for (var hi = 0; hi < history.length; ++hi) {
- var mod = history[hi];
- switch (mod.operation) {
- }
-
- }
-};
-
-TCAD.workbench.Cut = function() {
-
- this.depth = null;
-
- this.load = function(data) {
- this.depth = data.depth;
- };
-
- this.save = function() {
- return {
- depth : this.depth
- };
- };
-
- this.apply = function(app, face, faces) {
- TCAD.craft.cut(app, face, faces, this.depth);
- };
-};
-
-TCAD.workbench.Cut.prototype.TYPE = 'CUT';
-
-
TCAD.craft = {};
TCAD.craft.getSketchedPolygons3D = function(app, face) {
@@ -142,16 +110,18 @@ TCAD.craft.getSketchedPolygons3D = function(app, face) {
return sketchedPolygons;
};
-TCAD.craft.extrude = function(app, face, faces, height) {
+TCAD.craft.extrude = function(app, request) {
+ var face = request.face;
var sketchedPolygons = TCAD.craft.getSketchedPolygons3D(app, face);
if (sketchedPolygons == null) return null;
- var newSolidFaces = [];
+ var faces = TCAD.craft.collectFaces(request.solids);
+
var normal = face.polygon.normal;
var toMeldWith = [];
for (var i = 0; i < sketchedPolygons.length; i++) {
- var extruded = TCAD.geom.extrude(sketchedPolygons[i], normal.multiply(height));
+ var extruded = TCAD.geom.extrude(sketchedPolygons[i], normal.multiply(request.height));
toMeldWith = toMeldWith.concat(TCAD.craft._makeFromPolygons(extruded));
}
var work = TCAD.craft._makeFromPolygons(faces.map(function(f){ return f.polygon }));
@@ -218,7 +188,7 @@ TCAD.craft._mergeCSGPolygons = function (__cgsPolygons, allPoints) {
vertices: cp.vertices.map(function (cv) {
return vec(cv.pos)
}),
- csgInfo : cp.shared.__tcad,
+ shared : cp.shared.__tcad,
normal: vec(cp.plane.normal),
w: cp.plane.w
};
@@ -450,7 +420,7 @@ TCAD.craft._mergeCSGPolygons = function (__cgsPolygons, allPoints) {
vertices : path,
normal : csgData.normal,
w : csgData.w,
- csgInfo : csgData.csgInfo
+ shared : csgData.shared
});
}
}
@@ -526,7 +496,10 @@ TCAD.craft._makeFromPolygons = function(polygons) {
}
var pid = poly.id;
var shared = new CSG.Polygon.Shared([pid, pid, pid, pid]);
- shared.__tcad = poly.csgInfo;
+ shared.__tcad = {
+ csgInfo : poly.csgInfo,
+ face : poly.__face
+ };
var refs = poly.triangulate();
for ( var i = 0; i < refs.length; ++ i ) {
var a = refs[i][0] + off;
@@ -628,7 +601,7 @@ TCAD.craft.reconstruct = function (cut) {
return {
vertices : path.vertices.map(function(v) {return tr.apply(v);}),
normal : path.normal,
- csgInfo : path.csgInfo
+ shared : path.shared
}
});
@@ -715,7 +688,10 @@ TCAD.craft.reconstruct = function (cut) {
var p = new TCAD.Polygon(path.vertices, path.holes.map(function (path) {
return path.vertices
}), path.normal);
- p.csgInfo = path.csgInfo;
+ if (path.shared !== undefined) {
+ p.csgInfo = path.shared.csgInfo;
+ p.__face = path.shared.face;
+ }
return p;
})
);
@@ -724,17 +700,25 @@ TCAD.craft.reconstruct = function (cut) {
return result;
};
-TCAD.craft.cut = function(app, face, faces, depth) {
+TCAD.craft.collectFaces = function(solids) {
+ var faces = [];
+ for (var i = 0; i < solids.length; i++) {
+ TCAD.utils.addAll(faces, solids[i].polyFaces);
+ }
+ return faces;
+};
+TCAD.craft.cut = function(app, request) {
+ var face = request.face;
var sketchedPolygons = TCAD.craft.getSketchedPolygons3D(app, face);
if (sketchedPolygons == null) return null;
- var newSolidFaces = [];
+ var faces = TCAD.craft.collectFaces(request.solids);
var normal = face.polygon.normal;
var cutter = [];
for (var i = 0; i < sketchedPolygons.length; i++) {
- var extruded = TCAD.geom.extrude(sketchedPolygons[i], normal.multiply( - depth));
+ var extruded = TCAD.geom.extrude(sketchedPolygons[i], normal.multiply( - request.depth));
cutter = cutter.concat(TCAD.craft._makeFromPolygons(extruded));
}
var work = TCAD.craft._makeFromPolygons(faces.map(function(f){ return f.polygon }));
@@ -754,15 +738,45 @@ TCAD.Craft = function(app) {
TCAD.Craft.prototype.current = function() {
return this.history[this.history.length - 1];
};
-
-TCAD.Craft.prototype.modify = function(solid, modification) {
- var faces = modification();
- if (faces == null) return;
- this.app.viewer.scene.remove( solid.meshObject );
- this.app.viewer.scene.add(TCAD.utils.createSolidMesh(faces));
+TCAD.craft.detach = function(request) {
+ var detachedConfig = {};
+ for (var prop in request) {
+ if (request.hasOwnProperty(prop)) {
+ var value = request[prop];
+ if (typeof(value) === 'object' && value.id !== undefined) {
+ detachedConfig[prop] = value.id;
+ } else {
+ detachedConfig[prop] = value;
+ }
+ }
+ }
+ return detachedConfig
+};
+
+TCAD.Craft.prototype.modify = function(request) {
+
+ var op = TCAD.craft.OPS[request.type];
+ if (!op) return;
+
+ var detachedRequest = TCAD.craft.detach(request);
+ var newFaces = op(this.app, request);
+
+ if (newFaces == null) return;
+ for (var i = 0; i < request.solids.length; i++) {
+ var solid = request.solids[i];
+ this.app.viewer.scene.remove( solid.meshObject );
+ }
+ this.app.viewer.scene.add(TCAD.utils.createSolidMesh(newFaces));
+ this.history.push(detachedRequest);
+ this.app.bus.notify('operation');
//REMOVE IT
this.app._refreshSketches();
this.app.viewer.render();
};
+
+TCAD.craft.OPS = {
+ CUT : TCAD.craft.cut,
+ PAD : TCAD.craft.extrude
+};
diff --git a/web/css/toolkit.css b/web/css/toolkit.css
new file mode 100644
index 00000000..a1b34807
--- /dev/null
+++ b/web/css/toolkit.css
@@ -0,0 +1,99 @@
+
+.tc-box {
+ position: absolute;
+ margin-left: 0; margin-top: 0;
+ top: 0; left: 0;
+ width : 250px; height: 300px;
+ background-color: #000;
+}
+
+.tc-row {
+ height: 27px;
+ line-height: 27px;
+ overflow: hidden;
+ padding: 0 4px 0 5px;
+ border-bottom: 1px solid #2c2c2c;
+}
+
+.tc-title {
+ padding-left: 16px;
+ background: black url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;
+ cursor: pointer;
+}
+
+.tc-folder {
+ color: #eee;
+ font: 11px 'Lucida Grande', sans-serif;
+ background-color: #1a1a1a;
+}
+
+.tc-ctrl {
+ border-left: 3px solid #e61d5f;
+}
+
+.tc-ctrl-btn {
+ border-left: 3px solid #e61d5f;
+ cursor: pointer;
+}
+
+.tc-ctrl-btn:hover {
+ background-color: #000;
+}
+
+.tc-prop-name {
+ cursor: default;
+ float: left;
+ clear: left;
+ width: 40%;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.tc-prop-value {
+ float: left;
+ width: 60%;
+}
+
+.tc-ctrl input[type=text] {
+ color: #2fa1d6;
+ background: #303030;
+ outline: none;
+ border: 0;
+ margin-top: 4px;
+ padding: 3px;
+ width: 100%;
+ float: right;
+}
+
+.tc-ctrl-text input[type=text] {
+ color:#1ed36f;
+}
+
+.tc-ctrl input[type=text]:focus {
+ color: #eee;
+}
+
+.tc-scroll {
+ overflow-y: auto;
+ overflow-x: hidden;
+}
+
+.tc-scroll::-webkit-scrollbar {
+ width: 2px;
+}
+
+.tc-scroll::-webkit-scrollbar-track {
+ background:#eee;
+ border: thin solid lightgray;
+ box-shadow: 0px 0px 3px #dfdfdf inset;
+ border-radius:10px;
+}
+.tc-scroll::-webkit-scrollbar-thumb {
+ background:#999;
+ border: thin solid gray;
+ border-radius:10px;
+}
+
+.tc-scroll::-webkit-scrollbar-thumb:hover {
+ background:#7d7d7d;
+}
diff --git a/web/index.html b/web/index.html
index 32d18711..ce488e0f 100644
--- a/web/index.html
+++ b/web/index.html
@@ -8,7 +8,10 @@
overflow: hidden;
}
+
+
+
@@ -24,6 +27,7 @@
+