diff --git a/modules/workbenches/modeler/features/mirrorBody/mirrorBody.operation.ts b/modules/workbenches/modeler/features/mirrorBody/mirrorBody.operation.ts new file mode 100644 index 00000000..e7eaad61 --- /dev/null +++ b/modules/workbenches/modeler/features/mirrorBody/mirrorBody.operation.ts @@ -0,0 +1,66 @@ +import { roundValueForPresentation as r } from 'cad/craft/operationHelper'; +import { MFace } from "cad/model/mface"; +import { ApplicationContext } from "context"; +import { EntityKind } from "cad/model/entities"; +import Axis from "math/axis"; +import { OperationDescriptor } from "cad/craft/operationPlugin"; +import { MShell } from 'cad/model/mshell'; + +interface MirrorBodyParams { + inputBodies: MShell[]; + face:MFace; +} + +export const MirrorBodyOperation: OperationDescriptor = { + id: 'MIRROR_BODY', + label: 'Mirror Body', + icon: 'img/cad/MirrorBody', + info: 'Mirrors selected body along plane of symytry.', + paramsInfo: ({ }) => `(${r()})`, + run: (params: MirrorBodyParams, ctx: ApplicationContext) => { + console.log(params); + let occ = ctx.occService; + const oci = occ.commandInterface; + + let created =[]; + + params.inputBodies.forEach((shellToMirror) => { + const newShellName = shellToMirror.id + ":mirror"; + oci.copy(shellToMirror, newShellName); + params.face.csys.origin.data(); + oci.tmirror(newShellName, ...params.face.csys.origin.data(), ...params.face.csys.origin.normalize().data()); + created.push(occ.io.getShell(newShellName)); + }); + + return { + created, + consumed: [] + }; + + + }, + form: [ + { + type: 'selection', + name: 'face', + capture: [EntityKind.FACE], + label: 'Mirror Plane', + multi: false, + defaultValue: { + usePreselection: false, + preselectionIndex: 0 + }, + }, + { + type: 'selection', + name: 'inputBodies', + capture: [EntityKind.SHELL], + label: 'Bodies', + multi: true, + defaultValue: { + usePreselection: true, + preselectionIndex: 0 + }, + }, + ], +} diff --git a/modules/workbenches/modeler/features/smFlange/smFlange.operation.ts b/modules/workbenches/modeler/features/smFlange/smFlange.operation.ts new file mode 100644 index 00000000..41556d27 --- /dev/null +++ b/modules/workbenches/modeler/features/smFlange/smFlange.operation.ts @@ -0,0 +1,89 @@ +import { roundValueForPresentation as r } from 'cad/craft/operationHelper'; +import { MFace } from "cad/model/mface"; +import { ApplicationContext } from "context"; +import { EntityKind } from "cad/model/entities"; +import { BooleanDefinition } from "cad/craft/schema/common/BooleanDefinition"; +import Axis from "math/axis"; +import { OperationDescriptor } from "cad/craft/operationPlugin"; + +interface smFlangeParams { + angle: number; + face: MFace; + axis: Axis, + boolean: BooleanDefinition +} + +export const smFlangeOperation: OperationDescriptor = { + id: 'SM_FLANGE', + label: 'Flange', + icon: 'img/cad/smFlange', + info: 'Creates Sheet metal flange', + paramsInfo: ({ angle }) => `(${r(angle)})`, + run: (params: smFlangeParams, ctx: ApplicationContext) => { + console.log(params); + let occ = ctx.occService; + const oci = occ.commandInterface; + + const face = params.face; + + let occFaces = [face]; + + const tools = occFaces.map((faceName, i) => { + const shapeName = "Tool/" + i; + var args = [shapeName, faceName, ...params.axis.origin.data(), ...params.axis.direction.negate().data(), params.angle]; + oci.revol(...args); + + return shapeName; + }); + + + return occ.utils.applyBooleanModifier(tools, params.boolean); + + }, + form: [ + { + type: 'number', + label: 'angle', + name: 'angle', + defaultValue: 90, + }, + { + type: 'selection', + name: 'face', + capture: [EntityKind.FACE], + label: 'face', + multi: false, + defaultValue: { + usePreselection: true, + preselectionIndex: 0 + }, + }, + { + type: 'selection', + name: 'Edge', + capture: [EntityKind.EDGE], + label: 'Edge', + multi: false, + defaultValue: { + usePreselection: true, + preselectionIndex: 0 + }, + }, + + + { + type: 'axis', + name: 'axis', + label: 'axis', + optional: false + }, + { + type: 'boolean', + name: 'boolean', + label: 'boolean', + optional: true, + defaultValue: 'UNION' + } + + ], +} diff --git a/modules/workbenches/modeler/features/smTab/smTab.operation.ts b/modules/workbenches/modeler/features/smTab/smTab.operation.ts new file mode 100644 index 00000000..59bf7a3b --- /dev/null +++ b/modules/workbenches/modeler/features/smTab/smTab.operation.ts @@ -0,0 +1,106 @@ +import { roundValueForPresentation as r } from 'cad/craft/operationHelper'; +import { MFace } from "cad/model/mface"; +import { ApplicationContext } from "context"; +import { EntityKind } from "cad/model/entities"; +import { BooleanDefinition } from "cad/craft/schema/common/BooleanDefinition"; +import { UnitVector } from "math/vector"; +import { OperationDescriptor } from "cad/craft/operationPlugin"; + + +interface smTabParams { + thickness: number; + bendRadius: number; + kFactor: number; + flipper: boolean; + sketch: MFace; + boolean: BooleanDefinition; +} + +export const smTabOperation: OperationDescriptor = { + id: 'SM_TAB', + label: 'SM Tab', + icon: 'img/cad/smTab', + info: 'Create tab from sketch', + paramsInfo: ({ thickness, bendRadius }) => `(${r(thickness)} ${r(bendRadius)} )`, + run: (params: smTabParams, ctx: ApplicationContext) => { + + let occ = ctx.occService; + console.log(ctx.craftService.modifications$.value.history); + const oci = occ.commandInterface; + + const face = params.sketch; + + let sketch = ctx.sketchStorageService.readSketch(face.id); + if (!sketch) throw 'sketch not found for the face ' + face.id; + + const occFaces = occ.utils.sketchToFaces(sketch, face.csys); + + const dir: UnitVector= face.normal(); + + let extrusionVector =[]; + if(params.flipper == true){ + extrusionVector = dir.normalize()._multiply(params.thickness).data(); + }else{ + extrusionVector = dir.normalize()._multiply(params.thickness).negate().data(); + + } + + + const tools = occFaces.map((faceName, i) => { + const shapeName = "Tool/" + i; + const bla = oci.prism(shapeName, faceName, ...extrusionVector); + console.log(bla); + return shapeName; + }); + + + return occ.utils.applyBooleanModifier(tools, params.boolean); + + }, + + + form: [ + { + type: 'number', + label: 'Thickness', + name: 'thickness', + defaultValue: 1, + }, + { + type: 'number', + label: 'Bend Radius', + name: 'bendRadius', + defaultValue: 2, + }, + { + type: 'number', + label: 'K-Factor', + name: 'kFactor', + defaultValue: 0.35, + }, + { + type: 'checkbox', + label: 'flip', + name: 'flipper', + defaultValue: false, + }, + { + type: 'selection', + name: 'sketch', + capture: [EntityKind.FACE], + label: 'Sketch', + multi: false, + defaultValue: { + usePreselection: true, + preselectionIndex: 0 + }, + }, + { + type: 'boolean', + name: 'boolean', + label: 'boolean', + optional: true, + } + + ], +} diff --git a/modules/workbenches/modeler/index.ts b/modules/workbenches/modeler/index.ts index 7d97569d..1ae920e9 100644 --- a/modules/workbenches/modeler/index.ts +++ b/modules/workbenches/modeler/index.ts @@ -12,7 +12,10 @@ import { BooleanOperation } from "./features/boolean/boolean.operation"; import { RevolveOperation } from "./features/revolve/revolve.operation"; import { ShellOperation } from "./features/shell/shell.operation"; import { SweepOperation } from "./features/sweep/sweep.operation"; -import { offsetOperation } from "./features/offsetFace/offsetFace.operation" +import { offsetOperation } from "./features/offsetFace/offsetFace.operation"; +import { smTabOperation } from "./features/smTab/smTab.operation"; +import { smFlangeOperation } from "./features/smFlange/smFlange.operation"; +import { MirrorBodyOperation} from "./features/mirrorBody/mirrorBody.operation"; export const ModelerWorkspace: WorkbenchConfig = { @@ -31,7 +34,10 @@ export const ModelerWorkspace: WorkbenchConfig = { ShellOperation, LoftOperation, SweepOperation, - offsetOperation + offsetOperation, + smTabOperation, + smFlangeOperation, + MirrorBodyOperation ], actions: [], ui: { @@ -39,10 +45,11 @@ export const ModelerWorkspace: WorkbenchConfig = { 'DATUM_CREATE', 'PLANE', 'EditFace', '-', "EXTRUDE", "REVOLVE", "LOFT", "SWEEP", "-", "BOOLEAN", "-", - "SHELL_TOOL", "FILLET_TOOL", "OFFSET_TOOL", "-", + "SHELL_TOOL", "FILLET_TOOL", "OFFSET_TOOL", "MIRROR_BODY", "-", "PRIMITIVE_CYLINDER", "PRIMITIVE_BOX", "PRIMITIVE_CONE", "PRIMITIVE_SPHERE", "PRIMITIVE_TORUS", "-", "HOLE_TOOL", "-", "OCC_BOTTLE", '-', + "SM_TAB","SM_FLANGE" ] } } \ No newline at end of file diff --git a/modules/workbenches/registry.ts b/modules/workbenches/registry.ts index cba179ed..e11ae3e0 100644 --- a/modules/workbenches/registry.ts +++ b/modules/workbenches/registry.ts @@ -2,7 +2,7 @@ import {ModelerWorkspace} from "workbenches/modeler"; import {ExampleWorkspace} from "workbenches/examples"; import {WorkbenchConfig} from "cad/workbench/workbenchService"; + export const WorkbenchRegistry: WorkbenchConfig[] = [ ModelerWorkspace, - // ExampleWorkspace, ] \ No newline at end of file diff --git a/web/img/cad/smFlange96.png b/web/img/cad/smFlange96.png new file mode 100644 index 00000000..0ee6289e Binary files /dev/null and b/web/img/cad/smFlange96.png differ diff --git a/web/img/cad/smTab96.png b/web/img/cad/smTab96.png new file mode 100644 index 00000000..5b887fe5 Binary files /dev/null and b/web/img/cad/smTab96.png differ