@bitbybit-dev/occt
Version:
Bit By Bit Developers CAD algorithms using OpenCascade Technology kernel. Run in Node and in Browser.
261 lines (260 loc) • 10.9 kB
JavaScript
import * as Inputs from "../../api/inputs/inputs";
export class DimensionsService {
constructor(base, transformsService, converterService, entitiesService, edgesService, wiresService) {
this.base = base;
this.transformsService = transformsService;
this.converterService = converterService;
this.entitiesService = entitiesService;
this.edgesService = edgesService;
this.wiresService = wiresService;
}
simpleLinearLengthDimension(inputs) {
const shapesToDelete = [];
const lineBetweenPoints = this.wiresService.createLineWireWithExtensions({
start: inputs.start,
end: inputs.end,
extensionStart: inputs.crossingSize,
extensionEnd: inputs.crossingSize,
});
shapesToDelete.push(lineBetweenPoints);
const translatedLine = this.transformsService.translate({
shape: lineBetweenPoints,
translation: inputs.direction,
});
const translatedPts = this.base.point.translatePoints({
points: [inputs.start, inputs.end],
translation: inputs.direction,
});
const translatedStartPt = translatedPts[0];
const translatedEndPt = translatedPts[1];
const startLineToTranslatedPoint = this.wiresService.createLineWireWithExtensions({
start: inputs.start,
end: translatedStartPt,
extensionStart: -inputs.offsetFromPoints,
extensionEnd: inputs.crossingSize,
});
const endLineToTranslatedPoint = this.wiresService.createLineWireWithExtensions({
start: inputs.end,
end: translatedEndPt,
extensionStart: -inputs.offsetFromPoints,
extensionEnd: inputs.crossingSize,
});
const midPt = this.wiresService.midPointOnWire({ shape: translatedLine });
const length = this.base.point.distance({
startPoint: inputs.start,
endPoint: inputs.end,
});
const txtOpt = new Inputs.OCCT.TextWiresDto();
txtOpt.text = length.toFixed(inputs.decimalPlaces) + " " + inputs.labelSuffix;
txtOpt.xOffset = 0;
txtOpt.yOffset = 0;
txtOpt.height = inputs.labelSize;
txtOpt.centerOnOrigin = true;
const txt = this.wiresService.textWiresWithData(txtOpt);
// get the up vector for the dimension plane
const normalThreePoints = this.base.point.normalFromThreePoints({
point1: inputs.start,
point2: inputs.end,
point3: midPt,
reverseNormal: true,
});
const dirStartEnd = this.base.vector.sub({
first: inputs.end,
second: inputs.start,
});
const rotated = this.transformsService.rotate({
shape: txt.compound,
angle: -90,
axis: [0, 1, 0],
});
shapesToDelete.push(...txt.shapes.map((s) => s.shape));
const alignedLabelTxtToDir = this.transformsService.alignNormAndAxis({
shape: rotated,
fromOrigin: [0, 0, 0],
fromNorm: [0, 1, 0],
fromAx: [0, 0, 1],
toOrigin: [0, 0, 0],
toNorm: normalThreePoints,
toAx: dirStartEnd,
});
shapesToDelete.push(rotated);
const normDir = this.base.vector.normalized({ vector: inputs.direction });
const offsetLabelVec = this.base.vector.mul({ vector: normDir, scalar: inputs.labelOffset });
const addToDir = this.base.vector.add({
first: midPt,
second: offsetLabelVec,
});
const labelTransformed = this.transformsService.translate({
shape: alignedLabelTxtToDir,
translation: addToDir
});
shapesToDelete.push(alignedLabelTxtToDir);
const res = this.converterService.makeCompound({ shapes: [translatedLine, startLineToTranslatedPoint, endLineToTranslatedPoint, labelTransformed] });
// delete shapes
shapesToDelete.forEach((shape) => {
shape.delete();
});
return res;
}
simpleAngularDimension(inputs) {
const shapesToDelete = [];
const normDir1 = this.base.vector.normalized({ vector: inputs.direction1 });
const endVec = this.base.vector.mul({ vector: normDir1, scalar: inputs.radius });
const endPt = this.base.point.translatePoints({
points: [endVec],
translation: inputs.center,
})[0];
const line1WithExt = this.wiresService.createLineWireWithExtensions({
start: inputs.center,
end: endPt,
extensionStart: -inputs.offsetFromCenter,
extensionEnd: inputs.extraSize,
});
const normDir2 = this.base.vector.normalized({ vector: inputs.direction2 });
const endVec2 = this.base.vector.mul({ vector: normDir2, scalar: inputs.radius });
const endPt2 = this.base.point.translatePoints({
points: [endVec2],
translation: inputs.center,
})[0];
const line2WithExt = this.wiresService.createLineWireWithExtensions({
start: inputs.center,
end: endPt2,
extensionStart: -inputs.offsetFromCenter,
extensionEnd: inputs.extraSize,
});
const normalThreePoints = this.base.point.normalFromThreePoints({
point1: inputs.center,
point2: endPt,
point3: endPt2,
reverseNormal: true,
});
const normalThreePointsRev = this.base.point.normalFromThreePoints({
point1: inputs.center,
point2: endPt,
point3: endPt2,
reverseNormal: false,
});
const circ = this.entitiesService.createCircle(inputs.radius, inputs.center, normalThreePointsRev, Inputs.OCCT.typeSpecificityEnum.edge);
shapesToDelete.push(circ);
const arc = this.edgesService.arcFromCircleAndTwoPoints({
circle: circ,
start: endPt,
end: endPt2,
sense: false,
});
shapesToDelete.push(arc);
const wireArc = this.wiresService.createWireFromEdge({ shape: arc });
const midPt = this.wiresService.midPointOnWire({ shape: wireArc });
let angle = this.base.vector.angleBetween({
first: inputs.direction1,
second: inputs.direction2,
});
if (inputs.radians) {
angle = this.base.math.degToRad({ number: angle });
}
const txtOpt = new Inputs.OCCT.TextWiresDto();
txtOpt.text = angle.toFixed(inputs.decimalPlaces) + " " + inputs.labelSuffix;
txtOpt.xOffset = 0;
txtOpt.yOffset = 0;
txtOpt.height = inputs.labelSize;
txtOpt.centerOnOrigin = true;
const txt = this.wiresService.textWiresWithData(txtOpt);
const vectorToMid = this.base.vector.sub({
first: midPt,
second: inputs.center,
});
const normVecToMid = this.base.vector.normalized({ vector: vectorToMid });
const alignedLabelTxtToDir = this.transformsService.alignNormAndAxis({
shape: txt.compound,
fromOrigin: [0, 0, 0],
fromNorm: [0, 1, 0],
fromAx: [0, 0, 1],
toOrigin: [0, 0, 0],
toNorm: normalThreePoints,
toAx: normVecToMid,
});
shapesToDelete.push(...txt.shapes.map((s) => s.shape));
const offsetLabelVec = this.base.vector.mul({ vector: normVecToMid, scalar: inputs.labelOffset });
const addToDir = this.base.vector.add({
first: midPt,
second: offsetLabelVec,
});
const labelTransformed = this.transformsService.translate({
shape: alignedLabelTxtToDir,
translation: addToDir
});
shapesToDelete.push(alignedLabelTxtToDir);
const res = this.converterService.makeCompound({ shapes: [line1WithExt, line2WithExt, wireArc, labelTransformed] });
// delete shapes
shapesToDelete.forEach((shape) => {
shape.delete();
});
return res;
}
pinWithLabel(inputs) {
const pinLine = this.wiresService.createLineWireWithExtensions({
start: inputs.startPoint,
end: inputs.endPoint,
extensionStart: -inputs.offsetFromStart,
extensionEnd: 0,
});
const txtOpt = new Inputs.OCCT.TextWiresDto();
txtOpt.text = inputs.label;
txtOpt.xOffset = 0;
txtOpt.yOffset = 0;
txtOpt.height = inputs.labelSize;
txtOpt.centerOnOrigin = true;
const text = this.wiresService.textWiresWithData(txtOpt);
const textWidth = text.data.width;
const dirNorm = this.base.vector.normalized({ vector: inputs.direction });
const offsetLabelVec = this.base.vector.mul({ vector: dirNorm, scalar: textWidth / 2 + inputs.labelOffset });
// const translateTxtVec = this.vector.add({ first: inputs.direction, second: offsetLabelVec }) as Inputs.Base.Vector3;
const endPtLabelLine = this.base.point.translatePoints({
points: [inputs.endPoint],
translation: inputs.direction,
})[0];
const lineBeneathLabel = this.wiresService.createLineWireWithExtensions({
start: inputs.endPoint,
end: endPtLabelLine,
extensionStart: 0,
extensionEnd: 0,
});
const normalThreePoints = this.base.point.normalFromThreePoints({
point1: inputs.startPoint,
point2: inputs.endPoint,
point3: endPtLabelLine,
reverseNormal: false,
});
const rotated = this.transformsService.rotate({
shape: text.compound,
angle: -90,
axis: [0, 1, 0],
});
const shapesToDelete = text.shapes.map((s) => s.shape);
const alignedLabelTxtToDir = this.transformsService.alignNormAndAxis({
shape: rotated,
fromOrigin: [0, 0, 0],
fromNorm: [0, 1, 0],
fromAx: [0, 0, 1],
toOrigin: [0, 0, 0],
toNorm: normalThreePoints,
toAx: dirNorm,
});
shapesToDelete.push(rotated);
const addToDir = this.base.vector.add({
first: endPtLabelLine,
second: offsetLabelVec,
});
const labelTransformed = this.transformsService.translate({
shape: alignedLabelTxtToDir,
translation: addToDir,
});
shapesToDelete.push(alignedLabelTxtToDir);
const res = this.converterService.makeCompound({ shapes: [pinLine, labelTransformed, lineBeneathLabel] });
// delete shapes
shapesToDelete.forEach((shape) => {
shape.delete();
});
return res;
}
}