Skip to content

Commit 12e6920

Browse files
update that makes worker not to use OCCT result property as a way to get simple base values. Caching had to be updated for that. Unit tests implemented to test it out.
1 parent 473c6f7 commit 12e6920

File tree

9 files changed

+324
-48
lines changed

9 files changed

+324
-48
lines changed
File renamed without changes.

declarationsInputs.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2446,7 +2446,7 @@ export const inputDeclarations = `declare namespace Asset {
24462446
direction: Base.Vector3;
24472447
}
24482448
class LoftDto<T> {
2449-
constructor(shapes?: T[], makeSolid?: boolean);
2449+
constructor(shapes?: T[]);
24502450
/**
24512451
* Wires through which the loft passes
24522452
*/
@@ -2457,7 +2457,7 @@ export const inputDeclarations = `declare namespace Asset {
24572457
makeSolid: boolean;
24582458
}
24592459
class LoftAdvancedDto<T> {
2460-
constructor(shapes?: T[], makeSolid?: boolean, closed?: boolean, periodic?: boolean, straight?: boolean, nrPerpendicularSections?: number, useSmoothing?: boolean, maxUDegree?: number, parType?: ApproxParametrizationTypeEnum, tolerance?: number, startVertex?: Base.Point3, endVertex?: Base.Point3);
2460+
constructor(shapes?: T[]);
24612461
/**
24622462
* Wires through which the loft passes
24632463
*/

lib/api/bitbybit.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export class BitByBitBase {
2828
public context: Context;
2929
public jscadWorkerManager: JSCADWorkerManager;
3030
public occtWorkerManager: OCCTWorkerManager;
31-
31+
3232
public babylon: Babylon;
3333
public vector: Vector;
3434
public point: Point;

lib/api/inputs/occ-inputs.ts

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -692,9 +692,8 @@ export namespace OCCT {
692692
direction: Base.Vector3
693693
}
694694
export class LoftDto<T> {
695-
constructor(shapes?: T[], makeSolid?: boolean) {
695+
constructor(shapes?: T[]) {
696696
this.shapes = shapes;
697-
this.makeSolid = makeSolid;
698697
}
699698
/**
700699
* Wires through which the loft passes
@@ -708,30 +707,8 @@ export namespace OCCT {
708707
export class LoftAdvancedDto<T> {
709708
constructor(
710709
shapes?: T[],
711-
makeSolid?: boolean,
712-
closed?: boolean,
713-
periodic?: boolean,
714-
straight?: boolean,
715-
nrPerpendicularSections?: number,
716-
useSmoothing?: boolean,
717-
maxUDegree?: number,
718-
parType?: ApproxParametrizationTypeEnum,
719-
tolerance?: number,
720-
startVertex?: Base.Point3,
721-
endVertex?: Base.Point3,
722710
) {
723711
this.shapes = shapes;
724-
this.makeSolid = makeSolid;
725-
this.closed = closed;
726-
this.periodic = periodic;
727-
this.straight = straight;
728-
this.nrPeriodicSections = nrPerpendicularSections;
729-
this.useSmoothing = useSmoothing;
730-
this.maxUDegree = maxUDegree;
731-
this.parType = parType;
732-
this.tolerance = tolerance;
733-
this.startVertex = startVertex;
734-
this.endVertex = endVertex;
735712
}
736713
/**
737714
* Wires through which the loft passes

lib/workers/occ/cache-helper.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ export class CacheHelper {
5757
// this.hashesFromPreviousRun = {};
5858
}
5959

60+
isOCCTObject(obj): boolean {
61+
return (!Array.isArray(obj) && obj.$$ !== undefined) || (Array.isArray(obj) && obj[0].$$ !== undefined)
62+
}
63+
6064
/** Hashes input arguments and checks the cache for that hash.
6165
* It returns a copy of the cached object if it exists, but will
6266
* call the `cacheMiss()` callback otherwise. The result will be
@@ -71,19 +75,27 @@ export class CacheHelper {
7175
if (check) {
7276
// TODO I need to check if and why cloning is required.
7377
// toReturn = new this.occ.TopoDS_Shape(check);
74-
toReturn = check;
75-
toReturn.hash = check.hash;
78+
if (this.isOCCTObject(check)) {
79+
toReturn = check;
80+
toReturn.hash = check.hash;
81+
} else if (check.value) {
82+
toReturn = check.value;
83+
}
7684
} else {
7785
toReturn = cacheMiss();
78-
if (Array.isArray(toReturn)) {
86+
if (Array.isArray(toReturn) && this.isOCCTObject(toReturn)) {
7987
toReturn.forEach((r, index) => {
8088
const itemHash = this.computeHash({ ...args, index });
8189
r.hash = itemHash;
8290
this.addToCache(itemHash, r);
8391
});
8492
} else {
85-
toReturn.hash = curHash;
86-
this.addToCache(curHash, toReturn);
93+
if (this.isOCCTObject(toReturn)) {
94+
toReturn.hash = curHash;
95+
this.addToCache(curHash, toReturn);
96+
} else {
97+
this.addToCache(curHash, { value: toReturn });
98+
}
8799
}
88100

89101
}

lib/workers/occ/occ-worker.test.ts

Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
import initOpenCascade, { OpenCascadeInstance } from "bitbybit-occt/bitbybit-dev-occt/bitbybit-dev-occt";
2+
import * as Inputs from "bitbybit-occt/lib/api/inputs";
3+
import { CacheHelper } from "./cache-helper";
4+
import { initializationComplete, onMessageInput } from "./occ-worker";
5+
6+
describe('OCCT wire unit tests', () => {
7+
let occt: OpenCascadeInstance;
8+
9+
let cacheHelper: CacheHelper;
10+
beforeAll(async () => {
11+
occt = await initOpenCascade();
12+
cacheHelper = initializationComplete(occt, true);
13+
});
14+
15+
beforeEach(() => {
16+
cacheHelper.cleanAllCache();
17+
});
18+
19+
it('should', () => {
20+
expect(true).toBe(true);
21+
});
22+
23+
it('should create a wire', async () => {
24+
const cdto = new Inputs.OCCT.CircleDto(1, [0, 0, 0], [0, 1, 0]);
25+
const wire = await callAction<Inputs.OCCT.CircleDto>('shapes.wire.createCircleWire', cdto);
26+
expect(wire.hash).toEqual(1646405596);
27+
expect(wire.type).toEqual('occ-shape');
28+
});
29+
30+
it('should get length of a wire', async () => {
31+
const cdto = new Inputs.OCCT.CircleDto(1, [0, 0, 0], [0, 1, 0]);
32+
const wire = await callAction<Inputs.OCCT.CircleDto>('shapes.wire.createCircleWire', cdto);
33+
expect(wire.hash).toEqual(1646405596);
34+
expect(wire.type).toEqual('occ-shape');
35+
const length = await callAction<Inputs.OCCT.ShapeDto<Inputs.OCCT.TopoDSWirePointer>>('shapes.wire.getWireLength', { shape: wire });
36+
expect(length).toBe(6.283185307179586);
37+
});
38+
39+
40+
it('should create advanced loft through straight sections', async () => {
41+
const loft = await createLoft(callAction);
42+
expect(loft.hash).toBe(716684607);
43+
expect(loft.type).toBe('occ-shape');
44+
});
45+
46+
it('should loft advanced and use cache', async () => {
47+
const loft1 = await createLoft(callAction);
48+
const loft2 = await createLoft(callAction);
49+
50+
expect(loft1.hash).toBe(loft2.hash);
51+
expect(loft2.type).toBe('occ-shape');
52+
});
53+
54+
it('should subdivide wire into points', async () => {
55+
const cdto1 = new Inputs.OCCT.CircleDto(1, [0, 0, 0], [0, 1, 0]);
56+
const wire1 = await callAction<Inputs.OCCT.CircleDto>('shapes.wire.createCircleWire', cdto1);
57+
const divDto = new Inputs.OCCT.DivideDto(wire1, 10);
58+
const points = await callAction<Inputs.OCCT.DivideDto<Inputs.OCCT.TopoDSWirePointer>>('shapes.wire.divideWireByParamsToPoints', divDto);
59+
expect(points.length).toBe(11);
60+
expect(points).toEqual([
61+
[0, 0, 1],
62+
[0.5877852522924731, 0, 0.8090169943749475],
63+
[0.9510565162951535, 0, 0.30901699437494745],
64+
[0.9510565162951536, 0, -0.30901699437494734],
65+
[0.5877852522924732, 0, -0.8090169943749473],
66+
[1.2246467991473532e-16, 0, -1],
67+
[-0.587785252292473, 0, -0.8090169943749475],
68+
[-0.9510565162951535, 0, -0.30901699437494756],
69+
[-0.9510565162951536, 0, 0.30901699437494723],
70+
[-0.5877852522924734, 0, 0.8090169943749473],
71+
[-2.4492935982947064e-16, 0, 1]
72+
]);
73+
});
74+
75+
it('should subdivide wire into points', async () => {
76+
const cdto1 = new Inputs.OCCT.CircleDto(1, [0, 0, 0], [0, 1, 0]);
77+
const wire1 = await callAction<Inputs.OCCT.CircleDto>('shapes.wire.createCircleWire', cdto1);
78+
const divDto = new Inputs.OCCT.DivideDto(wire1, 10);
79+
await callAction<Inputs.OCCT.DivideDto<Inputs.OCCT.TopoDSWirePointer>>('shapes.wire.divideWireByParamsToPoints', divDto);
80+
const points2 = await callAction<Inputs.OCCT.DivideDto<Inputs.OCCT.TopoDSWirePointer>>('shapes.wire.divideWireByParamsToPoints', divDto);
81+
expect(points2.length).toBe(11);
82+
expect(points2).toEqual([
83+
[0, 0, 1],
84+
[0.5877852522924731, 0, 0.8090169943749475],
85+
[0.9510565162951535, 0, 0.30901699437494745],
86+
[0.9510565162951536, 0, -0.30901699437494734],
87+
[0.5877852522924732, 0, -0.8090169943749473],
88+
[1.2246467991473532e-16, 0, -1],
89+
[-0.587785252292473, 0, -0.8090169943749475],
90+
[-0.9510565162951535, 0, -0.30901699437494756],
91+
[-0.9510565162951536, 0, 0.30901699437494723],
92+
[-0.5877852522924734, 0, 0.8090169943749473],
93+
[-2.4492935982947064e-16, 0, 1]
94+
]);
95+
});
96+
97+
it('should get lengths of edges', async () => {
98+
const boxDto = new Inputs.OCCT.BoxDto(1, 1, 1);
99+
const box = await callAction<Inputs.OCCT.BoxDto>('shapes.solid.createBox', boxDto);
100+
expect(box.hash).toBe(-470453211);
101+
expect(box.type).toBe('occ-shape');
102+
const edges = await callAction<Inputs.OCCT.ShapeDto<Inputs.OCCT.TopoDSShapePointer>>('shapes.edge.getEdges', { shape: box });
103+
const lengths = await callAction<Inputs.OCCT.ShapesDto<Inputs.OCCT.TopoDSShapePointer>>('shapes.edge.getEdgesLengths', { shapes: edges });
104+
expect(lengths.length).toBe(12);
105+
expect(lengths).toEqual([
106+
1, 1, 1, 1, 1,
107+
1, 1, 1, 1, 1,
108+
1, 1
109+
]);
110+
const lengths2 = await callAction<Inputs.OCCT.ShapesDto<Inputs.OCCT.TopoDSShapePointer>>('shapes.edge.getEdgesLengths', { shapes: edges });
111+
expect(lengths2.length).toBe(12);
112+
expect(lengths2).toEqual([
113+
1, 1, 1, 1, 1,
114+
1, 1, 1, 1, 1,
115+
1, 1
116+
]);
117+
});
118+
119+
it('should get edges of a box and subdivide them into points', async () => {
120+
const boxDto = new Inputs.OCCT.BoxDto(1, 1, 1);
121+
const box = await callAction<Inputs.OCCT.BoxDto>('shapes.solid.createBox', boxDto);
122+
expect(box.hash).toBe(-470453211);
123+
expect(box.type).toBe('occ-shape');
124+
const edges = await callAction<Inputs.OCCT.ShapeDto<Inputs.OCCT.TopoDSShapePointer>>('shapes.edge.getEdges', { shape: box });
125+
expect(edges.length).toBe(12);
126+
const expectedEdgesResultBeforeCache = [
127+
{ hash: 1474984972, type: 'occ-shape' },
128+
{ hash: 1474985003, type: 'occ-shape' },
129+
{ hash: 1474985034, type: 'occ-shape' },
130+
{ hash: 1474985065, type: 'occ-shape' },
131+
{ hash: 1474985096, type: 'occ-shape' },
132+
{ hash: 1474985127, type: 'occ-shape' },
133+
{ hash: 1474985158, type: 'occ-shape' },
134+
{ hash: 1474985189, type: 'occ-shape' },
135+
{ hash: 1474985220, type: 'occ-shape' },
136+
{ hash: 1474985251, type: 'occ-shape' },
137+
{ hash: -1520107425, type: 'occ-shape' },
138+
{ hash: -1520107394, type: 'occ-shape' }
139+
];
140+
expect(edges).toEqual(expectedEdgesResultBeforeCache);
141+
const edgesAfterCache = await callAction<Inputs.OCCT.ShapeDto<Inputs.OCCT.TopoDSShapePointer>>('shapes.edge.getEdges', { shape: box });
142+
expect(edgesAfterCache).toEqual(expectedEdgesResultBeforeCache);
143+
144+
const points = await Promise.all(
145+
edgesAfterCache.map(edge => {
146+
const divDto = new Inputs.OCCT.DivideDto(edge, 4);
147+
return callAction<Inputs.OCCT.DivideDto<Inputs.OCCT.TopoDSWirePointer>>('shapes.edge.divideEdgeByParamsToPoints', divDto);
148+
})
149+
);
150+
expect(points).toEqual([
151+
[
152+
[-0.5, -0.5, -0.5],
153+
[-0.5, -0.5, -0.25],
154+
[-0.5, -0.5, 0],
155+
[-0.5, -0.5, 0.25],
156+
[-0.5, -0.5, 0.5]
157+
],
158+
[
159+
[-0.5, -0.5, 0.5],
160+
[-0.5, -0.25, 0.5],
161+
[-0.5, 0, 0.5],
162+
[-0.5, 0.25, 0.5],
163+
[-0.5, 0.5, 0.5]
164+
],
165+
[
166+
[-0.5, 0.5, 0.5],
167+
[-0.5, 0.5, 0.25],
168+
[-0.5, 0.5, 0],
169+
[-0.5, 0.5, -0.25],
170+
[-0.5, 0.5, -0.5]
171+
],
172+
[
173+
[-0.5, 0.5, -0.5],
174+
[-0.5, 0.25, -0.5],
175+
[-0.5, 0, -0.5],
176+
[-0.5, -0.25, -0.5],
177+
[-0.5, -0.5, -0.5]
178+
],
179+
[
180+
[0.5, -0.5, 0.5],
181+
[0.5, -0.5, 0.25],
182+
[0.5, -0.5, 0],
183+
[0.5, -0.5, -0.25],
184+
[0.5, -0.5, -0.5]
185+
],
186+
[
187+
[0.5, 0.5, 0.5],
188+
[0.5, 0.25, 0.5],
189+
[0.5, 0, 0.5],
190+
[0.5, -0.25, 0.5],
191+
[0.5, -0.5, 0.5]
192+
],
193+
[
194+
[0.5, 0.5, -0.5],
195+
[0.5, 0.5, -0.25],
196+
[0.5, 0.5, 0],
197+
[0.5, 0.5, 0.25],
198+
[0.5, 0.5, 0.5]
199+
],
200+
[
201+
[0.5, -0.5, -0.5],
202+
[0.5, -0.25, -0.5],
203+
[0.5, 0, -0.5],
204+
[0.5, 0.25, -0.5],
205+
[0.5, 0.5, -0.5]
206+
],
207+
[
208+
[-0.5, -0.5, -0.5],
209+
[-0.25, -0.5, -0.5],
210+
[0, -0.5, -0.5],
211+
[0.25, -0.5, -0.5],
212+
[0.5, -0.5, -0.5]
213+
],
214+
[
215+
[0.5, -0.5, 0.5],
216+
[0.25, -0.5, 0.5],
217+
[0, -0.5, 0.5],
218+
[-0.25, -0.5, 0.5],
219+
[-0.5, -0.5, 0.5]
220+
],
221+
[
222+
[0.5, 0.5, -0.5],
223+
[0.25, 0.5, -0.5],
224+
[0, 0.5, -0.5],
225+
[-0.25, 0.5, -0.5],
226+
[-0.5, 0.5, -0.5]
227+
],
228+
[
229+
[-0.5, 0.5, 0.5],
230+
[-0.25, 0.5, 0.5],
231+
[0, 0.5, 0.5],
232+
[0.25, 0.5, 0.5],
233+
[0.5, 0.5, 0.5]
234+
]
235+
])
236+
});
237+
238+
const callAction: <T>(functionName: string, inputs: T) => any = (functionName, inputs) => {
239+
return new Promise((resolve, reject) => {
240+
try {
241+
onMessageInput({
242+
action: {
243+
functionName,
244+
inputs
245+
},
246+
uid: 'sdadwa',
247+
}, (data) => {
248+
if (data !== 'busy') {
249+
resolve(data.result)
250+
}
251+
if (data.error) {
252+
console.error('ERROR HAPPENED: ', data.error);
253+
reject(data.error)
254+
}
255+
});
256+
} catch (err) {
257+
console.error('ERROR HAPPENED: ', err);
258+
reject(err)
259+
}
260+
});
261+
}
262+
263+
});
264+
265+
async function createLoft(callAction: <T>(functionName: string, inputs: T) => any) {
266+
const cdto1 = new Inputs.OCCT.CircleDto(1, [0, 0, 0], [0, 1, 0]);
267+
const wire1 = await callAction<Inputs.OCCT.CircleDto>('shapes.wire.createCircleWire', cdto1);
268+
269+
const cdto2 = new Inputs.OCCT.CircleDto(2, [0, 1, 0], [0, 1, 0]);
270+
const wire2 = await callAction<Inputs.OCCT.CircleDto>('shapes.wire.createCircleWire', cdto2);
271+
272+
const cdto3 = new Inputs.OCCT.CircleDto(1.5, [0, 2, 0], [0, 1, 0]);
273+
const wire3 = await callAction<Inputs.OCCT.CircleDto>('shapes.wire.createCircleWire', cdto3);
274+
275+
const ldto = new Inputs.OCCT.LoftAdvancedDto([wire1, wire2, wire3]);
276+
ldto.closed = true;
277+
ldto.straight = true;
278+
const loft = await callAction<Inputs.OCCT.LoftAdvancedDto<Inputs.OCCT.TopoDSShapePointer>>('operations.loftAdvanced', ldto);
279+
return loft;
280+
}
281+

0 commit comments

Comments
 (0)