mirror of
https://github.com/xibyte/jsketcher
synced 2026-01-03 06:14:34 +01:00
add plane concept
This commit is contained in:
parent
9e6ea50b5c
commit
69583959e2
9 changed files with 295 additions and 203 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
};
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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'})
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,3 +126,7 @@
|
|||
.tc-buttons-block {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.tc-inline-radio label {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue