mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-15 21:05:22 +01:00
138 lines
3.8 KiB
TypeScript
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,
|
|
},
|
|
],
|
|
}
|
|
|