diff --git a/web/app/cad/craft/operationPlugin.ts b/web/app/cad/craft/operationPlugin.ts index bd16ba08..aef03710 100644 --- a/web/app/cad/craft/operationPlugin.ts +++ b/web/app/cad/craft/operationPlugin.ts @@ -129,9 +129,10 @@ export interface OperationDescriptor { actionParams?: any; run: (request: R, opContext: CoreContext) => OperationResult | Promise; paramsInfo: (params: R) => string, - previewGeomProvider: (params: R) => OperationGeometryProvider, + previewGeomProvider?: (params: R) => OperationGeometryProvider, form: () => React.ReactNode, - schema: any + schema: any, + onParamsUpdate?: (params, name, value) => void } export interface OperationService { diff --git a/web/app/cad/mdf/generateForm.tsx b/web/app/cad/mdf/generateForm.tsx new file mode 100644 index 00000000..8b48b69b --- /dev/null +++ b/web/app/cad/mdf/generateForm.tsx @@ -0,0 +1,31 @@ +import React from 'react'; +import Entity from '../craft/wizard/components/form/Entity'; +import { CheckboxField, NumberField } from '../craft/wizard/components/form/Fields'; +import { Group } from '../craft/wizard/components/form/Form'; +import { OperationSchema, SchemaField } from './mdf'; + +export function generateForm(schema: OperationSchema) { + + return function MDForm() { + return + {Object.keys(schema).map(key => { + + const fieldDef: SchemaField = schema[key]; + const label = fieldDef.label || key; + + if (fieldDef.type === 'number') { + return + } else if (['face', 'edge', 'sketchObject', 'datumAxis'].includes(fieldDef.type)) { + return ; + } else if (fieldDef.type === 'boolean') { + return ; + } else { + return "I don't know"; + } + + })} + ; + }; + + +} \ No newline at end of file diff --git a/web/app/cad/mdf/mdf.ts b/web/app/cad/mdf/mdf.ts new file mode 100644 index 00000000..7ec9c6d1 --- /dev/null +++ b/web/app/cad/mdf/mdf.ts @@ -0,0 +1,61 @@ +import { CoreContext } from "context"; +import { IconType } from "react-icons"; +import { OperationResult } from "../craft/craftPlugin"; +import { OperationDescriptor } from "../craft/operationPlugin"; +import { generateForm } from "./generateForm"; + + +interface MDFCommand { + id: string; + label: string; + info: string; + icon: IconType | string; + run: (request: R, opContext: CoreContext) => OperationResult | Promise; + paramsInfo: (params: R) => string, + schema: OperationSchema, + mutualExclusiveFields?: string[] +} + +export type Coercable = any; + +export type OperationSchema = { + [key: string]: SchemaField +}; + +export interface SchemaField { + type: 'number' | 'face' | 'datumAxis' | 'edge' | 'sketchObject' | 'boolean' + defaultValue: Coercable, + optional: boolean, + label?: string +} + +export function loadMDFCommand(mdfCommand: MDFCommand): OperationDescriptor { + return { + id: mdfCommand.id, + label: mdfCommand.label, + icon: mdfCommand.icon, + info: mdfCommand.info, + paramsInfo: mdfCommand.paramsInfo, + onParamsUpdate: (params, name, value) => { + if (mdfCommand.mutualExclusiveFields) { + handleMutualExclusiveFields(mdfCommand.mutualExclusiveFields, params, name, value); + } + }, + run: mdfCommand.run, + // actionParams: { + // ...requiresFaceSelection(1) + // }, + form: generateForm(mdfCommand.schema), + schema: mdfCommand.schema + } +} + +export function handleMutualExclusiveFields(mutualExclusiveFields, params, name, value) { + if (mutualExclusiveFields.includes(name)) { + mutualExclusiveFields.forEach(param => { + if (param !== name) { + delete params[param]; + } + }) + } +} \ No newline at end of file diff --git a/web/app/cad/mdf/mdfExtrudeExample.ts b/web/app/cad/mdf/mdfExtrudeExample.ts new file mode 100644 index 00000000..a2a163f7 --- /dev/null +++ b/web/app/cad/mdf/mdfExtrudeExample.ts @@ -0,0 +1,65 @@ +import { roundValueForPresentation as r } from '../craft/operationHelper'; + + +export const MDF_EXTRUDE_EXAMPLE = { + id: 'EXTRUDE', + label: 'Extrude', + icon: 'img/cad/extrude', + info: 'extrudes 2D sketch', + paramsInfo: ({ value }) => `(${r(value)})`, + mutualExclusiveFields: ['datumAxisVector', 'edgeVector', 'sketchSegmentVector'], + run: (params, ctx) => { + return ctx.craftEngine.cutExtrude(false, params); + }, + schema: { + value: { + type: 'number', + defaultValue: 50, + label: 'height' + }, + wierdField: { + type: 'number', + defaultValue: 50, + label: 'weird field' + }, + prism: { + type: 'number', + min: 0, + defaultValue: 1 + }, + angle: { + type: 'number', + defaultValue: 0 + }, + rotation: { + type: 'number', + defaultValue: 0 + }, + face: { + type: 'face', + initializeBySelection: 0 + }, + datumAxisVector: { + type: 'datumAxis', + optional: true, + label: 'datum axis' + }, + edgeVector: { + type: 'edge', + optional: true, + label: 'edge', + accept: edge => edge.brepEdge.curve.degree === 1 + }, + sketchSegmentVector: { + type: 'sketchObject', + optional: true, + label: 'sketch segment', + accept: obj => obj.isSegment + }, + flip: { + type: 'boolean', + defaultValue: false, + } + + } +} diff --git a/web/app/cad/part/partOperationsPlugin.js b/web/app/cad/part/partOperationsPlugin.js index 9c9a438c..798b9e7a 100644 --- a/web/app/cad/part/partOperationsPlugin.js +++ b/web/app/cad/part/partOperationsPlugin.js @@ -15,13 +15,16 @@ import coneOperation from '../craft/primitives/cone/coneOperation'; import spatialCurveOperation from '../craft/spatialCurve/spatialCurveOperation'; import loftOperation from '../craft/loft/loftOperation'; import {intersectionOperation, subtractOperation, unionOperation} from '../craft/boolean/booleanOperation'; +import { loadMDFCommand } from '../mdf/mdf'; +import { MDF_EXTRUDE_EXAMPLE } from '../mdf/mdfExtrudeExample'; export function activate({services}) { services.operation.registerOperations([ planeOperation, boxOperation, - extrudeOperation, + // extrudeOperation, + loadMDFCommand(MDF_EXTRUDE_EXAMPLE), cutOperation, revolveOperation, filletOperation,