diff --git a/web/app/3d/ctrl.js b/web/app/3d/ctrl.js index 370cc0a7..7ae30d52 100644 --- a/web/app/3d/ctrl.js +++ b/web/app/3d/ctrl.js @@ -51,18 +51,23 @@ TCAD.UI = function(app) { var folder = new tk.Folder(isCut ? "Cut Options" : "Extrude Options"); tk.add(box, folder); var theValue = new tk.Number(isCut ? "Depth" : "Height", 50); + var scale = new tk.Number("Expansion", 1, 0.1); + var deflection = new tk.Number("Deflection", 0); var angle = new tk.Number("Angle", 0); var wizard = new TCAD.wizards.ExtrudeWizard(app.viewer, polygons); - theValue.input.on('t-change', function() { - var depthValue = $(this).val(); + function onChange() { + var depthValue = theValue.input.val(); + var scaleValue = scale.input.val(); var target = isCut ? normal.negate() : normal; target = target.multiply(depthValue); - wizard.update(target); + wizard.update(target, normal, scaleValue); app.viewer.render() - }); - theValue.input.trigger('t-change'); + } + theValue.input.on('t-change', onChange); + scale.input.on('t-change', onChange); + onChange(); tk.add(folder, theValue); - tk.add(folder, angle); + tk.add(folder, scale); function close() { box.close(); wizard.dispose(); diff --git a/web/app/3d/wizards/wizards.js b/web/app/3d/wizards/wizards.js index ebf6a452..b32c09e1 100644 --- a/web/app/3d/wizards/wizards.js +++ b/web/app/3d/wizards/wizards.js @@ -50,11 +50,11 @@ TCAD.wizards.ExtrudeWizard = function(viewer, polygons) { TCAD.wizards.ExtrudeWizard.prototype = Object.create( TCAD.wizards.OpWizard.prototype ); -TCAD.wizards.ExtrudeWizard.prototype.update = function(target) { +TCAD.wizards.ExtrudeWizard.prototype.update = function(target, normal, scale) { var linesCounter = 0; for (var i = 0; i < this.polygons.length; i++) { var poly = this.polygons[i]; - var lid = TCAD.geom.calculateExtrudedLid(poly, target, 1); + var lid = TCAD.geom.calculateExtrudedLid(poly, normal, target, scale); var p, q, n = poly.length; for (p = n - 1, q = 0; q < n; p = q++) { this.setupLine(linesCounter ++, poly[p], poly[q], TCAD.wizards.BASE_MATERIAL); diff --git a/web/app/engine.js b/web/app/engine.js index 46490878..725bb036 100644 --- a/web/app/engine.js +++ b/web/app/engine.js @@ -26,7 +26,7 @@ TCAD.utils.createBox = function(width) { var rot = TCAD.math.rotateMatrix(3/4, TCAD.math.AXIS.Z, TCAD.math.ORIGIN); square.forEach(function(v) { rot._apply(v) } ); var normal = TCAD.geom.normalOfCCWSeq(square); - return TCAD.geom.extrude(square, normal.multiply(width), normal); + return TCAD.geom.extrude(square, normal.multiply(width), normal, 1); }; TCAD.utils.createCSGBox = function(width) { @@ -336,12 +336,63 @@ TCAD.geom.isCCW = function(path2D) { return TCAD.geom.area(path2D) >= 0; }; +TCAD.BBox = function() { + this.minX = Number.MAX_VALUE; + this.minY = Number.MAX_VALUE; + this.maxX = -Number.MAX_VALUE; + this.maxY = -Number.MAX_VALUE; + this.checkBounds = function(x, y) { + this.minX = Math.min(this.minX, x); + this.minY = Math.min(this.minY, y); + this.maxX = Math.max(this.maxX, x); + this.maxY = Math.max(this.maxY, y); + }; -TCAD.geom.calculateExtrudedLid = function(sourcePolygon, direction, lateralExpansionFactor) { + this.center = function() { + return new TCAD.Vector(this.minX + (this.maxX - this.minX) / 2, this.minY + (this.maxY - this.minY) / 2, 0) + }; +}; + +TCAD.geom.calculateExtrudedLid = function(sourcePolygon, normal, direction, expansionFactor, deflection, angle) { var lid = []; - for (var si = 0; si < sourcePolygon.length; ++si) { - lid[si] = sourcePolygon[si].plus(direction); + var length = sourcePolygon.length; + var work; + var si; + if (expansionFactor != 1) { + var source2d = []; + work = []; + + var _3dTr = new TCAD.Matrix().setBasis(TCAD.geom.someBasis2(new CSG.Vector3D(normal))); // use passed basis + var _2dTr = _3dTr.invert(); + var sourceBBox = new TCAD.BBox(); + var workBBox = new TCAD.BBox(); + for (si = 0; si < length; ++si) { + var sourcePoint = _2dTr.apply(sourcePolygon[si]); + source2d[si] = sourcePoint; + work[si] = sourcePoint.multiply(expansionFactor); + work[si].z = source2d[si].z = 0; + sourceBBox.checkBounds(sourcePoint.x, sourcePoint.y); + workBBox.checkBounds(work[si].x, work[si].y) + } + var alignVector = workBBox.center().minus(sourceBBox.center()); + var depth = normal.dot(sourcePolygon[0]); + for (si = 0; si < length; ++si) { + work[si] = work[si].minus(alignVector); + work[si].z = depth; + work[si] = _3dTr.apply(work[si]); + } + } else { + work = sourcePolygon; } + + if (deflection != 0) { + //var + } + + for (si = 0; si < length; ++si) { + lid[si] = work[si].plus(direction); + } + return lid; }; @@ -354,7 +405,7 @@ TCAD.geom.extrude = function(source, target, sourceNormal) { var negate = extrudeDistance < 0; var poly = [null, null]; - var lid = TCAD.geom.calculateExtrudedLid(source, target, 1); + var lid = TCAD.geom.calculateExtrudedLid(source, sourceNormal, target, 1); var bottom, top; if (negate) { diff --git a/web/app/ui/toolkit.js b/web/app/ui/toolkit.js index bfc319d8..8ceb7bce 100644 --- a/web/app/ui/toolkit.js +++ b/web/app/ui/toolkit.js @@ -38,10 +38,11 @@ TCAD.toolkit.propLayout = function(root, name, valueEl) { .append(valueEl)); }; -TCAD.toolkit.Number = function(name, initValue) { +TCAD.toolkit.Number = function(name, initValue, baseStep) { this.root = $('
', {class: 'tc-row tc-ctrl tc-ctrl-number'}); this.input = $(""); this.slide = false; + baseStep = baseStep || 1; var scope = this; var lastValue = null; function trigger() { @@ -68,7 +69,7 @@ TCAD.toolkit.Number = function(name, initValue) { } var val = $(this).val(); if (!val) val = 0; - var step = e.shiftKey ? 100 : 1; + var step = baseStep * (e.shiftKey ? 100 : 1); val = parseFloat(val) + (delta < 0 ? -step : step); $(this).val(val); e.preventDefault();