diff --git a/web/app/engine.js b/web/app/engine.js index b72433d1..cee628bf 100644 --- a/web/app/engine.js +++ b/web/app/engine.js @@ -15,12 +15,32 @@ TCAD.utils.createSquare = function(width) { return new TCAD.Polygon(shell); }; +TCAD.utils.csgVec = function(v) { + return new CSG.Vector3D(v.x, v.y, v.z); +}; + +TCAD.utils.vec = function(v) { + return new TCAD.Vector(v.x, v.y, v.z); +}; + TCAD.utils.createBox = function(width) { var square = TCAD.utils.createSquare(width); var rot = TCAD.math.rotateMatrix(3/4, TCAD.math.AXIS.Z, TCAD.math.ORIGIN); square.eachVertex(function(path, i) { rot._apply(path[i]) } ); var polygons = TCAD.geom.extrude(square, square.normal.multiply(width)); - return TCAD.utils.createSolidMesh(TCAD.utils.toCsgGroups(polygons)); + return polygons; +}; + +TCAD.utils.createCSGBox = function(width) { + var csg = CSG.fromPolygons(TCAD.utils.createBox(width).map(function (p) { + var vertices = []; + for (var vi = 0; vi < p.shell.length; vi++) { + var v = p.shell[vi]; + vertices.push(new CSG.Vertex(TCAD.utils.csgVec(v))); + } + return new CSG.Polygon(vertices, TCAD.utils.createShared(p.id)); + })); + return TCAD.utils.createSolidMesh(csg); }; TCAD.utils.toCsgGroups = function(polygons) { @@ -94,7 +114,7 @@ TCAD.utils.createLine = function (a, b, color) { return new THREE.Segment(geometry, material); }; -TCAD.utils.createSolidMesh = function(csgGroups) { +TCAD.utils.createSolidMesh = function(csg) { var material = new THREE.MeshPhongMaterial({ vertexColors: THREE.FaceColors, color: TCAD.view.FACE_COLOR, @@ -104,7 +124,7 @@ TCAD.utils.createSolidMesh = function(csgGroups) { polygonOffsetUnits : 1 }); - var geometry = new TCAD.Solid(csgGroups, material); + var geometry = new TCAD.Solid(csg, material); return geometry.meshObject; }; @@ -403,9 +423,35 @@ TCAD.CSGGroup.prototype.toCSGPolygons = function() { return csgPolygons; }; +TCAD.utils.groupCSG = function(csg) { + var csgPolygons = csg.toPolygons(); + var groups = {}; + for (var i = 0; i < csgPolygons.length; i++) { + var p = csgPolygons[i]; + var tag = p.shared.getTag(); + if (groups[tag] === undefined) { + groups[tag] = { + tag : tag, + polygons : [], + shared : p.shared, + plane : p.plane + }; + } + groups[tag].polygons.push(p); + } + return groups; +}; + +TCAD.utils.createShared = function(id) { + var shared = new CSG.Polygon.Shared([id, id, id, id]); + shared.__tcad = {}; + return shared; +}; + /** @constructor */ -TCAD.Solid = function(csgPolygonGroups, material) { +TCAD.Solid = function(csg, material) { THREE.Geometry.call( this ); + this.csg = csg; this.dynamic = true; //true by default this.meshObject = new THREE.Mesh(this, material); @@ -418,54 +464,40 @@ TCAD.Solid = function(csgPolygonGroups, material) { this.polyFaces = []; var scope = this; - function pushVertices(vertices) { - for ( var v = 0; v < vertices.length; ++ v ) { - scope.vertices.push( new THREE.Vector3( vertices[v].x, vertices[v].y, vertices[v].z ) ); - } - } + function threeV(v) {return new THREE.Vector3( v.x, v.y, v.z )} var off = 0; - for (var gIdx = 0; gIdx < csgPolygonGroups.length; ++ gIdx) { - var group = csgPolygonGroups[gIdx]; + var groups = TCAD.utils.groupCSG(csg); + for (var gIdx in groups) { + var group = groups[gIdx]; + if (group.shared.__tcad === undefined) group.shared.__tcad = {}; var polyFace = new TCAD.SketchFace(this, group); this.polyFaces.push(polyFace); - for (var p = 0; p < group.polygons.length; ++p) { var poly = group.polygons[p]; - try { - var faces = poly.triangulate(); - } catch (e) { - console.log(e); - continue; - } - pushVertices(poly.vertices); - - for (var i = 0; i < faces.length; ++i) { - - var a = faces[i][0] + off; - var b = faces[i][1] + off; - var c = faces[i][2] + off; - - var fNormal = TCAD.geom.normalOfCCWSeqTHREE([ - this.vertices[a], this.vertices[b], this.vertices[c]]); - - if (!TCAD.utils.vectorsEqual(fNormal, poly.normal)) { - console.log("ASSERT"); - var _a = a; - a = c; - c = _a; - } + var vLength = poly.vertices.length; + if (vLength < 3) continue; + var firstVertex = poly.vertices[0]; + this.vertices.push(threeV(firstVertex.pos)); + this.vertices.push(threeV(poly.vertices[1].pos)); + var normal = threeV(poly.plane.normal); + for (var i = 2; i < vLength; i++) { + this.vertices.push(threeV(poly.vertices[i].pos)); + var a = off; + var b = i - 1 + off; + var c = i + off; var face = new THREE.Face3(a, b, c); polyFace.faces.push(face); face.__TCAD_polyFace = polyFace; - face.normal = poly.normal.three(); + face.normal = normal; face.materialIndex = gIdx; this.faces.push(face); } off = this.vertices.length; } } + this.mergeVertices(); //this.makeWireframe(polygons); @@ -505,16 +537,15 @@ TCAD.Solid.prototype.makeWireframe = function(polygons) { /** @constructor */ TCAD.SketchFace = function(solid, csgGroup) { - var proto = csgGroup.__face; csgGroup.__face = this; - if (proto === undefined) { + this.sketchGeom = null; + if (csgGroup.shared.__tcad.faceId === undefined) { this.id = solid.tCadId + ":" + (solid.faceCounter++); - this.sketchGeom = null; } else { - this.id = proto.id; - this.sketchGeom = proto.sketchGeom; + this.id = csgGroup.shared.__tcad.faceId; } - + csgGroup.shared.__tcad.faceId = this.id; + this.solid = solid; this.csgGroup = csgGroup; this.faces = []; @@ -532,10 +563,17 @@ if (typeof THREE !== "undefined") { color: 0x2B3856, linewidth: 3}); } +TCAD.SketchFace.prototype.basis = function() { + var vec = TCAD.utils.vec; + return TCAD.geom.someBasis(this.csgGroup.polygons[0].vertices.map(function (v) { + return vec(v.pos) + }), vec(this.csgGroup.plane.normal)); +} + TCAD.SketchFace.prototype.syncSketches = function(geom) { var i; - var normal = this.csgGroup.normal; - var offVector = normal.multiply(0); // disable it. use polygon offset feature of material + var normal = this.csgGroup.plane.normal; + var offVector = normal.scale(0); // disable it. use polygon offset feature of material if (this.sketch3DGroup != null) { for (var i = this.sketch3DGroup.children.length - 1; i >= 0; --i) { @@ -546,9 +584,10 @@ TCAD.SketchFace.prototype.syncSketches = function(geom) { this.solid.meshObject.add(this.sketch3DGroup); } - var _3dTransformation = new TCAD.Matrix().setBasis(this.csgGroup.basis()); + var basis = this.basis(); + var _3dTransformation = new TCAD.Matrix().setBasis(basis); //we lost depth or z off in 2d sketch, calculate it again - var depth = normal.dot(this.csgGroup.polygons[0].vertices[0]); + var depth = this.csgGroup.plane.w; for (i = 0; i < geom.connections.length; ++i) { var l = geom.connections[i]; var lg = new THREE.Geometry(); diff --git a/web/app/workbench.js b/web/app/workbench.js index 5ef20eff..f6321c9d 100644 --- a/web/app/workbench.js +++ b/web/app/workbench.js @@ -90,9 +90,9 @@ TCAD.craft.getSketchedPolygons3D = function(app, face) { if (poly2D.shell.length < 3) continue; if (depth == null) { - var _3dTransformation = new TCAD.Matrix().setBasis(face.csgGroup.basis()); + var _3dTransformation = new TCAD.Matrix().setBasis(face.basis()); //we lost depth or z off in 2d sketch, calculate it again - depth = normal.dot(face.csgGroup.polygons[0].vertices[0]); + depth = face.csgGroup.plane.w; } var shell = []; @@ -494,11 +494,10 @@ TCAD.craft._makeFromPolygons = function(polygons) { Array.prototype.push.apply( points, poly.holes[h] ); } var pid = poly.id; - var shared = new CSG.Polygon.Shared([pid, pid, pid, pid]); - shared.__tcad = { - csgInfo : poly.csgInfo, - face : poly.__face - }; + var shared = TCAD.utils.createShared(pid); + shared.__tcad.csgInfo = poly.csgInfo; + //shared.__tcad.faceId = poly.__face.id; + var refs = poly.triangulate(); for ( var i = 0; i < refs.length; ++ i ) { var a = refs[i][0] + off; @@ -763,16 +762,10 @@ TCAD.craft.cut = function(app, request) { var sketchedPolygons = TCAD.craft.getSketchedPolygons3D(app, face); if (sketchedPolygons == null) return null; - //face.polygon.__face = undefined; - var work; - if (!!request.solids[0].__cached_csg) { - work = request.solids[0].__cached_csg; - } else { - var faces = TCAD.craft.collectFaces(request.solids); - work = CSG.fromPolygons(TCAD.craft.collectCSGPolygons(faces)); - } + //face.c.__face = undefined; + var work = request.solids[0].csg; - var normal = face.csgGroup.normal; + var normal = TCAD.utils.vec(face.csgGroup.plane.normal); var cutter = []; for (var i = 0; i < sketchedPolygons.length; i++) { var extruded = TCAD.geom.extrude(sketchedPolygons[i], normal.multiply( - request.depth)); @@ -782,8 +775,7 @@ TCAD.craft.cut = function(app, request) { var cut = work.subtract(CSG.fromPolygons(cutter)); - var solid = TCAD.utils.createSolidMesh(TCAD.craft.toGroups(cut.polygons)).geometry; - //solid.__cached_csg = cut; + var solid = TCAD.utils.createSolidMesh(cut).geometry; return solid; }; @@ -837,6 +829,6 @@ TCAD.craft.OPS = { CUT : TCAD.craft.cut, PAD : TCAD.craft.extrude, BOX : function(app, request) { - return TCAD.utils.createBox(request.size).geometry; + return TCAD.utils.createCSGBox(request.size).geometry; } };