workbenches framework
4
modules/gems/indexType.d.ts
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
export type Index<T> = {
|
||||
[key: string]: T
|
||||
};
|
||||
|
|
@ -1,60 +1,28 @@
|
|||
import { ApplicationContext } from 'context';
|
||||
import { MBrepShell } from 'cad/model/mshell';
|
||||
import { roundValueForPresentation as r } from 'cad/craft/operationHelper';
|
||||
import { createOCCBottle } from './bottle.occ';
|
||||
import { occ2brep } from 'cad/occ/occ2models';
|
||||
import {ApplicationContext} from 'context';
|
||||
import {MBrepShell} from 'cad/model/mshell';
|
||||
import {roundValueForPresentation as r} from 'cad/craft/operationHelper';
|
||||
import {createOCCBottle} from './bottle.occ';
|
||||
import {occ2brep} from 'cad/occ/occ2models';
|
||||
import icon from './icon.svg';
|
||||
import {OperationDescriptor} from "cad/craft/operationPlugin";
|
||||
|
||||
export default {
|
||||
id: 'OCC_BOTTLE',
|
||||
label: 'OCC Bottle',
|
||||
icon: {
|
||||
iconType: 'svg',
|
||||
iconContent: icon
|
||||
},
|
||||
info: 'create occ bottle',
|
||||
mutualExclusiveFields: [],
|
||||
paramsInfo: ({ width, height, thickness, color }) => `(${r(width)} ${r(height)} ${r(thickness)} ${r(color)})`,
|
||||
schema: {
|
||||
width: {
|
||||
type: 'number',
|
||||
defaultValue: 200,
|
||||
label: 'width'
|
||||
},
|
||||
height: {
|
||||
type: 'number',
|
||||
defaultValue: 280,
|
||||
label: 'height'
|
||||
},
|
||||
thickness: {
|
||||
type: 'number',
|
||||
min: 0,
|
||||
label: 'thickness',
|
||||
defaultValue: 150
|
||||
},
|
||||
color: {
|
||||
type: 'string',
|
||||
defaultValue: "red",
|
||||
label: 'Color',
|
||||
enum: [
|
||||
{
|
||||
label: 'Red',
|
||||
value: 'red'
|
||||
},
|
||||
{
|
||||
label: 'Green',
|
||||
value: 'green'
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
run: ({ width, height, thickness, color }, ctx: ApplicationContext) => {
|
||||
const occObj = createOCCBottle(width, height, thickness, ctx.occService.occContext);
|
||||
const mobject = new MBrepShell(occ2brep(occObj, ctx.occService.occContext));
|
||||
console.log(color);
|
||||
return {
|
||||
consumed: [],
|
||||
created: [mobject]
|
||||
};
|
||||
}
|
||||
export const OCCBottle:OperationDescriptor<any> = {
|
||||
id: 'OCC_BOTTLE',
|
||||
label: 'OCC Bottle',
|
||||
icon: {
|
||||
iconType: 'svg',
|
||||
iconContent: icon
|
||||
},
|
||||
info: 'create occ bottle',
|
||||
paramsInfo: ({width, height, thickness, color}) => `(${r(width)} ${r(height)} ${r(thickness)} ${r(color)})`,
|
||||
form: [],
|
||||
run: ({width, height, thickness, color}, ctx: ApplicationContext) => {
|
||||
const occObj = createOCCBottle(width, height, thickness, ctx.occService.occContext);
|
||||
const mobject = new MBrepShell(occ2brep(occObj, ctx.occService.occContext));
|
||||
console.log(color);
|
||||
return {
|
||||
consumed: [],
|
||||
created: [mobject]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
|
||||
export default [
|
||||
];
|
||||
|
|
@ -1,8 +1,13 @@
|
|||
import OCC_BOTTLE from './features/occ_bottle';
|
||||
import OCCBottle from './features/occ_bottle';
|
||||
import {WorkbenchConfig} from "cad/workbench/workbenchService";
|
||||
|
||||
export default {
|
||||
workbenchId: 'examples',
|
||||
features: [
|
||||
OCC_BOTTLE,
|
||||
]
|
||||
export const ExampleWorkspace: WorkbenchConfig = {
|
||||
workbenchId: 'examples',
|
||||
features: [
|
||||
OCCBottle,
|
||||
],
|
||||
actions: [],
|
||||
ui: {
|
||||
toolbar: []
|
||||
}
|
||||
}
|
||||
|
|
@ -9,8 +9,8 @@ interface BooleanParams {
|
|||
boolean: BooleanDefinition
|
||||
}
|
||||
|
||||
const BooleanOperation: OperationDescriptor<BooleanParams> = {
|
||||
id: 'boolean_tool',
|
||||
export const BooleanOperation: OperationDescriptor<BooleanParams> = {
|
||||
id: 'BOOLEAN',
|
||||
label: 'Boolean',
|
||||
icon: 'img/cad/intersection',
|
||||
info: 'Booleans 2D sketch',
|
||||
|
|
@ -46,5 +46,3 @@ const BooleanOperation: OperationDescriptor<BooleanParams> = {
|
|||
},
|
||||
],
|
||||
}
|
||||
|
||||
export default BooleanOperation;
|
||||
|
|
@ -5,7 +5,6 @@ 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";
|
||||
import { negate } from 'cypress/types/lodash';
|
||||
|
||||
|
||||
interface ExtrudeParams {
|
||||
|
|
@ -16,7 +15,7 @@ interface ExtrudeParams {
|
|||
boolean: BooleanDefinition
|
||||
}
|
||||
|
||||
const ExtrudeOperation: OperationDescriptor<ExtrudeParams> = {
|
||||
export const ExtrudeOperation: OperationDescriptor<ExtrudeParams> = {
|
||||
id: 'EXTRUDE',
|
||||
label: 'Extrude',
|
||||
icon: 'img/cad/extrude',
|
||||
|
|
@ -137,5 +136,3 @@ const ExtrudeOperation: OperationDescriptor<ExtrudeParams> = {
|
|||
|
||||
],
|
||||
}
|
||||
|
||||
export default ExtrudeOperation;
|
||||
|
Before Width: | Height: | Size: 729 B After Width: | Height: | Size: 729 B |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.8 KiB |
91
modules/workbenches/modeler/features/fillet/index.ts
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
import {ApplicationContext} from 'context';
|
||||
import {roundValueForPresentation as r} from 'cad/craft/operationHelper';
|
||||
|
||||
import {EntityKind} from "cad/model/entities";
|
||||
import {OperationDescriptor} from "cad/craft/operationPlugin";
|
||||
|
||||
export const FilletOperation: OperationDescriptor<any> = {
|
||||
id: 'FILLET_TOOL',
|
||||
label: 'Fillet/Chapher',
|
||||
icon: 'img/cad/fillet',
|
||||
info: 'Fillet/Champher',
|
||||
paramsInfo: ({size, opperationType,}) => `(${r(size)} ${r(opperationType)}})`,
|
||||
form: [
|
||||
{
|
||||
type: 'selection',
|
||||
name: 'edges',
|
||||
capture: [EntityKind.EDGE],
|
||||
label: 'edges',
|
||||
multi: true,
|
||||
defaultValue: {
|
||||
usePreselection: true,
|
||||
preselectionIndex: 0
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'choice',
|
||||
style: "dropdown",
|
||||
label: 'opperationType',
|
||||
name: 'opperationType',
|
||||
values: ["Fillet", "Champher"],
|
||||
defaultValue: "Fillet",
|
||||
},
|
||||
{
|
||||
type: 'number',
|
||||
label: 'size',
|
||||
name: 'size',
|
||||
defaultValue: 5,
|
||||
},
|
||||
],
|
||||
|
||||
run: (params, ctx: ApplicationContext) => {
|
||||
|
||||
let occ = ctx.occService;
|
||||
const oci = occ.commandInterface;
|
||||
let returnObject = {
|
||||
consumed: [],
|
||||
created: [],
|
||||
}
|
||||
|
||||
var edgesAndValue = [];
|
||||
|
||||
//add all the edges and size to seperate arrays for each shell that edges are selected from
|
||||
|
||||
params.edges.forEach((edge) => {
|
||||
if (!returnObject.consumed.includes(edge.shell)) {
|
||||
returnObject.consumed.push(edge.shell);
|
||||
edgesAndValue[edge.shell.id] = [];
|
||||
}
|
||||
|
||||
if (params.opperationType == "Fillet") {
|
||||
//order of parameters is diferent between fillet and champher
|
||||
edgesAndValue[edge.shell.id].push(params.size);
|
||||
edgesAndValue[edge.shell.id].push(edge);
|
||||
}
|
||||
if (params.opperationType == "Champher") {
|
||||
//order of parameters is diferent between fillet and champher
|
||||
edgesAndValue[edge.shell.id].push(edge);
|
||||
edgesAndValue[edge.shell.id].push(params.size);
|
||||
}
|
||||
});
|
||||
|
||||
//perform the opperations on each of the bodies.
|
||||
Object.keys(edgesAndValue).forEach((shellToOpperateOnName) => {
|
||||
var shellToOpperateOn = edgesAndValue[shellToOpperateOnName];
|
||||
var newShellName = shellToOpperateOnName + "f";
|
||||
|
||||
if (params.opperationType == "Fillet") oci.blend(newShellName, shellToOpperateOn[1].shell, ...shellToOpperateOn);
|
||||
if (params.opperationType == "Champher") oci.chamf(newShellName, shellToOpperateOn[0].shell, ...shellToOpperateOn);
|
||||
|
||||
returnObject.created.push(occ.io.getShell(newShellName));
|
||||
});
|
||||
|
||||
|
||||
console.log(returnObject);
|
||||
|
||||
|
||||
return returnObject;
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
import { ApplicationContext } from 'context';
|
||||
import { MBrepShell } from 'cad/model/mshell';
|
||||
import { roundValueForPresentation as r } from 'cad/craft/operationHelper';
|
||||
import { occ2brep } from 'cad/occ/occ2models';
|
||||
|
||||
import { EntityKind } from "cad/model/entities";
|
||||
|
||||
export default {
|
||||
id: 'fillet_tool',
|
||||
label: 'Fillet/Chapher',
|
||||
icon: 'img/cad/fillet',
|
||||
info: 'Fillet/Champher',
|
||||
mutualExclusiveFields: [],
|
||||
paramsInfo: ({ size, opperationType, }) => `(${r(size)} ${r(opperationType)}})`,
|
||||
form: [
|
||||
{
|
||||
type: 'selection',
|
||||
name: 'edges',
|
||||
capture: [EntityKind.EDGE],
|
||||
label: 'edges',
|
||||
multi: true,
|
||||
defaultValue: {
|
||||
usePreselection: true,
|
||||
preselectionIndex: 0
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'choice',
|
||||
style: "dropdown",
|
||||
label: 'opperationType',
|
||||
name: 'opperationType',
|
||||
values: ["Fillet", "Champher"],
|
||||
defaultValue: "Fillet",
|
||||
},
|
||||
{
|
||||
type: 'number',
|
||||
label: 'size',
|
||||
name: 'size',
|
||||
defaultValue: 5,
|
||||
},
|
||||
],
|
||||
|
||||
run: (params, ctx: ApplicationContext) => {
|
||||
|
||||
let occ = ctx.occService;
|
||||
const oci = occ.commandInterface;
|
||||
let returnObject = {
|
||||
consumed: [],
|
||||
created: [],
|
||||
}
|
||||
|
||||
var edgesAndValue = [];
|
||||
|
||||
//add all the edges and size to seperate arrays for each shell that edges are selected from
|
||||
|
||||
params.edges.forEach((edge) => {
|
||||
if (!returnObject.consumed.includes(edge.shell)) {
|
||||
returnObject.consumed.push(edge.shell);
|
||||
edgesAndValue[edge.shell.id] = [];
|
||||
}
|
||||
|
||||
if (params.opperationType == "Fillet") {
|
||||
//order of parameters is diferent between fillet and champher
|
||||
edgesAndValue[edge.shell.id].push(params.size);
|
||||
edgesAndValue[edge.shell.id].push(edge);
|
||||
}
|
||||
if (params.opperationType == "Champher") {
|
||||
//order of parameters is diferent between fillet and champher
|
||||
edgesAndValue[edge.shell.id].push(edge);
|
||||
edgesAndValue[edge.shell.id].push(params.size);
|
||||
}
|
||||
});
|
||||
|
||||
//perform the opperations on each of the bodies.
|
||||
Object.keys(edgesAndValue).forEach((shellToOpperateOnName) => {
|
||||
var shellToOpperateOn = edgesAndValue[shellToOpperateOnName];
|
||||
var newShellName = shellToOpperateOnName + "f";
|
||||
|
||||
if (params.opperationType == "Fillet") oci.blend(newShellName, shellToOpperateOn[1].shell, ...shellToOpperateOn);
|
||||
if (params.opperationType == "Champher") oci.chamf(newShellName, shellToOpperateOn[0].shell, ...shellToOpperateOn);
|
||||
|
||||
returnObject.created.push(occ.io.getShell(newShellName));
|
||||
});
|
||||
|
||||
|
||||
console.log(returnObject);
|
||||
|
||||
|
||||
return returnObject;
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
|
@ -14,8 +14,8 @@ interface HoleParams {
|
|||
holeType: string;
|
||||
}
|
||||
|
||||
const HoleOperation: OperationDescriptor<HoleParams> = {
|
||||
id: 'hole_tool',
|
||||
export const HoleOperation: OperationDescriptor<HoleParams> = {
|
||||
id: 'HOLE_TOOL',
|
||||
label: 'hole',
|
||||
icon: 'img/cad/Shell',
|
||||
info: 'creates hole features',
|
||||
|
|
@ -136,5 +136,3 @@ const HoleOperation: OperationDescriptor<HoleParams> = {
|
|||
},
|
||||
],
|
||||
}
|
||||
|
||||
export default HoleOperation;
|
||||
|
|
@ -1,11 +1,8 @@
|
|||
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";
|
||||
import { negate } from 'cypress/types/lodash';
|
||||
import {roundValueForPresentation as r} from 'cad/craft/operationHelper';
|
||||
import {ApplicationContext} from "context";
|
||||
import {EntityKind} from "cad/model/entities";
|
||||
import {BooleanDefinition} from "cad/craft/schema/common/BooleanDefinition";
|
||||
import {OperationDescriptor} from "cad/craft/operationPlugin";
|
||||
import {MSketchLoop} from "cad/model/mloop";
|
||||
|
||||
|
||||
|
|
@ -15,8 +12,8 @@ interface LoftParams {
|
|||
loftType: string;
|
||||
}
|
||||
|
||||
const LoftOperation: OperationDescriptor<LoftParams> = {
|
||||
id: 'loft',
|
||||
export const LoftOperation: OperationDescriptor<LoftParams> = {
|
||||
id: 'LOFT',
|
||||
label: 'Loft',
|
||||
icon: 'img/cad/loft',
|
||||
info: 'Lofts 2D sketch',
|
||||
|
|
@ -81,5 +78,3 @@ const LoftOperation: OperationDescriptor<LoftParams> = {
|
|||
|
||||
],
|
||||
}
|
||||
|
||||
export default LoftOperation;
|
||||
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.8 KiB |
|
|
@ -13,8 +13,8 @@ interface PrimitiveBoxParams {
|
|||
boolean: BooleanDefinition,
|
||||
}
|
||||
|
||||
const PrimitiveBoxOperation: OperationDescriptor<PrimitiveBoxParams> = {
|
||||
id: 'primitive_box',
|
||||
export const PrimitiveBoxOperation: OperationDescriptor<PrimitiveBoxParams> = {
|
||||
id: 'PRIMITIVE_BOX',
|
||||
label: 'Primitive Box',
|
||||
icon: 'img/cad/cube',
|
||||
info: 'Primitive Box',
|
||||
|
|
@ -73,5 +73,3 @@ const PrimitiveBoxOperation: OperationDescriptor<PrimitiveBoxParams> = {
|
|||
|
||||
},
|
||||
}
|
||||
|
||||
export default PrimitiveBoxOperation;
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
|
@ -13,8 +13,8 @@ interface PrimitiveConeParams {
|
|||
boolean: BooleanDefinition,
|
||||
}
|
||||
|
||||
const PrimitiveConeOperation: OperationDescriptor<PrimitiveConeParams> = {
|
||||
id: 'primitive_cone',
|
||||
export const PrimitiveConeOperation: OperationDescriptor<PrimitiveConeParams> = {
|
||||
id: 'PRIMITIVE_CONE',
|
||||
label: 'Primitive Cone',
|
||||
icon: 'img/cad/cone',
|
||||
info: 'Primitive Cone',
|
||||
|
|
@ -73,5 +73,3 @@ const PrimitiveConeOperation: OperationDescriptor<PrimitiveConeParams> = {
|
|||
|
||||
},
|
||||
}
|
||||
|
||||
export default PrimitiveConeOperation;
|
||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
|
@ -0,0 +1,68 @@
|
|||
import {ApplicationContext} from 'context';
|
||||
import {roundValueForPresentation as r} from 'cad/craft/operationHelper';
|
||||
import {EntityKind} from "cad/model/entities";
|
||||
import {BooleanDefinition} from "cad/craft/schema/common/BooleanDefinition";
|
||||
import {OperationDescriptor} from "cad/craft/operationPlugin";
|
||||
|
||||
|
||||
interface PrimitiveCylinderParams {
|
||||
diameter: number,
|
||||
height: number,
|
||||
locations: {},
|
||||
boolean: BooleanDefinition,
|
||||
}
|
||||
|
||||
export const PrimitiveCylinderOperation: OperationDescriptor<PrimitiveCylinderParams> = {
|
||||
id: 'PRIMITIVE_CYLINDER',
|
||||
label: 'Primitive cylinder',
|
||||
icon: 'img/cad/cylinder',
|
||||
info: 'Primitive Cylinder',
|
||||
paramsInfo: ({height, diameter}) => `(${r(height)} , ${r(diameter)} )`,
|
||||
form: [
|
||||
{
|
||||
type: 'number',
|
||||
label: 'Diameter',
|
||||
name: 'diameter',
|
||||
defaultValue: 50,
|
||||
},
|
||||
{
|
||||
type: 'number',
|
||||
label: 'Height',
|
||||
name: 'height',
|
||||
defaultValue: 50,
|
||||
},
|
||||
{
|
||||
type: 'selection',
|
||||
name: 'locations',
|
||||
capture: [EntityKind.DATUM],
|
||||
label: 'locations',
|
||||
multi: false,
|
||||
optional: true,
|
||||
defaultValue: {
|
||||
usePreselection: true,
|
||||
preselectionIndex: 0
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
type: 'boolean',
|
||||
name: 'boolean',
|
||||
label: 'boolean',
|
||||
optional: true,
|
||||
}
|
||||
|
||||
],
|
||||
|
||||
|
||||
run: (params: PrimitiveCylinderParams, ctx: ApplicationContext) => {
|
||||
|
||||
let occ = ctx.occService;
|
||||
const oci = occ.commandInterface;
|
||||
|
||||
//pcylinder cy 5 10
|
||||
oci.pcylinder("cy", params.diameter / 2, params.height);
|
||||
|
||||
return occ.utils.applyBooleanModifier(["cy"], params.boolean);
|
||||
|
||||
},
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.9 KiB |
|
|
@ -0,0 +1,62 @@
|
|||
import {ApplicationContext} from 'context';
|
||||
import {roundValueForPresentation as r} from 'cad/craft/operationHelper';
|
||||
import {EntityKind} from "cad/model/entities";
|
||||
import {BooleanDefinition} from "cad/craft/schema/common/BooleanDefinition";
|
||||
import {OperationDescriptor} from "cad/craft/operationPlugin";
|
||||
|
||||
|
||||
interface PrimitiveSphereParams {
|
||||
radius: number,
|
||||
locations: {},
|
||||
boolean: BooleanDefinition,
|
||||
}
|
||||
|
||||
export const PrimitiveSphereOperation: OperationDescriptor<PrimitiveSphereParams> = {
|
||||
id: 'PRIMITIVE_SPHERE',
|
||||
label: 'Primitive Sphere',
|
||||
icon: 'img/cad/sphere',
|
||||
info: 'Primitive Sphere',
|
||||
paramsInfo: ({radius,}) => `(${r(radius)} )`,
|
||||
form: [
|
||||
{
|
||||
type: 'number',
|
||||
label: 'Radius',
|
||||
name: 'radius',
|
||||
defaultValue: 50,
|
||||
},
|
||||
|
||||
{
|
||||
type: 'selection',
|
||||
name: 'locations',
|
||||
capture: [EntityKind.DATUM],
|
||||
label: 'locations',
|
||||
multi: false,
|
||||
optional: true,
|
||||
defaultValue: {
|
||||
usePreselection: true,
|
||||
preselectionIndex: 0
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
type: 'boolean',
|
||||
name: 'boolean',
|
||||
label: 'boolean',
|
||||
optional: true,
|
||||
}
|
||||
|
||||
],
|
||||
|
||||
|
||||
run: (params: PrimitiveSphereParams, ctx: ApplicationContext) => {
|
||||
|
||||
let occ = ctx.occService;
|
||||
const oci = occ.commandInterface;
|
||||
|
||||
//pSphere cy 5 10
|
||||
oci.psphere("Sphere", params.radius);
|
||||
|
||||
return occ.utils.applyBooleanModifier(["Sphere"], params.boolean);
|
||||
|
||||
},
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
70
modules/workbenches/modeler/features/primitiveTorus/index.ts
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
import {ApplicationContext} from 'context';
|
||||
import {roundValueForPresentation as r} from 'cad/craft/operationHelper';
|
||||
import {EntityKind} from "cad/model/entities";
|
||||
import {BooleanDefinition} from "cad/craft/schema/common/BooleanDefinition";
|
||||
import {OperationDescriptor} from "cad/craft/operationPlugin";
|
||||
|
||||
|
||||
interface PrimitiveTorusParams {
|
||||
radius: number,
|
||||
tubeRadius: number,
|
||||
locations: {},
|
||||
boolean: BooleanDefinition,
|
||||
}
|
||||
|
||||
const PrimitiveTorusOperation: OperationDescriptor<PrimitiveTorusParams> = {
|
||||
id: 'PRIMITIVE_TORUS',
|
||||
label: 'Primitive Torus',
|
||||
icon: 'img/cad/torus',
|
||||
info: 'Primitive Torus',
|
||||
paramsInfo: ({radius, tubeRadius}) => `(${r(radius)} , ${r(tubeRadius)} )`,
|
||||
form: [
|
||||
{
|
||||
type: 'number',
|
||||
label: 'Radius',
|
||||
name: 'radius',
|
||||
defaultValue: 50,
|
||||
},
|
||||
{
|
||||
type: 'number',
|
||||
label: 'Tube Radius',
|
||||
name: 'tubeRadius',
|
||||
defaultValue: 10,
|
||||
},
|
||||
{
|
||||
type: 'selection',
|
||||
name: 'locations',
|
||||
capture: [EntityKind.DATUM],
|
||||
label: 'locations',
|
||||
multi: false,
|
||||
optional: true,
|
||||
defaultValue: {
|
||||
usePreselection: true,
|
||||
preselectionIndex: 0
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
type: 'boolean',
|
||||
name: 'boolean',
|
||||
label: 'boolean',
|
||||
optional: true,
|
||||
}
|
||||
|
||||
],
|
||||
|
||||
|
||||
run: (params: PrimitiveTorusParams, ctx: ApplicationContext) => {
|
||||
|
||||
let occ = ctx.occService;
|
||||
const oci = occ.commandInterface;
|
||||
|
||||
//pTorus cy 5 10
|
||||
oci.ptorus("torus", params.radius, params.tubeRadius);
|
||||
|
||||
return occ.utils.applyBooleanModifier(["torus"], params.boolean);
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
export default PrimitiveTorusOperation;
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
import { ApplicationContext } from 'context';
|
||||
import { roundValueForPresentation as r } from 'cad/craft/operationHelper';
|
||||
import { EntityKind } from "cad/model/entities";
|
||||
import { BooleanDefinition } from "cad/craft/schema/common/BooleanDefinition";
|
||||
import { OperationDescriptor } from "cad/craft/operationPlugin";
|
||||
|
||||
|
||||
interface PrimitiveCylinderParams {
|
||||
diameter: number,
|
||||
height: number,
|
||||
locations: {},
|
||||
boolean: BooleanDefinition,
|
||||
}
|
||||
|
||||
const PrimitiveCylinderOperation: OperationDescriptor<PrimitiveCylinderParams> = {
|
||||
id: 'primitive_cylinder',
|
||||
label: 'Primitive cylinder',
|
||||
icon: 'img/cad/cylinder',
|
||||
info: 'Primitive Cylinder',
|
||||
paramsInfo: ({ height, diameter}) => `(${r(height)} , ${r(diameter)} )`,
|
||||
form: [
|
||||
{
|
||||
type: 'number',
|
||||
label: 'Diameter',
|
||||
name: 'diameter',
|
||||
defaultValue: 50,
|
||||
},
|
||||
{
|
||||
type: 'number',
|
||||
label: 'Height',
|
||||
name: 'height',
|
||||
defaultValue: 50,
|
||||
},
|
||||
{
|
||||
type: 'selection',
|
||||
name: 'locations',
|
||||
capture: [EntityKind.DATUM],
|
||||
label: 'locations',
|
||||
multi: false,
|
||||
optional: true,
|
||||
defaultValue: {
|
||||
usePreselection: true,
|
||||
preselectionIndex: 0
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
type: 'boolean',
|
||||
name: 'boolean',
|
||||
label: 'boolean',
|
||||
optional: true,
|
||||
}
|
||||
|
||||
],
|
||||
|
||||
|
||||
run: (params: PrimitiveCylinderParams, ctx: ApplicationContext) => {
|
||||
|
||||
let occ = ctx.occService;
|
||||
const oci = occ.commandInterface;
|
||||
|
||||
//pcylinder cy 5 10
|
||||
oci.pcylinder("cy", params.diameter/2, params.height);
|
||||
|
||||
return occ.utils.applyBooleanModifier(["cy"], params.boolean);
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
export default PrimitiveCylinderOperation;
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
import { ApplicationContext } from 'context';
|
||||
import { roundValueForPresentation as r } from 'cad/craft/operationHelper';
|
||||
import { EntityKind } from "cad/model/entities";
|
||||
import { BooleanDefinition } from "cad/craft/schema/common/BooleanDefinition";
|
||||
import { OperationDescriptor } from "cad/craft/operationPlugin";
|
||||
|
||||
|
||||
interface PrimitiveSphereParams {
|
||||
radius: number,
|
||||
locations: {},
|
||||
boolean: BooleanDefinition,
|
||||
}
|
||||
|
||||
const PrimitiveSphereOperation: OperationDescriptor<PrimitiveSphereParams> = {
|
||||
id: 'primitive_sphere',
|
||||
label: 'Primitive Sphere',
|
||||
icon: 'img/cad/sphere',
|
||||
info: 'Primitive Sphere',
|
||||
paramsInfo: ({ radius, }) => `(${r(radius)} )`,
|
||||
form: [
|
||||
{
|
||||
type: 'number',
|
||||
label: 'Radius',
|
||||
name: 'radius',
|
||||
defaultValue: 50,
|
||||
},
|
||||
|
||||
{
|
||||
type: 'selection',
|
||||
name: 'locations',
|
||||
capture: [EntityKind.DATUM],
|
||||
label: 'locations',
|
||||
multi: false,
|
||||
optional: true,
|
||||
defaultValue: {
|
||||
usePreselection: true,
|
||||
preselectionIndex: 0
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
type: 'boolean',
|
||||
name: 'boolean',
|
||||
label: 'boolean',
|
||||
optional: true,
|
||||
}
|
||||
|
||||
],
|
||||
|
||||
|
||||
run: (params: PrimitiveSphereParams, ctx: ApplicationContext) => {
|
||||
|
||||
let occ = ctx.occService;
|
||||
const oci = occ.commandInterface;
|
||||
|
||||
//pSphere cy 5 10
|
||||
oci.psphere("Sphere", params.radius);
|
||||
|
||||
return occ.utils.applyBooleanModifier(["Sphere"], params.boolean);
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
export default PrimitiveSphereOperation;
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
import { ApplicationContext } from 'context';
|
||||
import { roundValueForPresentation as r } from 'cad/craft/operationHelper';
|
||||
import { EntityKind } from "cad/model/entities";
|
||||
import { BooleanDefinition } from "cad/craft/schema/common/BooleanDefinition";
|
||||
import { OperationDescriptor } from "cad/craft/operationPlugin";
|
||||
|
||||
|
||||
interface PrimitiveTorusParams {
|
||||
radius: number,
|
||||
tubeRadius: number,
|
||||
locations: {},
|
||||
boolean: BooleanDefinition,
|
||||
}
|
||||
|
||||
const PrimitiveTorusOperation: OperationDescriptor<PrimitiveTorusParams> = {
|
||||
id: 'primitive_torus',
|
||||
label: 'Primitive Torus',
|
||||
icon: 'img/cad/torus',
|
||||
info: 'Primitive Torus',
|
||||
paramsInfo: ({ radius, tubeRadius }) => `(${r(radius)} , ${r(tubeRadius)} )`,
|
||||
form: [
|
||||
{
|
||||
type: 'number',
|
||||
label: 'Radius',
|
||||
name: 'radius',
|
||||
defaultValue: 50,
|
||||
},
|
||||
{
|
||||
type: 'number',
|
||||
label: 'Tube Radius',
|
||||
name: 'tubeRadius',
|
||||
defaultValue: 10,
|
||||
},
|
||||
{
|
||||
type: 'selection',
|
||||
name: 'locations',
|
||||
capture: [EntityKind.DATUM],
|
||||
label: 'locations',
|
||||
multi: false,
|
||||
optional: true,
|
||||
defaultValue: {
|
||||
usePreselection: true,
|
||||
preselectionIndex: 0
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
type: 'boolean',
|
||||
name: 'boolean',
|
||||
label: 'boolean',
|
||||
optional: true,
|
||||
}
|
||||
|
||||
],
|
||||
|
||||
|
||||
run: (params: PrimitiveTorusParams, ctx: ApplicationContext) => {
|
||||
|
||||
let occ = ctx.occService;
|
||||
const oci = occ.commandInterface;
|
||||
|
||||
//pTorus cy 5 10
|
||||
oci.ptorus("torus", params.radius, params.tubeRadius);
|
||||
|
||||
return occ.utils.applyBooleanModifier(["torus"], params.boolean);
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
export default PrimitiveTorusOperation;
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
|
||||
export default [
|
||||
];
|
||||
|
|
@ -13,8 +13,8 @@ interface RevolveParams {
|
|||
boolean: BooleanDefinition
|
||||
}
|
||||
|
||||
const RevolveOperation: OperationDescriptor<RevolveParams> = {
|
||||
id: 'Revolve',
|
||||
export const RevolveOperation: OperationDescriptor<RevolveParams> = {
|
||||
id: 'REVOLVE',
|
||||
label: 'Revolve',
|
||||
icon: 'img/cad/revolve',
|
||||
info: 'Revolves 2D sketch',
|
||||
|
|
@ -77,5 +77,3 @@ const RevolveOperation: OperationDescriptor<RevolveParams> = {
|
|||
|
||||
],
|
||||
}
|
||||
|
||||
export default RevolveOperation;
|
||||
|
|
@ -10,8 +10,8 @@ interface ShellParams {
|
|||
faces: [MFace];
|
||||
}
|
||||
|
||||
const ShellOperation: OperationDescriptor<ShellParams> = {
|
||||
id: 'shell_tool',
|
||||
export const ShellOperation: OperationDescriptor<ShellParams> = {
|
||||
id: 'SHELL_TOOL',
|
||||
label: 'Shell',
|
||||
icon: 'img/cad/shell',
|
||||
info: 'Shells 2D sketch',
|
||||
|
|
@ -76,5 +76,3 @@ const ShellOperation: OperationDescriptor<ShellParams> = {
|
|||
},
|
||||
],
|
||||
}
|
||||
|
||||
export default ShellOperation;
|
||||
|
|
@ -1,31 +1,47 @@
|
|||
import EXTRUDE from './features/extrude/extrude.operation';
|
||||
import RevolveOperation from './features/revolve_tool/revolve.operation';
|
||||
import primitive_box from './features/primitive_box';
|
||||
import primitive_cone from './features/primitive_cone';
|
||||
import primitive_cylinder from './features/primitive_cylinder';
|
||||
import primitive_sphere from './features/primitive_sphere';
|
||||
import primitive_torus from './features/primitive_torus';
|
||||
import hole_tool from './features/hole_tool';
|
||||
import fillet_tool from './features/fillet_tool';
|
||||
import boolean_tool from './features/boolean_tool/boolean.operation';
|
||||
import ShellOperation from './features/shell_tool/shell.operation';
|
||||
import loft from './features/loft/loft.operation'
|
||||
import {ExtrudeOperation} from './features/extrude/extrude.operation';
|
||||
import {LoftOperation} from './features/loft/loft.operation'
|
||||
import {WorkbenchConfig} from "cad/workbench/workbenchService";
|
||||
import {PrimitiveBoxOperation} from "workbenches/modeler/features/primitiveBox";
|
||||
import {PrimitiveConeOperation} from "workbenches/modeler/features/primitiveCone";
|
||||
import {PrimitiveCylinderOperation} from "workbenches/modeler/features/primitiveCylinder";
|
||||
import {PrimitiveSphereOperation} from "workbenches/modeler/features/primitiveSphere";
|
||||
import PrimitiveTorusOperation from "workbenches/modeler/features/primitiveTorus";
|
||||
import {HoleOperation} from "workbenches/modeler/features/hole";
|
||||
import {FilletOperation} from "workbenches/modeler/features/fillet";
|
||||
import {BooleanOperation} from "workbenches/modeler/features/boolean/boolean.operation";
|
||||
import {RevolveOperation} from "workbenches/modeler/features/revolve/revolve.operation";
|
||||
import {ShellOperation} from "workbenches/modeler/features/shell/shell.operation";
|
||||
|
||||
export default {
|
||||
export const ModelerWorkspace: WorkbenchConfig = {
|
||||
|
||||
workbenchId: 'modeler',
|
||||
features: [
|
||||
EXTRUDE,
|
||||
primitive_box,
|
||||
primitive_cone,
|
||||
primitive_cylinder,
|
||||
primitive_sphere,
|
||||
primitive_torus,
|
||||
hole_tool,
|
||||
fillet_tool,
|
||||
RevolveOperation,
|
||||
boolean_tool,
|
||||
ShellOperation,
|
||||
loft,
|
||||
workbenchId: 'modeler',
|
||||
features: [
|
||||
ExtrudeOperation,
|
||||
PrimitiveBoxOperation,
|
||||
PrimitiveConeOperation,
|
||||
PrimitiveCylinderOperation,
|
||||
PrimitiveSphereOperation,
|
||||
PrimitiveTorusOperation,
|
||||
HoleOperation,
|
||||
FilletOperation,
|
||||
RevolveOperation,
|
||||
BooleanOperation,
|
||||
ShellOperation,
|
||||
LoftOperation,
|
||||
],
|
||||
actions: [],
|
||||
ui:{
|
||||
toolbar: [
|
||||
'DATUM_CREATE', 'PLANE', 'EditFace', '-',
|
||||
"OCC_BOTTLE", '-',
|
||||
"EXTRUDE", "REVOLVE", "LOFT","-", "BOOLEAN", "SHELL_TOOL",
|
||||
"PRIMITIVE_CYLINDER",
|
||||
"PRIMITIVE_BOX",
|
||||
"PRIMITIVE_CONE",
|
||||
"PRIMITIVE_SPHERE",
|
||||
"PRIMITIVE_TORUS",
|
||||
"HOLE_TOOL",
|
||||
"FILLET_TOOL"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
import ModelerWorkbench from './modeler';
|
||||
import ExampleWorkbench from './examples';
|
||||
import {ModelerWorkspace} from "workbenches/modeler";
|
||||
import {ExampleWorkspace} from "workbenches/examples";
|
||||
import {WorkbenchConfig} from "cad/workbench/workbenchService";
|
||||
|
||||
export default [
|
||||
ModelerWorkbench,
|
||||
ExampleWorkbench,
|
||||
export const WorkbenchRegistry: WorkbenchConfig[] = [
|
||||
ModelerWorkspace,
|
||||
// ExampleWorkspace,
|
||||
]
|
||||
|
|
@ -2,14 +2,13 @@ import {enableAnonymousActionHint} from './anonHint';
|
|||
import * as stream from 'lstream';
|
||||
import {state, StateStream, Stream} from 'lstream';
|
||||
import {LOG_FLAGS} from '../logFlags';
|
||||
import {CoreContext} from "context";
|
||||
import {ApplicationContext} from "context";
|
||||
import {IconType} from "react-icons";
|
||||
|
||||
export function activate(context: CoreContext) {
|
||||
export function activate(context: ApplicationContext) {
|
||||
|
||||
let {streams} = context;
|
||||
|
||||
|
||||
const appearanceStreams: ActionAppearanceStreams = {};
|
||||
const stateStreams: ActionStateStreams = {};
|
||||
const hint$: StateStream<Hint> = state(null);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ export default {
|
|||
},
|
||||
parallelTo: {
|
||||
type: 'entity',
|
||||
allowedKinds: 'face',
|
||||
allowedKinds: ['face'],
|
||||
optional: true,
|
||||
},
|
||||
depth: {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import {isMenuAction} from '../menu/menuPlugin';
|
|||
import {menuAboveElementHint} from '../menu/menuUtils';
|
||||
import {useStream} from "ui/effects";
|
||||
import {ActionButtonBehavior} from "../../actions/ActionButtonBehavior";
|
||||
import {NonExistentAppearance, NonExistentState} from "cad/dom/components/PlugableToolbar";
|
||||
|
||||
export default function PlugableControlBar() {
|
||||
return <ControlBar left={<LeftGroup />} right={<RightGroup />}/>;
|
||||
|
|
@ -44,8 +45,8 @@ function ConnectedActionButton(props) {
|
|||
|
||||
const actionId = props.actionId;
|
||||
|
||||
const actionAppearance = useStream(ctx => ctx.streams.action.appearance[actionId]);
|
||||
const actionState = useStream(ctx => ctx.streams.action.state[actionId]);
|
||||
const actionAppearance = useStream(ctx => (ctx.streams.action.appearance[actionId] || NonExistentAppearance(actionId)));
|
||||
const actionState = useStream(ctx => ctx.streams.action.state[actionId] || NonExistentState);
|
||||
|
||||
if (!actionAppearance || !actionState) {
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -5,9 +5,11 @@ import ImgIcon from 'ui/components/ImgIcon';
|
|||
import {toIdAndOverrides} from '../../actions/actionRef';
|
||||
import {ActionButtonBehavior} from '../../actions/ActionButtonBehavior';
|
||||
import capitalize from 'gems/capitalize';
|
||||
import {combine} from 'lstream';
|
||||
import {constant} from 'lstream';
|
||||
import {useStream} from "ui/effects";
|
||||
import {NoIcon} from "../../../sketcher/icons/NoIcon";
|
||||
import {GrCircleQuestion} from "react-icons/all";
|
||||
import {memoize} from "lodash/function";
|
||||
|
||||
function ConfigurableToolbar({actions, size, ...props}) {
|
||||
return <Toolbar size={size} {...props}>
|
||||
|
|
@ -64,11 +66,32 @@ function ActionButton({label, icon, icon96, icon32, cssIcons, symbol, size = 'la
|
|||
</ToolbarButton>
|
||||
}
|
||||
|
||||
const K = constant({
|
||||
info: "unknown action: ",
|
||||
label: "unknown action ",
|
||||
icon: GrCircleQuestion
|
||||
})
|
||||
|
||||
export const NonExistentAppearance = memoize((actionId) => {
|
||||
debugger
|
||||
return constant({
|
||||
info: "unknown action: " + actionId,
|
||||
label: "unknown action " + actionId,
|
||||
icon: () => <span>?{actionId}?</span>
|
||||
})
|
||||
})
|
||||
|
||||
export const NonExistentState = constant({
|
||||
enabled: true,
|
||||
visible: true
|
||||
});
|
||||
|
||||
|
||||
export function ConnectedActionButton(props) {
|
||||
|
||||
const actionId = props.actionId;
|
||||
const actionAppearance = useStream(ctx => ctx.streams.action.appearance[actionId]);
|
||||
const actionState = useStream(ctx => ctx.streams.action.state[actionId]);
|
||||
const actionAppearance = useStream(ctx => (ctx.streams.action.appearance[actionId] || NonExistentAppearance(actionId)));
|
||||
const actionState = useStream(ctx => ctx.streams.action.state[actionId] || NonExistentState);
|
||||
if (!actionAppearance || !actionState) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import {ActionButtonBehavior} from '../../actions/ActionButtonBehavior';
|
|||
import connect from 'ui/connect';
|
||||
import {combine, merger} from 'lstream';
|
||||
import {useStream} from "ui/effects";
|
||||
import {NonExistentAppearance, NonExistentState} from "cad/dom/components/PlugableToolbar";
|
||||
|
||||
function MenuHolder({menus}) {
|
||||
return menus.map(({id, actions}) => <ConnectedActionMenu key={id} menuId={id} actions={actions} />);
|
||||
|
|
@ -58,9 +59,8 @@ export function ConnectedMenuItem(props) {
|
|||
|
||||
const actionId = props.actionId;
|
||||
|
||||
const actionAppearance = useStream(ctx => ctx.streams.action.appearance[actionId]);
|
||||
const actionState = useStream(ctx => ctx.streams.action.state[actionId]);
|
||||
|
||||
const actionAppearance = useStream(ctx => (ctx.streams.action.appearance[actionId] || NonExistentAppearance(actionId)));
|
||||
const actionState = useStream(ctx => ctx.streams.action.state[actionId] || NonExistentState);
|
||||
|
||||
if (!actionAppearance || !actionState) {
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -1,41 +0,0 @@
|
|||
import {state} from 'lstream';
|
||||
|
||||
export function defineStreams({streams}) {
|
||||
|
||||
streams.ui = {
|
||||
controlBars: {
|
||||
left: state([]),
|
||||
right: state([])
|
||||
},
|
||||
toolbars: {
|
||||
headsUp: state([]),
|
||||
headsUpShowTitles: state(true),
|
||||
headsUpQuickActions: state([]),
|
||||
sketcherGeneral: state([]),
|
||||
sketcherConstraints: state([]),
|
||||
sketcherControl: state([])
|
||||
},
|
||||
floatViews: state([]),
|
||||
sockets: {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
export function activate({streams, services}) {
|
||||
|
||||
let components = new Map();
|
||||
const registerComponent = (id, Component) => components.set(id, Component);
|
||||
const getComponent = id => components.get(id);
|
||||
|
||||
let floatViewDescriptors = new Map();
|
||||
|
||||
function registerFloatView(id, Component, title, icon) {
|
||||
floatViewDescriptors.set(id, {Component, title, icon});
|
||||
streams.ui.floatViews.mutate(views => views.push(id));
|
||||
}
|
||||
const getFloatView = id => floatViewDescriptors.get(id);
|
||||
|
||||
services.ui = {
|
||||
registerComponent, getComponent, registerFloatView, getFloatView
|
||||
}
|
||||
}
|
||||
78
web/app/cad/dom/uiPlugin.ts
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
import {state, StateStream} from 'lstream';
|
||||
|
||||
export function defineStreams({streams}) {
|
||||
|
||||
streams.ui = {
|
||||
controlBars: {
|
||||
left: state([]),
|
||||
right: state([])
|
||||
},
|
||||
toolbars: {
|
||||
headsUp: state([]),
|
||||
headsUpShowTitles: state(true),
|
||||
headsUpQuickActions: state([]),
|
||||
sketcherGeneral: state([]),
|
||||
sketcherConstraints: state([]),
|
||||
sketcherControl: state([])
|
||||
},
|
||||
floatViews: state([]),
|
||||
sockets: {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
export function activate(ctx) {
|
||||
|
||||
const {streams, services} = ctx;
|
||||
|
||||
let components = new Map();
|
||||
const registerComponent = (id, Component) => components.set(id, Component);
|
||||
const getComponent = id => components.get(id);
|
||||
|
||||
let floatViewDescriptors = new Map();
|
||||
|
||||
function registerFloatView(id, Component, title, icon) {
|
||||
floatViewDescriptors.set(id, {Component, title, icon});
|
||||
streams.ui.floatViews.mutate(views => views.push(id));
|
||||
}
|
||||
const getFloatView = id => floatViewDescriptors.get(id);
|
||||
|
||||
services.ui = {
|
||||
registerComponent, getComponent, registerFloatView, getFloatView
|
||||
}
|
||||
|
||||
ctx.uiService = {
|
||||
...services.ui,
|
||||
streams: ctx.streams.ui
|
||||
}
|
||||
}
|
||||
|
||||
export type ActionRef = (string | string[])[];
|
||||
|
||||
declare module 'context' {
|
||||
interface CoreContext {
|
||||
|
||||
uiService: {
|
||||
registerFloatView(id: string, Component: any, title: string, icon: any);
|
||||
registerComponent(id: string, Component: any);
|
||||
getComponent(id: string) : any;
|
||||
getFloatView(id: string) : any;
|
||||
streams: {
|
||||
controlBars: {
|
||||
left: StateStream<ActionRef>
|
||||
right: StateStream<ActionRef>
|
||||
},
|
||||
toolbars: {
|
||||
headsUp: StateStream<ActionRef>,
|
||||
headsUpShowTitles: StateStream<boolean>,
|
||||
headsUpQuickActions: StateStream<ActionRef>,
|
||||
sketcherGeneral: StateStream<ActionRef>,
|
||||
sketcherConstraints: StateStream<ActionRef>,
|
||||
sketcherControl: StateStream<ActionRef>
|
||||
},
|
||||
floatViews: StateStream<ActionRef>,
|
||||
sockets: any
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -32,12 +32,13 @@ import * as OCCTPlugin from '../craft/e0/occtPlugin';
|
|||
import context from 'context';
|
||||
|
||||
import startReact from "../dom/startReact";
|
||||
import * as UIConfigPlugin from "../part/uiConfigPlugin";
|
||||
import * as UIConfigPlugin from "../workbench/uiConfigPlugin";
|
||||
import * as DebugPlugin from "../debugPlugin";
|
||||
import * as ExpressionsPlugin from "../expressions/expressionsPlugin";
|
||||
import * as PartOperationsPlugin from "../part/partOperationsPlugin";
|
||||
import {WorkbenchPlugin} from "../workbench/workbenchPlugin";
|
||||
import * as LocationPlugin from "../location/LocationPlugin";
|
||||
import * as AssemblyPlugin from "../assembly/assemblyPlugin";
|
||||
import {WorkbenchesLoaderPlugin} from "cad/workbench/workbenchesLoaderPlugin";
|
||||
|
||||
export default function startApplication(callback) {
|
||||
|
||||
|
|
@ -72,10 +73,11 @@ export default function startApplication(callback) {
|
|||
MarkerPlugin,
|
||||
PickControlPlugin,
|
||||
EntityContextPlugin,
|
||||
WorkbenchPlugin,
|
||||
SketcherPlugin,
|
||||
UIConfigPlugin,
|
||||
DebugPlugin,
|
||||
PartOperationsPlugin,
|
||||
WorkbenchesLoaderPlugin,
|
||||
LocationPlugin,
|
||||
AssemblyPlugin,
|
||||
RemotePartsPlugin,
|
||||
|
|
|
|||
|
|
@ -1,44 +0,0 @@
|
|||
import cutOperation from '../craft/cutExtrude/cutOperation';
|
||||
import planeOperation from '../craft/primitives/simplePlane/simplePlaneOperation';
|
||||
import filletOperation from '../craft/fillet/filletOperation';
|
||||
import revolveOperation from '../craft/revolve/revolveOperation';
|
||||
import createDatumOperation from '../craft/datum/create/createDatumOperation';
|
||||
import moveDatumOperation from '../craft/datum/move/moveDatumOperation';
|
||||
import rotateDatumOperation from '../craft/datum/rotate/rotateDatumOperation';
|
||||
import datumOperation from '../craft/primitives/plane/planeOperation';
|
||||
import boxOperation from '../craft/primitives/box/boxOperation';
|
||||
import sphereOperation from '../craft/primitives/sphere/sphereOperation';
|
||||
import cylinderOperation from '../craft/primitives/cylinder/cylinderOperation';
|
||||
import torusOperation from '../craft/primitives/torus/torusOperation';
|
||||
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 WorkbenchRegistry from 'workbenches/registry';
|
||||
|
||||
export function activate({services}) {
|
||||
services.operation.registerOperations([
|
||||
planeOperation,
|
||||
boxOperation,
|
||||
// extrudeOperation,
|
||||
cutOperation,
|
||||
revolveOperation,
|
||||
filletOperation,
|
||||
createDatumOperation,
|
||||
moveDatumOperation,
|
||||
rotateDatumOperation,
|
||||
datumOperation,
|
||||
sphereOperation,
|
||||
cylinderOperation,
|
||||
torusOperation,
|
||||
coneOperation,
|
||||
spatialCurveOperation,
|
||||
loftOperation,
|
||||
intersectionOperation,
|
||||
subtractOperation,
|
||||
unionOperation,
|
||||
]);
|
||||
WorkbenchRegistry.forEach(w => {
|
||||
services.operation.registerOperations(w.features);
|
||||
});
|
||||
}
|
||||
|
|
@ -1,10 +1,8 @@
|
|||
import {DelegatingPanTool} from '../../sketcher/tools/pan';
|
||||
import {DelegatingPanTool} from 'sketcher/tools/pan';
|
||||
import {Matrix4} from 'three/src/math/Matrix4';
|
||||
import {CAMERA_MODE} from '../scene/viewer';
|
||||
import DPR from 'dpr';
|
||||
import {SKETCHER_MODE_HEADS_UP_ACTIONS} from "./sketcherUIContrib";
|
||||
import {createEssentialAppContext} from "../../sketcher/sketcherContext";
|
||||
import {STANDARD_MODE_HEADS_UP_TOOLBAR} from "../part/uiConfigPlugin";
|
||||
import {createEssentialAppContext} from "sketcher/sketcherContext";
|
||||
import {ORIGIN} from "math/vector";
|
||||
|
||||
export class InPlaceSketcher {
|
||||
|
|
@ -44,8 +42,7 @@ export class InPlaceSketcher {
|
|||
this.viewer.toolManager.setDefaultTool(new DelegatingPanTool(this.viewer, viewer3d.sceneSetup.renderer.domElement));
|
||||
viewer3d.sceneSetup.trackballControls.addEventListener( 'change', this.onCameraChange);
|
||||
|
||||
this.ctx.streams.ui.toolbars.headsUp.next(SKETCHER_MODE_HEADS_UP_ACTIONS);
|
||||
this.ctx.streams.ui.toolbars.headsUpShowTitles.next(false);
|
||||
this.ctx.workbenchService.switchWorkbench('sketcher');
|
||||
|
||||
let sketchData = this.ctx.services.storage.get(this.sketchStorageKey);
|
||||
this.viewer.historyManager.init(sketchData);
|
||||
|
|
@ -70,8 +67,7 @@ export class InPlaceSketcher {
|
|||
this.sketcherAppContext = null;
|
||||
this.ctx.streams.sketcher.sketchingFace.next(null);
|
||||
this.ctx.streams.sketcher.sketcherAppContext.next(null);
|
||||
this.ctx.streams.ui.toolbars.headsUp.next(STANDARD_MODE_HEADS_UP_TOOLBAR);
|
||||
this.ctx.streams.ui.toolbars.headsUpShowTitles.next(true);
|
||||
this.ctx.workbenchService.switchToDefaultWorkbench();
|
||||
viewer3d.requestRender();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,62 +0,0 @@
|
|||
import objectToolActions from '../../sketcher/actions/objectToolActions';
|
||||
import measureActions from '../../sketcher/actions/measureActions';
|
||||
import {insertAfter} from 'gems/iterables';
|
||||
import operationActions from "../../sketcher/actions/operationActions";
|
||||
import constraintGlobalActions from "../../sketcher/actions/constraintGlobalActions";
|
||||
import generalToolActions from "../../sketcher/actions/generalToolActions";
|
||||
import sketcherControlActions from "./sketcherControlActions";
|
||||
|
||||
export default function (ctx) {
|
||||
ctx.actionService.registerActions(sketcherControlActions);
|
||||
ctx.actionService.registerActions([
|
||||
...constraintGlobalActions,
|
||||
...measureActions,
|
||||
...generalToolActions,
|
||||
...objectToolActions,
|
||||
...operationActions,
|
||||
|
||||
].map(convertSketcherAction));
|
||||
|
||||
}
|
||||
|
||||
const SKETCHER_PREFIX = 'sketcher.';
|
||||
|
||||
function toSketcherActionId(id) {
|
||||
return SKETCHER_PREFIX + id;
|
||||
}
|
||||
|
||||
function convertSketcherAction(action) {
|
||||
|
||||
return {
|
||||
id: toSketcherActionId(action.id),
|
||||
appearance: {
|
||||
icon: action.icon,
|
||||
label: action.shortName,
|
||||
info: action.description,
|
||||
},
|
||||
invoke: ({services}, e) => action.invoke(services.sketcher.inPlaceEditor.sketcherAppContext)
|
||||
}
|
||||
}
|
||||
export const SKETCHER_MODE_HEADS_UP_ACTIONS = [
|
||||
['sketchSaveAndExit', 'sketchExit'],
|
||||
'-',
|
||||
generalToolActions.map(a => toSketcherActionId(a.id)),
|
||||
'-',
|
||||
[
|
||||
...objectToolActions.map(a => toSketcherActionId(a.id)),
|
||||
toSketcherActionId('Offset'),
|
||||
],
|
||||
'-',
|
||||
measureActions.map(a => toSketcherActionId(a.id)),
|
||||
'-',
|
||||
constraintGlobalActions.map(a => toSketcherActionId(a.id)),
|
||||
'-',
|
||||
['LookAtFace'],
|
||||
'-',
|
||||
['sketchOpenInTab']
|
||||
];
|
||||
|
||||
insertAfter(SKETCHER_MODE_HEADS_UP_ACTIONS, SKETCHER_PREFIX + 'Export', '-');
|
||||
insertAfter(SKETCHER_MODE_HEADS_UP_ACTIONS, SKETCHER_PREFIX + 'PanTool', '-');
|
||||
insertAfter(SKETCHER_MODE_HEADS_UP_ACTIONS, SKETCHER_PREFIX + 'BezierTool', '-');
|
||||
|
||||
80
web/app/cad/sketch/sketcherUIContrib.ts
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
import objectToolActions from '../../sketcher/actions/objectToolActions';
|
||||
import measureActions from '../../sketcher/actions/measureActions';
|
||||
import {insertAfter} from 'gems/iterables';
|
||||
import operationActions from "../../sketcher/actions/operationActions";
|
||||
import constraintGlobalActions from "../../sketcher/actions/constraintGlobalActions";
|
||||
import generalToolActions from "../../sketcher/actions/generalToolActions";
|
||||
import sketcherControlActions from "./sketcherControlActions";
|
||||
import {ApplicationContext} from "context";
|
||||
import {WorkbenchConfig} from "cad/workbench/workbenchService";
|
||||
|
||||
export default function (ctx: ApplicationContext) {
|
||||
|
||||
const convertedActions = [
|
||||
...constraintGlobalActions,
|
||||
...measureActions,
|
||||
...generalToolActions,
|
||||
...objectToolActions,
|
||||
...operationActions,
|
||||
].map(convertSketcherAction);
|
||||
|
||||
const SKETCHER_MODE_HEADS_UP_ACTIONS = [
|
||||
['sketchSaveAndExit', 'sketchExit'],
|
||||
'-',
|
||||
generalToolActions.map(a => toSketcherActionId(a.id)),
|
||||
'-',
|
||||
[
|
||||
...objectToolActions.map(a => toSketcherActionId(a.id)),
|
||||
toSketcherActionId('Offset'),
|
||||
],
|
||||
'-',
|
||||
measureActions.map(a => toSketcherActionId(a.id)),
|
||||
'-',
|
||||
constraintGlobalActions.map(a => toSketcherActionId(a.id)),
|
||||
'-',
|
||||
['LookAtFace'],
|
||||
'-',
|
||||
['sketchOpenInTab']
|
||||
];
|
||||
|
||||
insertAfter(SKETCHER_MODE_HEADS_UP_ACTIONS, SKETCHER_PREFIX + 'Export', '-');
|
||||
insertAfter(SKETCHER_MODE_HEADS_UP_ACTIONS, SKETCHER_PREFIX + 'PanTool', '-');
|
||||
insertAfter(SKETCHER_MODE_HEADS_UP_ACTIONS, SKETCHER_PREFIX + 'BezierTool', '-');
|
||||
|
||||
ctx.workbenchService.registerWorkbench({
|
||||
workbenchId: 'sketcher',
|
||||
internal: true,
|
||||
features: [],
|
||||
actions: [
|
||||
...sketcherControlActions,
|
||||
...convertedActions
|
||||
],
|
||||
ui: {
|
||||
toolbar: SKETCHER_MODE_HEADS_UP_ACTIONS,
|
||||
toolbarStyle: 'compact'
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
const SKETCHER_PREFIX = 'sketcher.';
|
||||
|
||||
function toSketcherActionId(id: string): string {
|
||||
return SKETCHER_PREFIX + id;
|
||||
}
|
||||
|
||||
function convertSketcherAction(action) {
|
||||
|
||||
return {
|
||||
id: toSketcherActionId(action.id),
|
||||
appearance: {
|
||||
icon: action.icon,
|
||||
label: action.shortName,
|
||||
info: action.description,
|
||||
},
|
||||
invoke: ({services}, e) => action.invoke(services.sketcher.inPlaceEditor.sketcherAppContext)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -10,11 +10,6 @@ import Expressions from '../expressions/Expressions';
|
|||
import {SelectionView} from "../dom/components/SelectionView";
|
||||
import {GrSelect} from "react-icons/gr";
|
||||
|
||||
export const STANDARD_MODE_HEADS_UP_TOOLBAR = ['DATUM_CREATE', 'PLANE', 'EditFace', '-', "OCC_BOTTLE", '-',
|
||||
"EXTRUDE", "Revolve", "loft","-", "boolean_tool", "shell_tool",
|
||||
"primitive_cylinder", "primitive_box", "primitive_cone", "primitive_sphere", "primitive_torus", "hole_tool",
|
||||
"fillet_tool"];
|
||||
|
||||
export function activate(ctx) {
|
||||
const {services, streams} = ctx;
|
||||
streams.ui.controlBars.left.value = ['menu.file', 'menu.craft', 'menu.boolean', 'menu.primitives', 'menu.views', 'Donate', 'GitHub'];
|
||||
|
|
@ -24,7 +19,6 @@ export function activate(ctx) {
|
|||
['ShowSketches', {label: 'sketches'}], ['DeselectAll', {label: null}], ['ToggleCameraMode', {label: null}]
|
||||
];
|
||||
|
||||
streams.ui.toolbars.headsUp.value = STANDARD_MODE_HEADS_UP_TOOLBAR;
|
||||
streams.ui.toolbars.headsUpQuickActions.value = ['Save', 'StlExport'];
|
||||
|
||||
ctx.actionService.registerActions(CoreActions);
|
||||
20
web/app/cad/workbench/workbenchPlugin.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import {ApplicationContext} from "context";
|
||||
import {WorkbenchService} from "cad/workbench/workbenchService";
|
||||
|
||||
|
||||
declare module 'context' {
|
||||
interface CoreContext {
|
||||
|
||||
workbenchService: WorkbenchService;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const WorkbenchPlugin = {
|
||||
|
||||
activate(ctx: ApplicationContext) {
|
||||
|
||||
ctx.workbenchService = new WorkbenchService(ctx);
|
||||
}
|
||||
|
||||
}
|
||||
68
web/app/cad/workbench/workbenchService.ts
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
import {OperationDescriptor} from "cad/craft/operationPlugin";
|
||||
import {ActionDefinition} from "cad/actions/actionSystemPlugin";
|
||||
import {state} from "lstream";
|
||||
import {Index} from "gems/indexType";
|
||||
import {ApplicationContext, CoreContext} from "context";
|
||||
import {ActionRef} from "cad/dom/uiPlugin";
|
||||
|
||||
export class WorkbenchService {
|
||||
|
||||
workbenches$ = state<Index<WorkbenchConfig>>({});
|
||||
|
||||
currentWorkbench$ = state<WorkbenchConfig>(null);
|
||||
ctx: CoreContext;
|
||||
|
||||
constructor(ctx: ApplicationContext) {
|
||||
this.ctx = ctx;
|
||||
this.currentWorkbench$.attach(workbenchConfig => {
|
||||
if (!workbenchConfig) {
|
||||
return
|
||||
}
|
||||
ctx.uiService.streams.toolbars.headsUp.next(workbenchConfig.ui.toolbar);
|
||||
const toolbarStyle = workbenchConfig.ui.toolbarStyle || 'large'
|
||||
ctx.uiService.streams.toolbars.headsUpShowTitles.next(toolbarStyle === "large");
|
||||
})
|
||||
}
|
||||
|
||||
getWorkbenchConfig(workbenchId: string): WorkbenchConfig {
|
||||
return this.workbenches$.value[workbenchId];
|
||||
}
|
||||
|
||||
registerWorkbench(workbenchConfig: WorkbenchConfig) {
|
||||
if (this.getWorkbenchConfig(workbenchConfig.workbenchId)) {
|
||||
throw 'workbench already exists: ' + workbenchConfig.workbenchId;
|
||||
}
|
||||
this.ctx.operationService.registerOperations(workbenchConfig.features)
|
||||
this.ctx.actionService.registerActions(workbenchConfig.actions);
|
||||
|
||||
this.workbenches$.update(workbenches => ({
|
||||
...workbenches,
|
||||
[workbenchConfig.workbenchId]: workbenchConfig
|
||||
}));
|
||||
}
|
||||
|
||||
switchWorkbench(workbenchId: string) {
|
||||
const workbenchConfig = this.workbenches$.value[workbenchId];
|
||||
if (!workbenchConfig) {
|
||||
throw 'nonexistent workbench ' + workbenchId;
|
||||
}
|
||||
this.currentWorkbench$.next(workbenchConfig);
|
||||
}
|
||||
|
||||
switchToDefaultWorkbench() {
|
||||
this.switchWorkbench('modeler');
|
||||
}
|
||||
}
|
||||
|
||||
export interface WorkbenchUIConfig {
|
||||
toolbar: ActionRef;
|
||||
toolbarStyle?: 'compact' | 'large';
|
||||
}
|
||||
|
||||
export interface WorkbenchConfig {
|
||||
workbenchId: string;
|
||||
internal?: boolean;
|
||||
features: OperationDescriptor<any>[];
|
||||
actions: ActionDefinition<any>[];
|
||||
ui: WorkbenchUIConfig;
|
||||
}
|
||||
54
web/app/cad/workbench/workbenchesLoaderPlugin.ts
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
import {ApplicationContext, CoreContext} from "context";
|
||||
import {WorkbenchRegistry} from "workbenches/registry";
|
||||
import planeOperation from "cad/craft/primitives/simplePlane/simplePlaneOperation";
|
||||
import boxOperation from "cad/craft/primitives/box/boxOperation";
|
||||
import cutOperation from "cad/craft/cutExtrude/cutOperation";
|
||||
import revolveOperation from "cad/craft/revolve/revolveOperation";
|
||||
import filletOperation from "cad/craft/fillet/filletOperation";
|
||||
import createDatumOperation from "cad/craft/datum/create/createDatumOperation";
|
||||
import moveDatumOperation from "cad/craft/datum/move/moveDatumOperation";
|
||||
import rotateDatumOperation from "cad/craft/datum/rotate/rotateDatumOperation";
|
||||
import datumOperation from "cad/craft/primitives/plane/planeOperation";
|
||||
import sphereOperation from "cad/craft/primitives/sphere/sphereOperation";
|
||||
import cylinderOperation from "cad/craft/primitives/cylinder/cylinderOperation";
|
||||
import torusOperation from "cad/craft/primitives/torus/torusOperation";
|
||||
import coneOperation from "cad/craft/primitives/cone/coneOperation";
|
||||
import spatialCurveOperation from "cad/craft/spatialCurve/spatialCurveOperation";
|
||||
import loftOperation from "cad/craft/loft/loftOperation";
|
||||
import {intersectionOperation, subtractOperation, unionOperation} from "cad/craft/boolean/booleanOperation";
|
||||
|
||||
|
||||
export const WorkbenchesLoaderPlugin = {
|
||||
|
||||
activate(ctx: ApplicationContext) {
|
||||
registerCoreOperations(ctx);
|
||||
WorkbenchRegistry.forEach(wConfig => ctx.workbenchService.registerWorkbench(wConfig));
|
||||
ctx.workbenchService.switchToDefaultWorkbench();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function registerCoreOperations(ctx: CoreContext) {
|
||||
|
||||
ctx.operationService.registerOperations([
|
||||
planeOperation,
|
||||
boxOperation,
|
||||
// extrudeOperation,
|
||||
cutOperation,
|
||||
revolveOperation,
|
||||
filletOperation,
|
||||
createDatumOperation,
|
||||
moveDatumOperation,
|
||||
rotateDatumOperation,
|
||||
datumOperation,
|
||||
sphereOperation,
|
||||
cylinderOperation,
|
||||
torusOperation,
|
||||
coneOperation,
|
||||
spatialCurveOperation,
|
||||
loftOperation,
|
||||
intersectionOperation,
|
||||
subtractOperation,
|
||||
unionOperation,
|
||||
]);
|
||||
}
|
||||