mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-15 21:05:22 +01:00
extrude operation on top of BREP framework
This commit is contained in:
parent
2b0b408d73
commit
43780d3188
14 changed files with 72 additions and 53 deletions
|
|
@ -14,7 +14,7 @@ export const CUT = mergeInfo('CUT', {
|
|||
info: 'makes a cut based on 2D sketch'
|
||||
});
|
||||
|
||||
export const PAD = mergeInfo('PAD', {
|
||||
export const EXTRUDE = mergeInfo('EXTRUDE', {
|
||||
info: 'extrudes 2D sketch'
|
||||
});
|
||||
|
||||
|
|
@ -55,7 +55,7 @@ export const IMPORT_STL = mergeInfo('IMPORT_STL', {
|
|||
});
|
||||
|
||||
requiresFaceSelection(CUT, 1);
|
||||
requiresFaceSelection(PAD, 1);
|
||||
requiresFaceSelection(EXTRUDE, 1);
|
||||
requiresFaceSelection(REVOLVE, 1);
|
||||
|
||||
requiresSolidSelection(INTERSECTION, 2);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import {Matrix3, ORIGIN} from '../../../math/l3space'
|
||||
import {Matrix3, BasisForPlane, ORIGIN} from '../../../math/l3space'
|
||||
import * as math from '../../../math/math'
|
||||
import Vector from '../../../math/vector'
|
||||
import {Extruder} from '../../../brep/brep-builder'
|
||||
import {BREPValidator} from '../../../brep/brep-validator'
|
||||
import {subtract} from '../../../brep/operations/boolean'
|
||||
import {subtract, union} from '../../../brep/operations/boolean'
|
||||
import {Loop} from '../../../brep/topo/loop'
|
||||
import {Shell} from '../../../brep/topo/shell'
|
||||
import {ReadSketchFromFace} from './sketch-reader'
|
||||
|
|
@ -11,24 +11,25 @@ import {ReadSketchFromFace} from './sketch-reader'
|
|||
import {BREPSceneSolid} from '../../scene/brep-scene-object'
|
||||
|
||||
export function Extrude(app, params) {
|
||||
|
||||
return doOperation(app, params, false);
|
||||
}
|
||||
|
||||
export function Cut(app, params) {
|
||||
return doOperation(app, params, true);
|
||||
}
|
||||
|
||||
export function doOperation(app, params, cut) {
|
||||
const face = app.findFace(params.face);
|
||||
const solid = face.solid;
|
||||
|
||||
const sketch = ReadSketchFromFace(app, face);
|
||||
//for (let polygon of sketch) {
|
||||
// if (!Loop.isPolygonCCWOnSurface(polygon, face.brepFace.surface)) {
|
||||
// polygon.reverse();
|
||||
// }
|
||||
//}
|
||||
|
||||
const extruder = new ParametricExtruder(face, params);
|
||||
const cutter = combineCutters(sketch.map(s => extruder.extrude(s, face.brepFace.surface.normal))) ;
|
||||
BREPValidator.validateToConsole(cutter);
|
||||
const result = subtract(solid.shell, cutter);
|
||||
const extruder = new ParametricExtruder(params);
|
||||
let normal = face.brepFace.surface.normal;
|
||||
if (!cut) normal = normal.negate();
|
||||
const operand = combineShells(sketch.map(s => extruder.extrude(s, normal)));
|
||||
BREPValidator.validateToConsole(operand);
|
||||
|
||||
const op = cut ? subtract : union;
|
||||
const result = op(solid.shell, operand);
|
||||
for (let newFace of result.faces) {
|
||||
if (newFace.id == face.id) {
|
||||
newFace.id = undefined;
|
||||
|
|
@ -41,30 +42,29 @@ export function Cut(app, params) {
|
|||
}
|
||||
}
|
||||
|
||||
function combineCutters(cutters) {
|
||||
if (cutters.length == 1) {
|
||||
return cutters[0];
|
||||
function combineShells(shells) {
|
||||
if (shells.length == 1) {
|
||||
return shells[0];
|
||||
}
|
||||
const cutter = new Shell();
|
||||
cutters.forEach(c => c.faces.forEach(f => cutter.faces.push(f)));
|
||||
shells.forEach(c => c.faces.forEach(f => cutter.faces.push(f)));
|
||||
return cutter;
|
||||
}
|
||||
|
||||
export class ParametricExtruder extends Extruder {
|
||||
|
||||
constructor(face, params) {
|
||||
constructor(params) {
|
||||
super();
|
||||
this.face = face;
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
prepareLidCalculation(baseNormal, lidNormal) {
|
||||
let target;
|
||||
this.basis = BasisForPlane(baseNormal);
|
||||
if (this.params.rotation != 0) {
|
||||
const basis = this.face.basis();
|
||||
target = Matrix3.rotateMatrix(this.params.rotation * Math.PI / 180, basis[0], ORIGIN).apply(lidNormal);
|
||||
target = Matrix3.rotateMatrix(this.params.rotation * Math.PI / 180, this.basis[0], ORIGIN).apply(lidNormal);
|
||||
if (this.params.angle != 0) {
|
||||
target = Matrix3.rotateMatrix(this.params.angle * Math.PI / 180, basis[2], ORIGIN)._apply(target);
|
||||
target = Matrix3.rotateMatrix(this.params.angle * Math.PI / 180, this.basis[2], ORIGIN)._apply(target);
|
||||
}
|
||||
target._multiply(Math.abs(this.params.value));
|
||||
} else {
|
||||
|
|
@ -73,10 +73,11 @@ export class ParametricExtruder extends Extruder {
|
|||
this.target = target;
|
||||
}
|
||||
|
||||
calculateLid(basePoints) {
|
||||
calculateLid(basePoints, baseNormal, lidNormal) {
|
||||
if (this.params.prism != 1) {
|
||||
const scale = this.params.prism;
|
||||
const _3Dtr = this.face.brepFace.surface.get3DTransformation();
|
||||
|
||||
const _3Dtr = new Matrix3().setBasis(this.basis);
|
||||
const _2Dtr = _3Dtr.invert();
|
||||
const poly2d = basePoints.map(p => _2Dtr.apply(p));
|
||||
basePoints = math.polygonOffset(poly2d, scale).map(p => _3Dtr.apply(p));
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ export class CutWizard extends PreviewWizard {
|
|||
|
||||
export class ExtrudeWizard extends PreviewWizard {
|
||||
constructor(app, initialState) {
|
||||
super(app, 'EXTRUDE', METADATA, new ExtrudePreviewer(false), initialState)
|
||||
super(app, 'EXTRUDE', METADATA, initialState)
|
||||
}
|
||||
|
||||
createPreviewObject(app, params) {
|
||||
|
|
@ -48,7 +48,7 @@ export class ExtrudePreviewer extends SketchBasedPreviewer {
|
|||
}
|
||||
|
||||
createImpl(app, params, sketch, face) {
|
||||
const parametricExtruder = new ParametricExtruder(face, params);
|
||||
const parametricExtruder = new ParametricExtruder(params);
|
||||
|
||||
const surface = face.brepFace.surface;
|
||||
const baseNormal = this.inversed ? surface.normal : surface.normal.negate();
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ ExtrudeWizard.prototype.getParams = function() {
|
|||
|
||||
ExtrudeWizard.prototype.createRequest = function(done) {
|
||||
done({
|
||||
type : this.invert ? 'CUT' : 'PAD',
|
||||
type : this.invert ? 'CUT' : 'EXTRUDE',
|
||||
solids : [this.app.findSolidByCadId(this.face.solid.tCadId)],
|
||||
face : this.app.findFace(this.face.id),
|
||||
params : this.operationParams,
|
||||
|
|
|
|||
|
|
@ -793,7 +793,7 @@ function materialize(index, detachedConfig) {
|
|||
|
||||
export const MESH_OPERATIONS = {
|
||||
CUT : cut,
|
||||
PAD : extrude,
|
||||
EXTRUDE : extrude,
|
||||
REVOLVE : performRevolve,
|
||||
PLANE : function(app, request) {
|
||||
let basis, depth = request.params.depth;
|
||||
|
|
|
|||
|
|
@ -10,13 +10,11 @@ export const CUT = {
|
|||
action: (app, params) => Cut(app, params)
|
||||
};
|
||||
|
||||
export const PAD = {
|
||||
export const EXTRUDE = {
|
||||
icon: 'img/3d/extrude',
|
||||
label: 'Extrude',
|
||||
info: (p) => '(' + r(p.value) + ')',
|
||||
action: (app, request) => {
|
||||
|
||||
}
|
||||
action: (app, params) => Extrude(app, params)
|
||||
};
|
||||
|
||||
export const REVOLVE = {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ export const craft = {
|
|||
label: 'craft',
|
||||
cssIcons: ['magic'],
|
||||
info: 'set of available craft operations on a solid',
|
||||
actions: ['PAD', 'CUT', 'REVOLVE', 'SHELL']
|
||||
actions: ['EXTRUDE', 'CUT', 'REVOLVE', 'SHELL']
|
||||
};
|
||||
|
||||
export const primitives = {
|
||||
|
|
@ -29,7 +29,7 @@ export const main = {
|
|||
label: 'start',
|
||||
cssIcons: ['rocket'],
|
||||
info: 'common set of actions',
|
||||
actions: ['PAD', 'CUT', 'SHELL', '-', 'INTERSECTION', 'DIFFERENCE', 'UNION', '-', 'PLANE', 'BOX', 'SPHERE', '-',
|
||||
actions: ['EXTRUDE', 'CUT', 'SHELL', '-', 'INTERSECTION', 'DIFFERENCE', 'UNION', '-', 'PLANE', 'BOX', 'SPHERE', '-',
|
||||
'EditFace', '-', 'DeselectAll', 'RefreshSketches']
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ import '../../css/app3d.less'
|
|||
import * as BREPBuilder from '../brep/brep-builder'
|
||||
import * as BREPPrimitives from '../brep/brep-primitives'
|
||||
import * as BREPBool from '../brep/operations/boolean'
|
||||
import * as BREPMeshBool from './craft/mesh/mesh-boolean'
|
||||
import {BREPValidator} from '../brep/brep-validator'
|
||||
import {BREPSceneSolid} from './scene/brep-scene-object'
|
||||
import TPI from './tpi'
|
||||
|
|
@ -262,7 +261,7 @@ App.prototype.BREPMeshTestImpl = function() {
|
|||
//addToScene(box2);
|
||||
//addToScene(box3);
|
||||
|
||||
let result = BREPMeshBool.subtract(box1, box2);
|
||||
//let result = BREPMeshBool.subtract(box1, box2);
|
||||
//result = BREPBool.subtract(result, box3);
|
||||
//this.addShellOnScene(result);
|
||||
//addToScene(box1);
|
||||
|
|
@ -548,7 +547,7 @@ App.prototype.extrude = function() {
|
|||
var app = this;
|
||||
var solids = [polyFace.solid];
|
||||
this.craft.modify({
|
||||
type: 'PAD',
|
||||
type: 'EXTRUDE',
|
||||
solids : solids,
|
||||
face : polyFace,
|
||||
height : height
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
export function init() {
|
||||
localStorage.setItem("TCAD.projects.sample", '{"history":[{"type":"PLANE","solids":[],"params":{"basis":[[1,0,0],[0,0,1],[0,1,0]],"depth":"0"},"protoParams":["XZ","0"]},{"type":"PAD","solids":[0],"face":"0:0","params":{"target":[0,-50,0],"expansionFactor":"1"},"protoParams":["50","1","0","0"]},{"type":"PAD","solids":[1],"face":"1:1","params":{"target":[0,-50,0],"expansionFactor":"1"},"protoParams":["50","1","0","0"]},{"type":"CUT","solids":[2],"face":"2:0","params":{"target":[0,252,0],"expansionFactor":"1"},"protoParams":["252","1","0","0"]},{"type":"CUT","solids":[3],"face":"1:1$","params":{"target":[0,50,0],"expansionFactor":"1"},"protoParams":["50","1","0","0"]}]}');
|
||||
localStorage.setItem("TCAD.projects.sample", '{"history":[{"type":"PLANE","solids":[],"params":{"basis":[[1,0,0],[0,0,1],[0,1,0]],"depth":"0"},"protoParams":["XZ","0"]},{"type":"EXTRUDE","solids":[0],"face":"0:0","params":{"target":[0,-50,0],"expansionFactor":"1"},"protoParams":["50","1","0","0"]},{"type":"EXTRUDE","solids":[1],"face":"1:1","params":{"target":[0,-50,0],"expansionFactor":"1"},"protoParams":["50","1","0","0"]},{"type":"CUT","solids":[2],"face":"2:0","params":{"target":[0,252,0],"expansionFactor":"1"},"protoParams":["252","1","0","0"]},{"type":"CUT","solids":[3],"face":"1:1$","params":{"target":[0,50,0],"expansionFactor":"1"},"protoParams":["50","1","0","0"]}]}');
|
||||
localStorage.setItem("TCAD.projects.sample.sketch.0:0", '{"layers":[{"name":"_dim","style":{"lineWidth":1,"strokeStyle":"#bcffc1","fillStyle":"#00FF00"},"data":[]},{"name":"__bounds__","style":{"lineWidth":2,"strokeStyle":"#fff5c3","fillStyle":"#000000"},"data":[{"id":6,"_class":"TCAD.TWO.Segment","aux":true,"edge":0,"points":[[0,[1,-400],[2,400]],[3,[4,-400],[5,-400]]]},{"id":13,"_class":"TCAD.TWO.Segment","aux":true,"edge":2,"points":[[7,[8,-400],[9,-400]],[10,[11,400],[12,-400]]]},{"id":20,"_class":"TCAD.TWO.Segment","aux":true,"edge":4,"points":[[14,[15,400],[16,-400]],[17,[18,400],[19,400]]]},{"id":27,"_class":"TCAD.TWO.Segment","aux":true,"edge":6,"points":[[21,[22,400],[23,400]],[24,[25,-400],[26,400]]]}]},{"name":"sketch","style":{"lineWidth":2,"strokeStyle":"#ffffff","fillStyle":"#000000"},"data":[{"id":34,"_class":"TCAD.TWO.Segment","points":[[28,[29,-80.41502600578134],[30,240.48794311524324]],[31,[32,252.10163324769275],[33,71.15131239804411]]]},{"id":41,"_class":"TCAD.TWO.Segment","points":[[35,[36,255.946878629896],[37,-145.76094357167156]],[38,[39,-91.17342089039929],[40,-338.36716169336114]]]},{"id":48,"_class":"TCAD.TWO.Segment","points":[[42,[43,-172.00749593627577],[44,-240.71428346724593]],[45,[46,-88.51020843368133],[47,-140.46311545122035]]]},{"id":55,"_class":"TCAD.TWO.Segment","points":[[49,[50,-102.18982576106004],[51,18.31440664196805]],[52,[53,-182.7982464866314],[54,86.82364838151852]]]},{"id":72,"_class":"TCAD.TWO.Arc","points":[[63,[64,255.946878629896],[65,-145.76094357167156]],[66,[67,252.10163324769275],[68,71.15131239804411]],[69,[70,196.33682709088268],[71,-38.32745196977044]]]},{"id":83,"_class":"TCAD.TWO.Arc","points":[[74,[75,-80.41502600578134],[76,240.48794311524324]],[77,[78,-182.7982464866314],[79,86.82364838151852]],[80,[81,-122.59914075444685],[82,157.65429488839598]]]},{"id":94,"_class":"TCAD.TWO.Arc","points":[[85,[86,-88.51020843368133],[87,-140.46311545122035]],[88,[89,-102.18982576106004],[90,18.31440664196805]],[91,[92,-175.53398017227],[93,-67.98267439986091]]]},{"id":105,"_class":"TCAD.TWO.Arc","points":[[96,[97,-172.00749593627577],[98,-240.71428346724593]],[99,[100,-91.17342089039929],[101,-338.36716169336114]],[102,[103,-122.4591797419898],[104,-281.9821285194346]]]}]},{"name":"_construction_","style":{"lineWidth":1,"strokeStyle":"#aaaaaa","fillStyle":"#000000"},"data":[]}],"constraints":[["Tangent",[72,41]],["Tangent",[72,34]],["coi",[63,35]],["coi",[66,31]],["Tangent",[83,34]],["Tangent",[83,55]],["coi",[74,28]],["coi",[77,52]],["Tangent",[94,48]],["Tangent",[94,55]],["coi",[85,45]],["coi",[88,49]],["Tangent",[105,48]],["Tangent",[105,41]],["coi",[96,42]],["coi",[99,38]]],"boundary":{"lines":[{"a":{"x":-400,"y":400},"b":{"x":-400,"y":-400}},{"a":{"x":-400,"y":-400},"b":{"x":400,"y":-400}},{"a":{"x":400,"y":-400},"b":{"x":400,"y":400}},{"a":{"x":400,"y":400},"b":{"x":-400,"y":400}}],"arcs":[],"circles":[]}}');
|
||||
localStorage.setItem("TCAD.projects.sample.sketch.1:0", '{"boundary":{"lines":[{"a":{"x":80.41502600578134,"y":240.48794311524324},"b":{"x":-252.10163324769275,"y":71.15131239804411}},{"a":{"x":-255.946878629896,"y":-145.76094357167156},"b":{"x":91.17342089039929,"y":-338.36716169336114}},{"a":{"x":172.00749593627577,"y":-240.71428346724593},"b":{"x":88.51020843368133,"y":-140.46311545122035}},{"a":{"x":102.18982576106004,"y":18.31440664196805},"b":{"x":182.7982464866314,"y":86.82364838151852}}],"arcs":[{"a":{"x":-252.10163324769275,"y":71.15131239804411},"b":{"x":-255.946878629896,"y":-145.76094357167156},"c":{"x":-196.33682672526209,"y":-38.32745176660378}},{"a":{"x":91.17342089039929,"y":-338.36716169336114},"b":{"x":172.00749593627577,"y":-240.71428346724593},"c":{"x":122.45917974196499,"y":-281.98212851943595}},{"a":{"x":102.18982576106004,"y":18.31440664196805},"b":{"x":88.51020843368133,"y":-140.46311545122035},"c":{"x":175.5339801724776,"y":-67.98267439979745}},{"a":{"x":182.7982464866314,"y":86.82364838151852},"b":{"x":80.41502600578134,"y":240.48794311524324},"c":{"x":122.59914075460381,"y":157.65429488902345}}],"circles":[]}}');
|
||||
localStorage.setItem("TCAD.projects.sample.sketch.1:1", '{"layers":[{"name":"_dim","style":{"lineWidth":1,"strokeStyle":"#bcffc1","fillStyle":"#00FF00"},"data":[]},{"name":"__bounds__","style":{"lineWidth":2,"strokeStyle":"#fff5c3","fillStyle":"#000000"},"data":[{"id":6,"_class":"TCAD.TWO.Segment","aux":true,"edge":0,"points":[[0,[1,-91.17342089039929],[2,-338.36716169336114]],[3,[4,255.946878629896],[5,-145.76094357167156]]]},{"id":13,"_class":"TCAD.TWO.Segment","aux":true,"edge":2,"points":[[7,[8,252.10163324769275],[9,71.15131239804411]],[10,[11,-80.41502600578134],[12,240.48794311524324]]]},{"id":20,"_class":"TCAD.TWO.Segment","aux":true,"edge":4,"points":[[14,[15,-182.7982464866314],[16,86.82364838151852]],[17,[18,-102.18982576106004],[19,18.31440664196805]]]},{"id":27,"_class":"TCAD.TWO.Segment","aux":true,"edge":6,"points":[[21,[22,-88.51020843368133],[23,-140.46311545122035]],[24,[25,-172.00749593627577],[26,-240.71428346724593]]]},{"id":37,"_class":"TCAD.TWO.Arc","aux":true,"edge":8,"points":[[28,[29,255.946878629896],[30,-145.76094357167156]],[31,[32,252.10163324769275],[33,71.15131239804411]],[34,[35,196.33682672526209],[36,-38.32745176660376]]]},{"id":48,"_class":"TCAD.TWO.Arc","aux":true,"edge":10,"points":[[39,[40,-80.41502600578134],[41,240.48794311524324]],[42,[43,-182.7982464866314],[44,86.82364838151852]],[45,[46,-122.59914075460384],[47,157.65429488902345]]]},{"id":59,"_class":"TCAD.TWO.Arc","aux":true,"edge":12,"points":[[50,[51,-88.51020843368133],[52,-140.46311545122035]],[53,[54,-102.18982576106004],[55,18.31440664196805]],[56,[57,-175.5339801724776],[58,-67.98267439979745]]]},{"id":70,"_class":"TCAD.TWO.Arc","aux":true,"edge":14,"points":[[61,[62,-172.00749593627577],[63,-240.71428346724593]],[64,[65,-91.17342089039929],[66,-338.36716169336114]],[67,[68,-122.45917974196257],[69,-281.982128519434]]]}]},{"name":"sketch","style":{"lineWidth":2,"strokeStyle":"#ffffff","fillStyle":"#000000"},"data":[{"id":75,"_class":"TCAD.TWO.Circle","c":[72,[73,-122.59914075460384],[74,157.65429488902345]],"r":92.9565103454672},{"id":77,"_class":"TCAD.TWO.EndPoint","location":[77,[78,30.202166630027865],[79,-54.24889318543422]]},{"id":83,"_class":"TCAD.TWO.Circle","c":[80,[81,-122.45917974196257],[82,-281.982128519434]],"r":64.48310377876552}]},{"name":"_construction_","style":{"lineWidth":1,"strokeStyle":"#aaaaaa","fillStyle":"#000000"},"data":[]}],"constraints":[["RR",[48,75]],["coi",[72,45]],["coi",[80,67]],["RR",[83,70]]]}');
|
||||
|
|
|
|||
|
|
@ -6,9 +6,8 @@ import ToolBar from './toolbar'
|
|||
import * as MenuConfig from '../menu/menu-config'
|
||||
import * as Operations from '../craft/operations'
|
||||
import Menu from '../menu/menu'
|
||||
import {CutWizard} from '../craft/brep/wizards/cut-extrude'
|
||||
import {ExtrudeWizard, CutWizard} from '../craft/brep/wizards/cut-extrude'
|
||||
|
||||
import {ExtrudeWizard as MeshExtrudeWizard} from '../craft/mesh/wizards/extrude'
|
||||
import {RevolveWizard} from '../craft/mesh/wizards/revolve'
|
||||
import {PlaneWizard} from '../craft/mesh/wizards/plane'
|
||||
import {BoxWizard} from '../craft/brep/wizards/box'
|
||||
|
|
@ -45,7 +44,7 @@ function UI(app) {
|
|||
var ui = this;
|
||||
|
||||
this.app.bus.subscribe("showSketches", (enabled) => {
|
||||
var solids = app.findAllSolids();
|
||||
var solids = app.findAllSolidsOnScene();
|
||||
for (var i = 0; i < solids.length; i++) {
|
||||
for (var j = 0; j < solids[i].sceneFaces.length; j++) {
|
||||
var face = solids[i].sceneFaces[j];
|
||||
|
|
@ -73,12 +72,11 @@ UI.prototype.createCraftToolBar = function (vertPos) {
|
|||
var toolBar = new ToolBar(this.app);
|
||||
toolBar.add(this.app.actionManager.actions['PLANE']);
|
||||
toolBar.add(this.app.actionManager.actions['EditFace']);
|
||||
toolBar.add(this.app.actionManager.actions['PAD']);
|
||||
toolBar.add(this.app.actionManager.actions['EXTRUDE']);
|
||||
toolBar.add(this.app.actionManager.actions['CUT']);
|
||||
toolBar.add(this.app.actionManager.actions['REVOLVE']);
|
||||
|
||||
|
||||
|
||||
$('#viewer-container').append(toolBar.node);
|
||||
toolBar.node.css({left: '10px',top : vertPos + 'px'});
|
||||
return toolBar;
|
||||
|
|
@ -172,8 +170,8 @@ UI.prototype.createWizard = function(type, overridingHistory, initParams, face)
|
|||
let wizard = null;
|
||||
if ('CUT' === type) {
|
||||
wizard = new CutWizard(this.app, initParams);
|
||||
} else if ('PAD' === type) {
|
||||
wizard = new MeshExtrudeWizard(this.app, face, false, initParams);
|
||||
} else if ('EXTRUDE' === type) {
|
||||
wizard = new ExtrudeWizard(this.app, initParams);
|
||||
} else if ('REVOLVE' === type) {
|
||||
wizard = new RevolveWizard(this.app, face, initParams);
|
||||
} else if ('PLANE' === type) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
export const keymap = {
|
||||
|
||||
'CUT': 'C',
|
||||
'PAD': 'E',
|
||||
'EXTRUDE': 'E',
|
||||
'ZoomIn': '+',
|
||||
'ZoomOut': '-',
|
||||
'menu.craft': 'shift+C',
|
||||
|
|
|
|||
|
|
@ -41,7 +41,10 @@ ModificationsPanel.prototype.updateList = function() {
|
|||
id : i,
|
||||
info: this.app.ui.getInfoForOp(op),
|
||||
OnBind : (dom, data) => {
|
||||
dom.css('background-image', 'url('+ getIconForOp(op)+')');
|
||||
const icon = getIconForOp(op);
|
||||
if (icon) {
|
||||
dom.css('background-image', 'url('+ icon+')');
|
||||
}
|
||||
if (!op.face) {
|
||||
dom.find('.require-face').addClass('action-disabled');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,23 @@ import {HalfEdge, Edge} from './topo/edge'
|
|||
import {Line} from './geom/impl/line'
|
||||
import {Plane} from './geom/impl/plane'
|
||||
import {Point} from './geom/point'
|
||||
import {BasisForPlane, Matrix3} from '../math/l3space'
|
||||
import * as cad_utils from '../3d/cad-utils'
|
||||
import * as math from '../math/math'
|
||||
|
||||
function isCCW(points, normal) {
|
||||
const tr2d = new Matrix3().setBasis(BasisForPlane(normal)).invert();
|
||||
const points2d = points.map(p => tr2d.apply(p));
|
||||
return math.isCCW(points2d);
|
||||
}
|
||||
|
||||
function checkCCW(points, normal) {
|
||||
if (!isCCW(points, normal)) {
|
||||
points = points.slice();
|
||||
points.reverse();
|
||||
}
|
||||
return points;
|
||||
}
|
||||
|
||||
export function createPrism(basePoints, height) {
|
||||
return new SimpleExtruder(height).extrude(basePoints, cad_utils.normalOfCCWSeq(basePoints));
|
||||
|
|
@ -21,8 +36,9 @@ export class Extruder {
|
|||
calculateLid(basePoints) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
|
||||
extrude(basePoints, normal) {
|
||||
basePoints = checkCCW(basePoints, normal);
|
||||
const baseLoop = createPlaneLoop(basePoints.map(p => new Vertex(p)));
|
||||
const baseFace = createPlaneFace(normal, baseLoop);
|
||||
const lidNormal = normal.multiply(-1);
|
||||
|
|
@ -30,7 +46,7 @@ export class Extruder {
|
|||
this.prepareLidCalculation(normal, lidNormal);
|
||||
|
||||
//iterateSegments(basePoints.map(p => new Vertex(p.plus(offVector))), (a, b) => lidSegments.push({a, b}));
|
||||
const lidPoints = this.calculateLid(basePoints).reverse();
|
||||
const lidPoints = this.calculateLid(basePoints, normal, lidNormal).reverse();
|
||||
const lidLoop = createPlaneLoop(lidPoints.map(p => new Vertex(p)));
|
||||
|
||||
const shell = new Shell();
|
||||
|
|
|
|||
|
|
@ -299,7 +299,11 @@ Bus.prototype.notify = function(event, data, sender) {
|
|||
const callback = listenerList[i][0];
|
||||
const listenerId = listenerList[i][1];
|
||||
if (sender == undefined || listenerId == null || listenerId != sender) {
|
||||
callback(data);
|
||||
try {
|
||||
callback(data);
|
||||
} catch(e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue