mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-09 18:02:50 +01:00
feature request: Allow plane to be created relative to face with offset from face. #17
This commit is contained in:
parent
90535c6d4f
commit
702d01a62a
5 changed files with 68 additions and 26 deletions
|
|
@ -177,18 +177,13 @@ export function createPlane(basis, depth) {
|
|||
var plane = new Solid(CSG.fromPolygons([polygon]), material, 'PLANE');
|
||||
plane.wireframeGroup.visible = false;
|
||||
plane.mergeable = false;
|
||||
var _3d = tr.invert();
|
||||
|
||||
function setBounds(bbox) {
|
||||
var corner = new Vector(bbox.minX, bbox.minY, 0);
|
||||
var size = new Vector(bbox.width(), bbox.height(), 1);
|
||||
_3d._apply(size);
|
||||
_3d._apply(corner);
|
||||
plane.mesh.scale.set(size.x, size.y, size.z);
|
||||
plane.mesh.position.set(corner.x, corner.y, corner.z);
|
||||
currentBounds = bbox;
|
||||
var poly = new CSG.Polygon(bbox.toPolygon().map(function(p){return new CSG.Vertex(csgVec( _3d._apply(p) ))}), shared);
|
||||
const poly = new CSG.Polygon(bbox.toPolygon().map(function(p){p.z = depth; return new CSG.Vertex(csgVec( tr._apply(p) ))}), shared);
|
||||
plane.csg = CSG.fromPolygons([poly]);
|
||||
plane.dropGeometry();
|
||||
plane.createGeometry();
|
||||
}
|
||||
var bb = new BBox();
|
||||
bb.checkBounds(-400, -400);
|
||||
|
|
|
|||
|
|
@ -15,25 +15,37 @@ export function Solid(csg, material, type, id) {
|
|||
this.cadGroup = new THREE.Object3D();
|
||||
this.cadGroup.__tcad_solid = this;
|
||||
|
||||
var geometry = new THREE.Geometry();
|
||||
geometry.dynamic = true;
|
||||
this.mesh = new THREE.Mesh(geometry, material);
|
||||
this.cadGroup.add(this.mesh);
|
||||
|
||||
this.tCadId = Counters.solid ++;
|
||||
this.id = id === undefined ? this.tCadId : id; // to keep identity through the history
|
||||
this.faceCounter = 0;
|
||||
|
||||
this.wireframeGroup = new THREE.Object3D();
|
||||
this.cadGroup.add(this.wireframeGroup);
|
||||
this.mergeable = true;
|
||||
this.material = material;
|
||||
this.createGeometry();
|
||||
}
|
||||
|
||||
Solid.prototype.createGeometry = function() {
|
||||
const geometry = new THREE.Geometry();
|
||||
geometry.dynamic = true;
|
||||
this.mesh = new THREE.Mesh(geometry, this.material);
|
||||
this.cadGroup.add(this.mesh);
|
||||
|
||||
this.polyFaces = [];
|
||||
this.wires = HashTable.forEdge();
|
||||
this.curvedSurfaces = {};
|
||||
this.mergeable = true;
|
||||
|
||||
this.setupGeometry();
|
||||
}
|
||||
};
|
||||
|
||||
Solid.prototype.dropGeometry = function() {
|
||||
this.cadGroup.remove( this.mesh );
|
||||
this.mesh.geometry.dispose();
|
||||
for(let i = this.wireframeGroup.children.length-1; i >=0 ; i--){
|
||||
this.wireframeGroup.remove(this.wireframeGroup.children[i]);
|
||||
}
|
||||
};
|
||||
|
||||
function groupCSG(csg) {
|
||||
var csgPolygons = csg.toPolygons();
|
||||
|
|
@ -101,7 +113,7 @@ Solid.prototype.setupGeometry = function() {
|
|||
|
||||
Solid.prototype.vanish = function() {
|
||||
this.cadGroup.parent.remove( this.cadGroup );
|
||||
this.mesh.material.dispose();
|
||||
this.material.dispose();
|
||||
this.mesh.geometry.dispose();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ UI.prototype.createWizard = function(type, overridingHistory, initParams, face)
|
|||
} else if ('REVOLVE' === type) {
|
||||
wizard = new RevolveWizard(this.app, face, initParams);
|
||||
} else if ('PLANE' === type) {
|
||||
wizard = new PlaneWizard(this.app.viewer, initParams);
|
||||
wizard = new PlaneWizard(this.app, initParams);
|
||||
} else if ('BOX' === type) {
|
||||
wizard = new BoxWizard(this.app.viewer, initParams);
|
||||
} else if ('SPHERE' === type) {
|
||||
|
|
|
|||
|
|
@ -2,23 +2,35 @@ import {AXIS, IDENTITY_BASIS} from '../../math/l3space'
|
|||
import * as tk from '../../ui/toolkit.js'
|
||||
import {FACE_COLOR} from '../cad-utils'
|
||||
import {Wizard} from './wizard-commons'
|
||||
import {Matrix3} from '../../math/l3space'
|
||||
|
||||
export function PlaneWizard(viewer, initParams) {
|
||||
Wizard.call(this, viewer, initParams);
|
||||
export function PlaneWizard(app, initParams) {
|
||||
Wizard.call(this, app.viewer, initParams);
|
||||
this.app = app;
|
||||
this.previewGroup = new THREE.Object3D();
|
||||
this.viewer.scene.add(this.previewGroup);
|
||||
this.previewGroup.add(this.plane = this.createPlane());
|
||||
this.operationParams = {
|
||||
basis : IDENTITY_BASIS,
|
||||
depth : 0
|
||||
depth : 0,
|
||||
relativeToFaceId: ''
|
||||
};
|
||||
this.selectionListener = () => {
|
||||
const face = this.app.viewer.selectionMgr.selection[0];
|
||||
if (face) {
|
||||
this.ui.relativeToFace.input.val(face.id);
|
||||
this.synch();
|
||||
}
|
||||
};
|
||||
app.bus.subscribe('selection', this.selectionListener);
|
||||
|
||||
this.focus = () => this.ui.depth.input.focus();
|
||||
this.synch();
|
||||
}
|
||||
|
||||
PlaneWizard.prototype = Object.create( Wizard.prototype );
|
||||
|
||||
PlaneWizard.prototype.DEFAULT_PARAMS = ['XY', 0];
|
||||
PlaneWizard.prototype.DEFAULT_PARAMS = ['XY', 0, ''];
|
||||
|
||||
PlaneWizard.prototype.title = function() {
|
||||
return "Add a Plane";
|
||||
|
|
@ -30,8 +42,17 @@ PlaneWizard.prototype.createPlane = function() {
|
|||
return new THREE.Mesh(geometry, material);
|
||||
};
|
||||
|
||||
PlaneWizard.prototype.update = function(orientation, w) {
|
||||
if (orientation === 'XY') {
|
||||
PlaneWizard.prototype.update = function(orientation, w, relativeToFaceId) {
|
||||
if (relativeToFaceId != '') {
|
||||
const face = this.app.findFace(relativeToFaceId);
|
||||
const m = new THREE.Matrix4();
|
||||
m.makeBasis.apply(m, face.basis());
|
||||
const wVec = new THREE.Vector3(0, 0, w + face.depth());
|
||||
wVec.applyMatrix4(m);
|
||||
m.setPosition(wVec);
|
||||
this.plane.matrix.identity();
|
||||
this.plane.applyMatrix(m);
|
||||
} else if (orientation === 'XY') {
|
||||
this.plane.rotation.x = 0;
|
||||
this.plane.rotation.y = 0;
|
||||
this.plane.rotation.z = 0;
|
||||
|
|
@ -59,16 +80,20 @@ PlaneWizard.prototype.update = function(orientation, w) {
|
|||
throw orientation + " isn't supported yet";
|
||||
}
|
||||
this.operationParams.depth = w;
|
||||
this.operationParams.relativeToFaceId = relativeToFaceId;
|
||||
this.viewer.render();
|
||||
};
|
||||
|
||||
PlaneWizard.prototype.createUI = function(orientation, w) {
|
||||
PlaneWizard.prototype.createUI = function(orientation, w, relativeToFaceId) {
|
||||
const folder = this.ui.folder;
|
||||
const choice = ['XY', 'XZ', 'ZY'];
|
||||
this.ui.orientation = new tk.InlineRadio(choice, choice, choice.indexOf(orientation));
|
||||
this.ui.depth = new tk.Number("Depth", w);
|
||||
this.ui.relativeToFace = new tk.Text("Relative to Face", relativeToFaceId === undefined ? '' : relativeToFaceId);
|
||||
tk.add(folder, this.ui.orientation);
|
||||
tk.add(folder, this.ui.relativeToFace);
|
||||
tk.add(folder, this.ui.depth);
|
||||
|
||||
var onChange = tk.methodRef(this, "synch");
|
||||
this.ui.orientation.root.find('input:radio').change(onChange);
|
||||
this.ui.depth.input.on('t-change', onChange);
|
||||
|
|
@ -80,7 +105,7 @@ PlaneWizard.prototype.synch = function() {
|
|||
};
|
||||
|
||||
PlaneWizard.prototype.getParams = function() {
|
||||
return [this.ui.orientation.getValue(), this.ui.depth.input.val()]
|
||||
return [this.ui.orientation.getValue(), parseFloat(this.ui.depth.input.val()), this.ui.relativeToFace.input.val()]
|
||||
};
|
||||
|
||||
PlaneWizard.prototype.createRequest = function(done) {
|
||||
|
|
|
|||
|
|
@ -902,7 +902,17 @@ export const OPERATIONS = {
|
|||
PAD : extrude,
|
||||
REVOLVE : performRevolve,
|
||||
PLANE : function(app, request) {
|
||||
return [cad_utils.createPlane(request.params.basis, request.params.depth)];
|
||||
let basis, depth = request.params.depth;
|
||||
const relativeToFaceId = request.params.relativeToFaceId;
|
||||
if (relativeToFaceId != undefined && relativeToFaceId != '') {
|
||||
const face = app.findFace(relativeToFaceId);
|
||||
if (!face) return;
|
||||
basis = face.basis();
|
||||
depth += face.depth();
|
||||
} else {
|
||||
basis = request.params.basis;
|
||||
}
|
||||
return [cad_utils.createPlane(basis, depth)];
|
||||
},
|
||||
BOX : function(app, request) {
|
||||
var p = request.params;
|
||||
|
|
|
|||
Loading…
Reference in a new issue