jsketcher/modules/workbenches/modeler/features/fillet/fillet.operation.ts
2022-11-05 21:23:16 -07:00

138 lines
3.8 KiB
TypeScript

import {ApplicationContext} from 'cad/context';
import {roundValueForPresentation as r} from 'cad/craft/operationHelper';
import {EntityKind} from "cad/model/entities";
import {OperationDescriptor} from "cad/craft/operationBundle";
import {FromMObjectProductionAnalyzer} from "cad/craft/production/productionAnalyzer";
import {MEdge} from "cad/model/medge";
import {MObject} from "cad/model/mobject";
import {MShell} from "cad/model/mshell";
import { MBrepFace } from 'cad/model/mface';
interface FilletParams {
edges: MEdge[] | MBrepFace[],
size: number
opperationType: 'Champher'|'Fillet'
}
export const FilletOperation: OperationDescriptor<any> = {
id: 'FILLET_TOOL',
label: 'Fillet/Chapher',
icon: 'img/cad/fillet',
info: 'Fillet/Champher',
path:__dirname,
paramsInfo: ({size, opperationType,}) => `(${r(size)} ${r(opperationType)}})`,
run: (params: FilletParams, ctx: ApplicationContext) => {
const occ = ctx.occService;
const oci = occ.commandInterface;
let edgeList = [];
//check if input contains faces and if a face is an input add all adjacent edges to list for processing.
params.edges.forEach((edge) => {
if(edge.TYPE === EntityKind.FACE){
edgeList = edgeList.concat(edge.edges);
}
if(edge.TYPE === EntityKind.EDGE){
edgeList.push(edge);
}
});
//add all the edges and size to seperate arrays for each shell that edges are selected from
const groups = new Map<MShell, any[]>()
edgeList.forEach((edge) => {
let shellArgs = groups.get(edge.shell);
if (!shellArgs) {
shellArgs = [];
groups.set(edge.shell, shellArgs);
}
if (params.opperationType == "Fillet") {
//order of parameters is diferent between fillet and champher
shellArgs.push(params.size, edge);
} else if (params.opperationType == "Champher") {
//order of parameters is diferent between fillet and champher
shellArgs.push(edge, params.size);
} else {
throw 'unsupported';
}
});
//perform the opperations on each of the bodies.
let result = {
created: [],
consumed: Array.from(groups.keys()),
error: {},
}
const analyzer = new FromMObjectProductionAnalyzer(result.consumed);
groups.forEach((shellArgs, shellToOpperateOn) => {
const newShellName = shellToOpperateOn.id+'/MOD';
if (params.opperationType == "Fillet") {
oci.blend(newShellName, shellToOpperateOn, ...shellArgs);
} else if (params.opperationType == "Champher") {
oci.chamf(newShellName, shellToOpperateOn, ...shellArgs);
} else {
throw 'unsupported';
}
result.created.push(occ.io.getShell(newShellName, analyzer));
});
result.created.forEach(function (item, index, arr ){
if (item.faces.length <=1) result = {
created: [],
consumed:[],
error :{
type:"fail",
message:"Fillet failed, Try changing radius or remove edge causing failure."
},
};
})
if (result.created[0].faces.length <=1) result = {
created: [],
consumed:[],
error :{
type:"fail",
message:"Fillet failed, Try changing radius or remove edge causing failure."
},
};
return result;
},
form: [
{
type: 'selection',
name: 'edges',
capture: [EntityKind.EDGE,EntityKind.FACE],
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,
},
],
}