add plane concept

This commit is contained in:
Val Erastov 2015-11-05 18:26:34 -08:00
parent 9e6ea50b5c
commit 69583959e2
9 changed files with 295 additions and 203 deletions

View file

@ -11,11 +11,12 @@ TCAD.UI = function(app) {
var cameraFolder = new tk.Folder("Camera");
var objectsFolder = new tk.Folder("Objects");
var modificationsFolder = new tk.Folder("Modifications");
var extrude, cut, edit, refreshSketches, showSketches, printSolids, printFace, printFaceId;
var extrude, cut, edit, addPlane, refreshSketches, showSketches, printSolids, printFace, printFaceId;
tk.add(mainBox, propFolder);
tk.add(propFolder, extrude = new tk.Button("Extrude"));
tk.add(propFolder, cut = new tk.Button("Cut"));
tk.add(propFolder, edit = new tk.Button("Edit"));
tk.add(propFolder, addPlane = new tk.Button("Add a Plane"));
tk.add(propFolder, refreshSketches = new tk.Button("Refresh Sketches"));
tk.add(propFolder, showSketches = new tk.CheckBox("Show Sketches", true));
tk.add(mainBox, debugFolder);
@ -111,6 +112,38 @@ TCAD.UI = function(app) {
extrude.root.click(cutExtrude(false));
edit.root.click(tk.methodRef(app, "sketchFace"));
refreshSketches.root.click(tk.methodRef(app, "refreshSketches"));
addPlane.root.click(function() {
var box = new tk.Box();
box.root.css({left : (mainBox.root.width() + 10) + 'px', top : 0});
var folder = new tk.Folder("Add a Plane");
tk.add(box, folder);
var choice = ['XY', 'XZ', 'ZY'];
var orientation = new tk.InlineRadio(choice, choice, 0);
var depth = new tk.Number("Depth", 0);
tk.add(folder, orientation);
tk.add(folder, depth);
var wizard = new TCAD.wizards.PlaneWizard(app.viewer);
function onChange() {
wizard.update(orientation.getValue(), depth.input.val());
}
function close() {
box.close();
wizard.dispose();
}
function ok() {
app.craft.modify({
type: 'PLANE',
solids : [],
params : wizard.operationParams
});
close();
}
orientation.root.find('input:radio').change(onChange);
depth.input.on('t-change', onChange);
onChange();
tk.add(folder, new tk.ButtonRow(["Cancel", "OK"], [close, ok]));
});
printSolids.root.click(function () {
app.viewer.scene.children.map(function(o) {
if (o.geometry instanceof TCAD.Solid) {

View file

@ -11,7 +11,9 @@ TCAD.App = function() {
this.ui = new TCAD.UI(this);
this.craft = new TCAD.Craft(this);
this.addBox();
if (this.id == '$scratch$') {
this.addBox();
}
this._refreshSketches();
this.viewer.render();
@ -52,22 +54,19 @@ TCAD.App = function() {
};
TCAD.App.prototype.findAllSolids = function() {
return this.viewer.scene.children
return this.viewer.workGroup.children
.filter(function(obj) {return !!obj.geometry && obj.geometry.tCadId !== undefined} )
.map(function(obj) {return obj.geometry} )
};
TCAD.App.prototype.findFace = function(faceId) {
var solidId = faceId.split(":")[0];
var children = this.viewer.scene.children;
for (var i = 0; i < children.length; i++) {
var obj = children[i];
if (!!obj.geometry && obj.geometry.tCadId !== undefined) {
for (var j = 0; j < obj.geometry.polyFaces.length; j++) {
var face = obj.geometry.polyFaces[j];
if (face.id == faceId) {
return face;
}
var solids = this.findAllSolids();
for (var i = 0; i < solids.length; i++) {
var solid = solids[i];
for (var j = 0; j < solid.polyFaces.length; j++) {
var face = solid.polyFaces[j];
if (face.id == faceId) {
return face;
}
}
}
@ -273,17 +272,16 @@ TCAD.App.prototype.refreshSketches = function() {
};
TCAD.App.prototype._refreshSketches = function() {
for (var oi = 0; oi < this.viewer.scene.children.length; ++oi) {
var obj = this.viewer.scene.children[oi];
if (obj.geometry !== undefined && obj.geometry.polyFaces !== undefined) {
for (var i = 0; i < obj.geometry.polyFaces.length; i++) {
var sketchFace = obj.geometry.polyFaces[i];
var faceStorageKey = this.faceStorageKey(sketchFace.id);
var savedFace = localStorage.getItem(faceStorageKey);
if (savedFace != null) {
var geom = TCAD.workbench.readSketchGeom(JSON.parse(savedFace));
sketchFace.syncSketches(geom);
}
var allSolids = this.findAllSolids();
for (var oi = 0; oi < allSolids.length; ++oi) {
var obj = allSolids[oi];
for (var i = 0; i < obj.polyFaces.length; i++) {
var sketchFace = obj.polyFaces[i];
var faceStorageKey = this.faceStorageKey(sketchFace.id);
var savedFace = localStorage.getItem(faceStorageKey);
if (savedFace != null) {
var geom = TCAD.workbench.readSketchGeom(JSON.parse(savedFace));
sketchFace.syncSketches(geom);
}
}
}

View file

@ -2,9 +2,9 @@ TCAD.DPR = (window.devicePixelRatio) ? window.devicePixelRatio : 1;
TCAD.view = {};
TCAD.view.setFaceColor = function(polyFace, color) {
for (var i = 0; i < polyFace.faces.length; ++i) {
var face = polyFace.faces[i];
TCAD.view.setFacesColor = function(faces, color) {
for (var i = 0; i < faces.length; ++i) {
var face = faces[i];
if (color == null) {
face.color.set(new THREE.Color());
} else {
@ -49,10 +49,6 @@ TCAD.Viewer = function(bus) {
}
window.addEventListener( 'resize', onWindowResize, false );
/**
* CONTROLS
**/
// controls = new THREE.OrbitControls( camera , renderer.domElement);
var trackballControls = new THREE.TrackballControls( camera , renderer.domElement);
@ -106,19 +102,10 @@ TCAD.Viewer = function(bus) {
updateTransformControls();
}
/**
* TOOLS
**/
this.toolMgr = new TCAD.ToolManager(this);
/**
* FACE SELECTING
**/
this.selectionMgr = new TCAD.FaceSelectionManager( 0xFAFAD2, 0xFF0000, null);
this.workGroup = new THREE.Object3D();
this.scene.add(this.workGroup);
this.selectionMgr = new TCAD.SelectionManager( this, 0xFAFAD2, 0xFF0000, null);
var viewer = this;
var raycaster = new THREE.Raycaster();
@ -129,32 +116,11 @@ TCAD.Viewer = function(bus) {
var mouse = new THREE.Vector3( x, y, 1 );
raycaster.setFromCamera( mouse, camera );
return raycaster.intersectObjects( scene.children );
return raycaster.intersectObjects( viewer.workGroup.children, true );
};
var scope = this;
function onClick(e) {
var intersects = scope.raycast(e);
if (intersects.length === 0) scope.transformControls.detach();
for (var ii = 0; ii < intersects.length; ii++) {
var pickResult = intersects[ii];
if (!pickResult.face) continue;
if (pickResult.face.__TCAD_polyFace !== undefined) {
var poly = pickResult.face.__TCAD_polyFace;
if (scope.selectionMgr.contains(poly)) {
scope.toolMgr.handleClick(poly, pickResult);
} else {
if (e.shiftKey) {
scope.transformControls.attach(pickResult.object);
} else {
scope.select(poly);
pickResult.object.geometry.colorsNeedUpdate = true;
}
}
}
render();
break;
}
viewer.selectionMgr.handlePick(e);
}
var mouseState = {
@ -162,20 +128,14 @@ TCAD.Viewer = function(bus) {
startY : 0
};
function onMove(e) {
};
renderer.domElement.addEventListener('mousemove', function(e){scope.toolMgr.handleMove(e)}, false);
renderer.domElement.addEventListener('mousedown',
renderer.domElement.addEventListener('mousedown',
function(e) {
mouseState.startX = e.clientX;
mouseState.startY = e.clientY;
renderer.domElement.addEventListener('mousemove', onMove, false);
}, false);
renderer.domElement.addEventListener('mouseup',
renderer.domElement.addEventListener('mouseup',
function(e) {
renderer.domElement.removeEventListener('mousemove', onMove);
var dx = Math.abs(mouseState.startX - e.clientX);
var dy = Math.abs(mouseState.startY - e.clientY);
var TOL = 1;
@ -194,139 +154,55 @@ TCAD.Viewer = function(bus) {
animate();
};
TCAD.Viewer.prototype.select = function(polyFace) {
this.selectionMgr.select(polyFace);
this.bus.notify('selection', polyFace);
};
TCAD.FaceSelectionManager = function(selectionColor, readOnlyColor, defaultColor) {
TCAD.SelectionManager = function(viewer, selectionColor, readOnlyColor, defaultColor) {
this.viewer = viewer;
this.selectionColor = selectionColor;
this.readOnlyColor = readOnlyColor;
this.defaultColor = defaultColor;
this.selection = [];
this.planeSelection = [];
};
TCAD.FaceSelectionManager.prototype.select = function(polyFace) {
TCAD.SelectionManager.prototype.handlePick = function(event) {
var pickResults = this.viewer.raycast(event);
for (var i = 0; i < pickResults.length; i++) {
var pickResult = pickResults[i];
if (!!pickResult.face && pickResult.face.__TCAD_polyFace !== undefined) {
var sketchFace = pickResult.face.__TCAD_polyFace;
if (!this.contains(sketchFace)) {
this.select(sketchFace);
pickResult.object.geometry.colorsNeedUpdate = true;
this.viewer.bus.notify('selection', sketchFace);
this.viewer.render();
break;
}
}
}
};
TCAD.SelectionManager.prototype.select = function(sketchFace) {
this.clear();
if (polyFace.curvedSurfaces !== null) {
for (var i = 0; i < polyFace.curvedSurfaces.length; i++) {
var face = polyFace.curvedSurfaces[i];
if (sketchFace.curvedSurfaces !== null) {
for (var i = 0; i < sketchFace.curvedSurfaces.length; i++) {
var face = sketchFace.curvedSurfaces[i];
this.selection.push(face);
TCAD.view.setFaceColor(face, this.readOnlyColor);
TCAD.view.setFacesColor(face.faces, this.readOnlyColor);
}
} else {
this.selection.push(polyFace);
TCAD.view.setFaceColor(polyFace, this.selectionColor);
this.selection.push(sketchFace);
TCAD.view.setFacesColor(sketchFace.faces, this.selectionColor);
}
};
TCAD.FaceSelectionManager.prototype.contains = function(polyFace) {
return this.selection.indexOf(polyFace) != -1;
TCAD.SelectionManager.prototype.contains = function(face) {
return this.selection.indexOf(face) != -1;
};
TCAD.FaceSelectionManager.prototype.clear = function() {
TCAD.SelectionManager.prototype.clear = function() {
for (var i = 0; i < this.selection.length; ++ i) {
TCAD.view.setFaceColor(this.selection[i], this.defaultColor);
TCAD.view.setFacesColor(this.selection[i].faces, this.defaultColor);
}
this.selection.length = 0;
};
TCAD.ToolManager = function(viewer) {
this.viewer = viewer;
this.tool = null;
};
TCAD.ToolManager.prototype.handleClick = 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.handleClick(face, pickResult);
};
TCAD.ToolManager.prototype.handleMove = function(event) {
if (this.tool == null) {
return;
}
this.tool.handleMove(event, this.viewer);
};
TCAD.ToolManager.prototype.commit = function() {
if (this.tool == null) {
return;
}
this.tool.commit();
this.viewer.render();
this.tool = null;
};
TCAD.PolygonTool = function(workArea, viewer) {
this.workArea = workArea;
this.viewer = viewer;
this.poly = {shell : [], holes : []};
};
TCAD.PolygonTool.prototype.handleClick = function(face, pickResult) {
this.poly.shell.push(new TCAD.Vector().setV(pickResult.point));
var point = TCAD.utils.createPoint(pickResult.point.x, pickResult.point.y, pickResult.point.z);
this.workArea.sketch.group.add(point);
};
TCAD.PolygonTool.prototype.handleMove = function(event, raycast) {
};
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.createSolidMesh(TCAD.geom.extrude(_2d, n.multiply(1.1)));
this.workArea.sketch.group.parent.add(solid);
};
TCAD.LineTool = function(workArea) {
this.workArea = workArea;
this.protoLine = null;
};
TCAD.LineTool.prototype.handleClick = function(face, pickResult) {
if (this.protoLine == null) {
this.protoLine = TCAD.utils.createLine(pickResult.point, pickResult.point, 0x0000ff);
this.workArea.sketch.group.add(this.protoLine);
} else {
}
};
TCAD.LineTool.prototype.handleMove = function(event, viewer) {
if (this.protoLine != null) {
var intersects = viewer.raycast(event);
if (intersects.length > 0 && intersects[0].face.__TCAD_polyFace == this.workArea) {
var p = intersects[0].point;
var vertices = this.protoLine.geometry.vertices;
vertices[vertices.length - 1].x = p.x;
vertices[vertices.length - 1].y = p.y;
vertices[vertices.length - 1].z = p.z;
this.protoLine.geometry.verticesNeedUpdate = true;
viewer.render();
}
}
};
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.createSolidMesh(TCAD.geom.extrude(_2d, n.multiply(1.1)));
// this.workArea.sketch.group.parent.add(solid);
};

View file

@ -81,3 +81,60 @@ TCAD.wizards.ExtrudeWizard.prototype.update = function(basis, normal, depth, sca
expansionFactor : scale
}
};
TCAD.wizards.PlaneWizard = function(viewer) {
this.previewGroup = new THREE.Object3D();
this.viewer = viewer;
viewer.scene.add(this.previewGroup);
this.previewGroup.add(this.plane = this.createPlane());
this.viewer.render();
this.operationParams = {
basis : TCAD.math.IDENTITY_BASIS,
depth : 0
};
};
TCAD.wizards.PlaneWizard.prototype.createPlane = function() {
var geometry = new THREE.PlaneGeometry(750,750,1,1,1);
var material = new THREE.MeshLambertMaterial( { color : TCAD.view.FACE_COLOR, transparent: true, opacity:0.5, side: THREE.DoubleSide });
var plane = new THREE.Mesh(geometry, material);
return plane;
};
TCAD.wizards.PlaneWizard.prototype.update = function(orientation, w) {
if (orientation === 'XY') {
this.plane.rotation.x = 0;
this.plane.rotation.y = 0;
this.plane.rotation.z = 0;
this.plane.position.x = 0;
this.plane.position.y = 0;
this.plane.position.z = w;
this.operationParams.basis = TCAD.math.IDENTITY_BASIS;
} else if (orientation === 'XZ') {
this.plane.rotation.x = Math.PI / 2;
this.plane.rotation.y = 0;
this.plane.rotation.z = 0;
this.plane.position.x = 0;
this.plane.position.y = w;
this.plane.position.z = 0;
this.operationParams.basis = [TCAD.math.AXIS.X, TCAD.math.AXIS.Z, TCAD.math.AXIS.Y];
} else if (orientation === 'ZY') {
this.plane.rotation.x = 0;
this.plane.rotation.y = Math.PI / 2;
this.plane.rotation.z = 0;
this.plane.position.x = w;
this.plane.position.y = 0;
this.plane.position.z = 0;
this.operationParams.basis = [TCAD.math.AXIS.Z, TCAD.math.AXIS.Y, TCAD.math.AXIS.X];
} else {
throw orientation + " isn't supported yet";
}
this.operationParams.depth = w;
this.viewer.render();
};
TCAD.wizards.PlaneWizard.prototype.dispose = function() {
this.viewer.scene.remove(this.previewGroup);
this.viewer.render();
};

View file

@ -105,20 +105,80 @@ TCAD.utils.createLine = function (a, b, color) {
return new THREE.Line(geometry, material);
};
TCAD.utils.createSolidMesh = function(csg) {
var material = new THREE.MeshPhongMaterial({
TCAD.utils.createSolidMaterial = function() {
return new THREE.MeshPhongMaterial({
vertexColors: THREE.FaceColors,
color: TCAD.view.FACE_COLOR,
shininess: 0,
polygonOffset : true,
polygonOffsetFactor : 4,
polygonOffsetUnits : 1
});
};
TCAD.utils.createSolidMesh = function(csg) {
var material = TCAD.utils.createSolidMaterial();
var geometry = new TCAD.Solid(csg, material);
return geometry.meshObject;
};
TCAD.utils.intercept = function(obj, methodName, aspect) {
var originFunc = obj[methodName];
obj[methodName] = function() {
var $this = this;
aspect(function() {originFunc.apply($this, arguments)}, arguments);
}
};
TCAD.utils.createPlane = function(basis, depth, boundingPolygon, shared) {
var tu = TCAD.utils;
boundingPolygon = boundingPolygon || TCAD.utils.createSquare(800);
shared = shared || tu.createShared();
var material = tu.createSolidMaterial();
material.transparent = true;
material.opacity = 0.5;
material.side = THREE.DoubleSide;
var tr = new TCAD.Matrix().setBasis(basis);
var shift = basis[2].multiply(depth);
tr.tx = shift.x;
tr.ty = shift.y;
tr.tz = shift.z;
var currentBounds = new TCAD.BBox();
var points = boundingPolygon.map(function(p) { currentBounds.checkBounds(p.x, p.y); return tr._apply(p); });
var polygon = new CSG.Polygon(points.map(function(p){return new CSG.Vertex(TCAD.utils.csgVec(p))}), shared);
var plane = new TCAD.Solid(CSG.fromPolygons([polygon]), material);
plane.wireframeGroup.visible = false;
plane.mergeable = false;
var sketchFace = plane.polyFaces[0];
tu.intercept(sketchFace, 'syncSketches', function(invocation, args) {
var geom = args[0];
invocation(geom);
var bbox = new TCAD.BBox();
var connections = geom.connections.concat(TCAD.utils.arrFlatten1L(geom.loops));
for (var i = 0; i < connections.length; ++i) {
var l = connections[i];
bbox.checkBounds(l.a.x, l.a.y);
bbox.checkBounds(l.b.x, l.b.y);
}
if (bbox.maxX > currentBounds.maxX || bbox.maxY > currentBounds.maxY || bbox.minX < currentBounds.minX || bbox.minY < currentBounds.minY) {
var parent = plane.meshObject.parent;
plane.vanish();
bbox.expand(20);
var newPlane = TCAD.utils.createPlane(basis, depth, bbox.toPolygon(), sketchFace.csgGroup.shared);
TCAD.SketchFace.prototype.syncSketches.call(newPlane.geometry.polyFaces[0], geom);
parent.add(newPlane);
}
});
return plane.meshObject;
};
TCAD.utils.fixCCW = function(path, normal) {
var _2DTransformation = new TCAD.Matrix().setBasis(TCAD.geom.someBasis(path, normal)).invert();
var path2D = [];
@ -354,6 +414,30 @@ TCAD.BBox = function() {
this.center = function() {
return new TCAD.Vector(this.minX + (this.maxX - this.minX) / 2, this.minY + (this.maxY - this.minY) / 2, 0)
};
this.width = function() {
return this.maxX - this.minX;
};
this.height = function() {
return this.maxY - this.minY;
};
this.expand = function(delta) {
this.minX -= delta;
this.minY -= delta;
this.maxX += delta;
this.maxY += delta;
};
this.toPolygon = function() {
return [
new TCAD.Vector(this.minX, this.minY, 0),
new TCAD.Vector(this.maxX, this.minY, 0),
new TCAD.Vector(this.maxX, this.maxY, 0),
new TCAD.Vector(this.minX, this.maxY, 0)
];
}
};
TCAD.geom.calculateExtrudedLid = function(sourcePolygon, normal, direction, expansionFactor) {
@ -523,6 +607,7 @@ TCAD.Solid = function(csg, material) {
this.polyFaces = [];
this.wires = TCAD.struct.hashTable.forEdge();
this.curvedSurfaces = {};
this.mergeable = true;
var scope = this;
function threeV(v) {return new THREE.Vector3( v.x, v.y, v.z )}
@ -571,6 +656,12 @@ if (typeof THREE !== "undefined") {
TCAD.Solid.prototype = Object.create( THREE.Geometry.prototype );
}
TCAD.Solid.prototype.vanish = function() {
this.meshObject.parent.remove( this.meshObject );
this.meshObject.material.dispose();
this.dispose();
};
TCAD.Solid.prototype.collectCurvedSurface = function(face) {
var derivedFrom = TCAD.utils.getDerivedFrom(face.csgGroup.shared);
if (derivedFrom === null || derivedFrom._class !== "TCAD.TWO.Arc" && derivedFrom._class !== "TCAD.TWO.Circle" ) return;

View file

@ -45,7 +45,9 @@ TCAD.math.AXIS = {
X : new TCAD.Vector(1, 0, 0),
Y : new TCAD.Vector(0, 1, 0),
Z : new TCAD.Vector(0, 0, 1)
};
};
TCAD.math.IDENTITY_BASIS = [TCAD.math.AXIS.X, TCAD.math.AXIS.Y, TCAD.math.AXIS.Z];
TCAD.math.rotateMatrix = function(angle, axis, pivot) {
var sin = Math.sin(angle);

View file

@ -34,13 +34,37 @@ TCAD.toolkit.Button = function(title) {
TCAD.toolkit.CheckBox = function(title, checked) {
this.root = $('<div/>',
{class: 'tc-row tc-ctrl tc-ctrl-btn'});
{class: 'tc-row tc-ctrl'});
this.root.append('<label><input type="checkbox">' + title + '</label>')
this.input = this.root.find("input");
this.input.prop('checked', !!checked);
console.log(this.input);
};
TCAD.toolkit.InlineRadio = function(choiceLabels, choiceValues, checkedIndex) {
var name = 'TCAD.toolkit.InlineRadio_' + (TCAD.toolkit.InlineRadio.COUNTER++)
this.root = $('<div/>',
{class: 'tc-row tc-ctrl tc-inline-radio'});
this.inputs = [];
for (var i = 0; i < choiceLabels.length; i++) {
var checked = checkedIndex === i ? "checked" : '';
var label = $('<label><input type="radio" name="' + name + '" value="' + choiceValues[i] + '">' + choiceLabels[i] + '</label>');
this.inputs.push(label.find("input"));
this.root.append(label);
}
this.inputs[checkedIndex].prop('checked', true);
};
TCAD.toolkit.InlineRadio.prototype.getValue = function() {
for (var i = 0; i < this.inputs.length; i++) {
if (this.inputs[i].prop('checked')) {
return this.inputs[i].attr('value');
}
}
return null;
};
TCAD.toolkit.InlineRadio.COUNTER = 0;
TCAD.toolkit.propLayout = function(root, name, valueEl) {
root.append($('<span/>', {class: 'tc-prop-name', text: name}))
.append($('<div/>', {class: 'tc-prop-value'})

View file

@ -146,7 +146,12 @@ TCAD.craft.extrude = function(app, request) {
toMeldWith = toMeldWith.concat(extruded);
}
var meld = request.solids[0].csg.union(CSG.fromPolygons(TCAD.craft._triangulateCSG(toMeldWith)));
var solid = request.solids[0];
var meld = CSG.fromPolygons(TCAD.craft._triangulateCSG(toMeldWith));
if (solid.mergeable) {
meld = solid.csg.union(meld);
}
face.csgGroup.shared.__tcad.faceId += '$';
return [TCAD.utils.createSolidMesh(meld).geometry];
@ -759,18 +764,17 @@ TCAD.Craft.prototype.modify = function(request) {
var op = TCAD.craft.OPS[request.type];
if (!op) return;
var detachedRequest = TCAD.craft.detach(request);
var newSolids = op(this.app, request);
if (newSolids == null) return;
var i;
for (i = 0; i < request.solids.length; i++) {
this.app.viewer.scene.remove( request.solids[i].meshObject );
request.solids[i].vanish();
}
for (i = 0; i < newSolids.length; i++) {
this.app.viewer.scene.add(newSolids[i].meshObject);
this.app.viewer.workGroup.add(newSolids[i].meshObject);
}
this.history.push(detachedRequest);
this.history.push(TCAD.craft.detach(request));
this.app.bus.notify('craft');
this.app.viewer.render();
@ -779,6 +783,9 @@ TCAD.Craft.prototype.modify = function(request) {
TCAD.craft.OPS = {
CUT : TCAD.craft.cut,
PAD : TCAD.craft.extrude,
PLANE : function(app, request) {
return [TCAD.utils.createPlane(request.params.basis, request.params.depth).geometry];
},
BOX : function(app, request) {
return [TCAD.utils.createCSGBox(request.size).geometry];
}

View file

@ -126,3 +126,7 @@
.tc-buttons-block {
text-align: right;
}
.tc-inline-radio label {
padding-right: 5px;
}