Skip to content

Commit 7a3264b

Browse files
bounding unit tests
1 parent 8101b1e commit 7a3264b

File tree

1 file changed

+253
-0
lines changed

1 file changed

+253
-0
lines changed

packages/dev/occt/lib/services/operations.test.ts

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,259 @@ describe("OCCT operations unit tests", () => {
914914
res.delete();
915915
});
916916

917+
describe("Bounding box operations", () => {
918+
it("should get bounding box properties of a box shape", () => {
919+
const box = occHelper.entitiesService.bRepPrimAPIMakeBox(2, 3, 4, [0, 0, 0]);
920+
const bbox = operations.boundingBoxOfShape({ shape: box });
921+
922+
expect(bbox.min[0]).toBeCloseTo(-1, 5);
923+
expect(bbox.min[1]).toBeCloseTo(-2, 5);
924+
expect(bbox.min[2]).toBeCloseTo(-1.5, 5);
925+
expect(bbox.max[0]).toBeCloseTo(1, 5);
926+
expect(bbox.max[1]).toBeCloseTo(2, 5);
927+
expect(bbox.max[2]).toBeCloseTo(1.5, 5);
928+
expect(bbox.center[0]).toBeCloseTo(0, 5);
929+
expect(bbox.center[1]).toBeCloseTo(0, 5);
930+
expect(bbox.center[2]).toBeCloseTo(0, 5);
931+
expect(bbox.size[0]).toBeCloseTo(2, 5);
932+
expect(bbox.size[1]).toBeCloseTo(4, 5);
933+
expect(bbox.size[2]).toBeCloseTo(3, 5);
934+
935+
box.delete();
936+
});
937+
938+
it("should get bounding box min point of a sphere", () => {
939+
const sphere = occHelper.entitiesService.bRepPrimAPIMakeSphere([0, 0, 0], [0, 1, 0], 2);
940+
const min = operations.boundingBoxMinOfShape({ shape: sphere });
941+
942+
expect(min[0]).toBeCloseTo(-2, 5);
943+
expect(min[1]).toBeCloseTo(-2, 5);
944+
expect(min[2]).toBeCloseTo(-2, 5);
945+
946+
sphere.delete();
947+
});
948+
949+
it("should get bounding box max point of a sphere", () => {
950+
const sphere = occHelper.entitiesService.bRepPrimAPIMakeSphere([5, 10, -3], [0, 1, 0], 1.5);
951+
const max = operations.boundingBoxMaxOfShape({ shape: sphere });
952+
953+
expect(max[0]).toBeCloseTo(6.5, 5);
954+
expect(max[1]).toBeCloseTo(11.5, 5);
955+
expect(max[2]).toBeCloseTo(-1.5, 5);
956+
957+
sphere.delete();
958+
});
959+
960+
it("should get bounding box center of a cylinder", () => {
961+
const cyl = occHelper.entitiesService.bRepPrimAPIMakeCylinder([0, 0, 0], [0, 1, 0], 2, 10, 360);
962+
const center = operations.boundingBoxCenterOfShape({ shape: cyl });
963+
964+
expect(center[0]).toBeCloseTo(0, 5);
965+
expect(center[1]).toBeCloseTo(5, 5);
966+
expect(center[2]).toBeCloseTo(0, 5);
967+
968+
cyl.delete();
969+
});
970+
971+
it("should get bounding box size of a cube", () => {
972+
const box = occHelper.entitiesService.bRepPrimAPIMakeBox(5, 5, 5, [0, 0, 0]);
973+
const size = operations.boundingBoxSizeOfShape({ shape: box });
974+
975+
expect(size[0]).toBeCloseTo(5, 5);
976+
expect(size[1]).toBeCloseTo(5, 5);
977+
expect(size[2]).toBeCloseTo(5, 5);
978+
979+
box.delete();
980+
});
981+
982+
it("should create a bounding box shape from a complex wire", () => {
983+
const points = [
984+
[0, 0, 0],
985+
[5, 10, 3],
986+
[-2, 5, 8],
987+
[3, -1, 2]
988+
] as Inputs.Base.Point3[];
989+
const polyWire = wire.createPolylineWire({ points });
990+
991+
const bboxShape = operations.boundingBoxShapeOfShape({ shape: polyWire });
992+
const volume = solid.getSolidVolume({ shape: bboxShape });
993+
const bbox = operations.boundingBoxOfShape({ shape: polyWire });
994+
995+
// Volume should be width * height * depth
996+
const expectedVolume = bbox.size[0] * bbox.size[1] * bbox.size[2];
997+
expect(volume).toBeCloseTo(expectedVolume, 5);
998+
999+
polyWire.delete();
1000+
bboxShape.delete();
1001+
});
1002+
1003+
it("should get bounding box of compound shape with multiple solids", () => {
1004+
const box1 = occHelper.entitiesService.bRepPrimAPIMakeBox(1, 1, 1, [0, 0, 0]);
1005+
const box2 = occHelper.entitiesService.bRepPrimAPIMakeBox(1, 1, 1, [5, 5, 5]);
1006+
const compound = occHelper.converterService.makeCompound({ shapes: [box1, box2] });
1007+
1008+
const bbox = operations.boundingBoxOfShape({ shape: compound });
1009+
1010+
expect(bbox.min[0]).toBeCloseTo(-0.5, 4);
1011+
expect(bbox.min[1]).toBeCloseTo(-0.5, 4);
1012+
expect(bbox.min[2]).toBeCloseTo(-0.5, 4);
1013+
expect(bbox.max[0]).toBeCloseTo(5.5, 4);
1014+
expect(bbox.max[1]).toBeCloseTo(5.5, 4);
1015+
expect(bbox.max[2]).toBeCloseTo(5.5, 4);
1016+
expect(bbox.size[0]).toBeCloseTo(6, 4);
1017+
expect(bbox.size[1]).toBeCloseTo(6, 4);
1018+
expect(bbox.size[2]).toBeCloseTo(6, 4);
1019+
1020+
box1.delete();
1021+
box2.delete();
1022+
compound.delete();
1023+
});
1024+
1025+
it("should get bounding box of extruded wire", () => {
1026+
const circleWire = wire.createCircleWire({ center: [3, 0, 0], radius: 1, direction: [0, 1, 0] });
1027+
const extruded = operations.extrude({ shape: circleWire, direction: [0, 5, 0] });
1028+
1029+
const bbox = operations.boundingBoxOfShape({ shape: extruded });
1030+
1031+
expect(bbox.min[0]).toBeCloseTo(2, 5);
1032+
expect(bbox.min[1]).toBeCloseTo(0, 5);
1033+
expect(bbox.min[2]).toBeCloseTo(-1, 5);
1034+
expect(bbox.max[0]).toBeCloseTo(4, 5);
1035+
expect(bbox.max[1]).toBeCloseTo(5, 5);
1036+
expect(bbox.max[2]).toBeCloseTo(1, 5);
1037+
1038+
circleWire.delete();
1039+
extruded.delete();
1040+
});
1041+
1042+
it("should get bounding box of revolved shape", () => {
1043+
const squareFace = face.createSquareFace({ center: [5, 0, 0], size: 2, direction: [0, 1, 0] });
1044+
const revolved = operations.revolve({ shape: squareFace, direction: [0, 1, 0], angle: 180, copy: false });
1045+
1046+
const bbox = operations.boundingBoxOfShape({ shape: revolved });
1047+
1048+
expect(bbox.min[0]).toBeCloseTo(-6, 0);
1049+
expect(bbox.min[1]).toBeCloseTo(0, 5);
1050+
expect(bbox.min[2]).toBeCloseTo(-6, 0);
1051+
expect(bbox.max[0]).toBeCloseTo(6, 0);
1052+
expect(bbox.max[1]).toBeCloseTo(0, 5);
1053+
expect(bbox.max[2]).toBeCloseTo(1, 0);
1054+
1055+
squareFace.delete();
1056+
revolved.delete();
1057+
});
1058+
});
1059+
1060+
describe("Bounding sphere operations", () => {
1061+
it("should get bounding sphere properties of a box", () => {
1062+
const box = occHelper.entitiesService.bRepPrimAPIMakeBox(2, 2, 2, [0, 0, 0]);
1063+
const bsphere = operations.boundingSphereOfShape({ shape: box });
1064+
1065+
// Box is centered at [0,0,0], bounding sphere center is at bbox center
1066+
expect(bsphere.center[0]).toBeCloseTo(0, 5);
1067+
expect(bsphere.center[1]).toBeCloseTo(0, 5);
1068+
expect(bsphere.center[2]).toBeCloseTo(0, 5);
1069+
expect(bsphere.radius).toBeCloseTo(Math.sqrt(3), 5);
1070+
1071+
box.delete();
1072+
});
1073+
1074+
it("should get bounding sphere center of a sphere", () => {
1075+
const sphere = occHelper.entitiesService.bRepPrimAPIMakeSphere([3, 4, 5], [0, 1, 0], 2);
1076+
const center = operations.boundingSphereCenterOfShape({ shape: sphere });
1077+
1078+
expect(center[0]).toBeCloseTo(3, 5);
1079+
expect(center[1]).toBeCloseTo(4, 5);
1080+
expect(center[2]).toBeCloseTo(5, 5);
1081+
1082+
sphere.delete();
1083+
});
1084+
1085+
it("should get bounding sphere radius of a cylinder", () => {
1086+
const cyl = occHelper.entitiesService.bRepPrimAPIMakeCylinder([0, 0, 0], [0, 1, 0], 3, 8, 360);
1087+
const radius = operations.boundingSphereRadiusOfShape({ shape: cyl });
1088+
1089+
// For a cylinder with radius 3 and height 8, the bounding sphere radius is
1090+
// the distance from center (0, 4, 0) to corner (3, 8, 0) or (3, 0, 0)
1091+
// = sqrt(3^2 + 4^2 + 3^2) = sqrt(34) ≈ 5.83
1092+
expect(radius).toBeCloseTo(Math.sqrt(34), 2);
1093+
1094+
cyl.delete();
1095+
});
1096+
1097+
it("should create a bounding sphere shape from a torus-like shape", () => {
1098+
const circle = face.createCircleFace({ center: [5, 0, 0], radius: 1, direction: [0, 1, 0] });
1099+
const torus = operations.revolve({ shape: circle, direction: [0, 1, 0], angle: 360, copy: false });
1100+
1101+
const bsphereShape = operations.boundingSphereShapeOfShape({ shape: torus });
1102+
const bsphere = operations.boundingSphereOfShape({ shape: torus });
1103+
1104+
// Get the volume of the bounding sphere
1105+
const volume = solid.getSolidVolume({ shape: bsphereShape });
1106+
const expectedVolume = (4 / 3) * Math.PI * Math.pow(bsphere.radius, 3);
1107+
1108+
expect(volume).toBeCloseTo(expectedVolume, 2);
1109+
1110+
circle.delete();
1111+
torus.delete();
1112+
bsphereShape.delete();
1113+
});
1114+
1115+
it("should get bounding sphere of compound with multiple shapes", () => {
1116+
const sphere1 = occHelper.entitiesService.bRepPrimAPIMakeSphere([0, 0, 0], [0, 1, 0], 1);
1117+
const sphere2 = occHelper.entitiesService.bRepPrimAPIMakeSphere([10, 0, 0], [0, 1, 0], 1);
1118+
const compound = occHelper.converterService.makeCompound({ shapes: [sphere1, sphere2] });
1119+
1120+
const bsphere = operations.boundingSphereOfShape({ shape: compound });
1121+
1122+
// Center should be at midpoint of bounding box
1123+
expect(bsphere.center[0]).toBeCloseTo(5, 5);
1124+
expect(bsphere.center[1]).toBeCloseTo(0, 5);
1125+
expect(bsphere.center[2]).toBeCloseTo(0, 5);
1126+
1127+
expect(bsphere.radius).toBeCloseTo(Math.sqrt(38), 2);
1128+
1129+
sphere1.delete();
1130+
sphere2.delete();
1131+
compound.delete();
1132+
});
1133+
1134+
it("should get bounding sphere for a wire", () => {
1135+
const points = [
1136+
[0, 0, 0],
1137+
[10, 0, 0],
1138+
[10, 10, 0],
1139+
[0, 10, 0]
1140+
] as Inputs.Base.Point3[];
1141+
const squareWire = wire.createPolylineWire({ points });
1142+
1143+
const bsphere = operations.boundingSphereOfShape({ shape: squareWire });
1144+
1145+
expect(bsphere.center).toEqual([5, 5, 0]);
1146+
expect(bsphere.radius).toBeCloseTo(Math.sqrt(50), 5);
1147+
1148+
squareWire.delete();
1149+
});
1150+
1151+
it("should compare bounding box and bounding sphere volumes", () => {
1152+
const box = occHelper.entitiesService.bRepPrimAPIMakeBox(4, 4, 4, [-2, -2, -2]);
1153+
1154+
const bboxShape = operations.boundingBoxShapeOfShape({ shape: box });
1155+
const bsphereShape = operations.boundingSphereShapeOfShape({ shape: box });
1156+
1157+
const bboxVolume = solid.getSolidVolume({ shape: bboxShape });
1158+
const bsphereVolume = solid.getSolidVolume({ shape: bsphereShape });
1159+
1160+
// Bounding sphere should always have larger volume than bounding box for a cube
1161+
expect(bsphereVolume).toBeGreaterThan(bboxVolume);
1162+
expect(bboxVolume).toBeCloseTo(64, 4);
1163+
1164+
box.delete();
1165+
bboxShape.delete();
1166+
bsphereShape.delete();
1167+
});
1168+
});
1169+
9171170

9181171
});
9191172

0 commit comments

Comments
 (0)