From 5d43cc6d046ff3020e80650b97543f238abf4b35 Mon Sep 17 00:00:00 2001 From: martinRenou Date: Fri, 17 Nov 2023 12:52:18 +0100 Subject: [PATCH] Update OCC build (#221) * Update OCC build * Linter * Fix --- packages/occ-worker/package.json | 5 +- packages/occ-worker/src/actions.ts | 186 +----------------- packages/occ-worker/src/occapi.ts | 64 +++--- packages/occ-worker/src/occparser.ts | 53 +++-- packages/occ-worker/src/operatorcache.ts | 10 +- packages/occ-worker/src/types.ts | 4 +- packages/occ-worker/src/worker.ts | 6 +- packages/occ-worker/worker.webpack.config.js | 5 +- packages/opencascade/.gitignore | 5 + ...encascade.js => build_opencascade_wasm.js} | 4 +- packages/opencascade/package.json | 19 +- packages/opencascade/src/index.ts | 16 ++ packages/opencascade/tsconfig.json | 8 + .../extension.webpack.config.js | 12 +- yarn.lock | 84 +++++++- 15 files changed, 205 insertions(+), 276 deletions(-) create mode 100644 packages/opencascade/.gitignore rename packages/opencascade/{build_opencascade.js => build_opencascade_wasm.js} (96%) create mode 100644 packages/opencascade/src/index.ts create mode 100644 packages/opencascade/tsconfig.json diff --git a/packages/occ-worker/package.json b/packages/occ-worker/package.json index d540186c..c10c96cf 100644 --- a/packages/occ-worker/package.json +++ b/packages/occ-worker/package.json @@ -25,8 +25,9 @@ }, "scripts": { "build:lib": "tsc -b", - "build": "jlpm build:lib && webpack --config worker.webpack.config.js --mode=development", - "build:prod": "jlpm build:lib && webpack --config worker.webpack.config.js --mode=production", + "build": "jlpm build:lib && webpack --config worker.webpack.config.js --mode=development && jlpm run build:remove_full_occ_wasm", + "build:prod": "jlpm build:lib && webpack --config worker.webpack.config.js --mode=production && jlpm run build:remove_full_occ_wasm", + "build:remove_full_occ_wasm": "rimraf lib/opencascade.full.wasm", "clean": "rimraf tsconfig.tsbuildinfo", "clean:lib": "rimraf lib tsconfig.tsbuildinfo", "clean:all": "jlpm run clean:lib", diff --git a/packages/occ-worker/src/actions.ts b/packages/occ-worker/src/actions.ts index 3b587330..cb85180d 100644 --- a/packages/occ-worker/src/actions.ts +++ b/packages/occ-worker/src/actions.ts @@ -1,8 +1,4 @@ -import { - Handle_Poly_Triangulation, - OpenCascadeInstance, - TopoDS_Shape -} from '@jupytercad/opencascade'; +import { OCC } from '@jupytercad/opencascade'; import { IJCadContent, IJCadObject } from '@jupytercad/schema'; import { IDict, WorkerAction } from './types'; @@ -10,189 +6,15 @@ import { BrepFile, ShapesFactory } from './occapi'; import { OccParser } from './occparser'; import { IOperatorArg, IOperatorFuncOutput } from './types'; -let occ: OpenCascadeInstance; +let occ: OCC.OpenCascadeInstance; -export function getOcc(): OpenCascadeInstance { +export function getOcc(): OCC.OpenCascadeInstance { if (!occ) { - occ = (self as any).occ as OpenCascadeInstance; + occ = (self as any).occ as OCC.OpenCascadeInstance; } return occ; } -interface IFace { - vertex_coord: Array; - uv_coord: Array; - normal_coord: Array; - tri_indexes: Array; - number_of_triangles: number; -} - -/** - * Convert OpenCascade shapes into `THREE` compatible data types. - * - * @param {Array} shapeData - * @returns {{ - * faceList: any[]; - * edgeList: any[]; - * }} - */ -export function shapeToThree( - shapeData: Array<{ occShape: TopoDS_Shape; jcObject: IJCadObject }> -): { - faceList: any[]; - edgeList: any[]; -} { - const oc = getOcc(); - const maxDeviation = 0.5; - const faceList: Array = []; - const edgeList = []; - const triangulations: Array = []; - shapeData.forEach(data => { - const { occShape: shape, jcObject } = data; - if (!jcObject.visible) { - return; - } - new oc.BRepMesh_IncrementalMesh_2( - shape, - maxDeviation, - false, - maxDeviation * 5, - true - ); - - const expl = new oc.TopExp_Explorer_2( - shape, - oc.TopAbs_ShapeEnum.TopAbs_FACE as any, - oc.TopAbs_ShapeEnum.TopAbs_SHAPE as any - ); - expl.Init( - shape, - oc.TopAbs_ShapeEnum.TopAbs_FACE as any, - oc.TopAbs_ShapeEnum.TopAbs_SHAPE as any - ); - while (expl.More()) { - const face = oc.TopoDS.Face_1(expl.Current()); - const aLocation = new oc.TopLoc_Location_1(); - const myT = oc.BRep_Tool.Triangulation(face, aLocation); - if (myT.IsNull()) { - console.error('Encountered Null Face!'); - return; - } - const thisFace: IFace = { - vertex_coord: [], - uv_coord: [], - normal_coord: [], - tri_indexes: [], - number_of_triangles: 0 - }; - const pc = new oc.Poly_Connect_2(myT); - const nodes = myT.get().Nodes(); - - thisFace.vertex_coord = new Array(nodes.Length() * 3); - for (let i = 0; i < nodes.Length(); i++) { - const p = nodes.Value(i + 1).Transformed(aLocation.Transformation()); - thisFace.vertex_coord[i * 3 + 0] = p.X(); - thisFace.vertex_coord[i * 3 + 1] = p.Y(); - thisFace.vertex_coord[i * 3 + 2] = p.Z(); - } - // Write UV buffer - const orient = face.Orientation_1(); - if (myT.get().HasUVNodes()) { - // Get UV Bounds - let UMin = 0, - UMax = 0, - VMin = 0, - VMax = 0; - - const UVNodes = myT.get().UVNodes(), - UVNodesLength = UVNodes.Length(); - thisFace.uv_coord = new Array(UVNodesLength * 2); - for (let i = 0; i < UVNodesLength; i++) { - const p = UVNodes.Value(i + 1); - const x = p.X(), - y = p.Y(); - thisFace.uv_coord[i * 2 + 0] = x; - thisFace.uv_coord[i * 2 + 1] = y; - - // Compute UV Bounds - if (i === 0) { - UMin = x; - UMax = x; - VMin = y; - VMax = y; - } - if (x < UMin) { - UMin = x; - } else if (x > UMax) { - UMax = x; - } - if (y < VMin) { - VMin = y; - } else if (y > VMax) { - VMax = y; - } - } - - // Normalize each face's UVs to 0-1 - for (let i = 0; i < UVNodesLength; i++) { - let x = thisFace.uv_coord[i * 2 + 0], - y = thisFace.uv_coord[i * 2 + 1]; - - x = (x - UMin) / (UMax - UMin); - y = (y - VMin) / (VMax - VMin); - if (orient !== oc.TopAbs_Orientation.TopAbs_FORWARD) { - x = 1.0 - x; - } - - thisFace.uv_coord[i * 2 + 0] = x; - thisFace.uv_coord[i * 2 + 1] = y; - } - } - // Write normal buffer - const myNormal = new oc.TColgp_Array1OfDir_2( - nodes.Lower(), - nodes.Upper() - ); - // let SST = new oc.StdPrs_ToolTriangulatedShape(); - oc.StdPrs_ToolTriangulatedShape.Normal(face, pc, myNormal); - thisFace.normal_coord = new Array(myNormal.Length() * 3); - for (let i = 0; i < myNormal.Length(); i++) { - const d = myNormal.Value(i + 1).Transformed(aLocation.Transformation()); - thisFace.normal_coord[i * 3 + 0] = d.X(); - thisFace.normal_coord[i * 3 + 1] = d.Y(); - thisFace.normal_coord[i * 3 + 2] = d.Z(); - } - - // Write triangle buffer - const triangles = myT.get().Triangles(); - thisFace.tri_indexes = new Array(triangles.Length() * 3); - let validFaceTriCount = 0; - for (let nt = 1; nt <= myT.get().NbTriangles(); nt++) { - const t = triangles.Value(nt); - let n1 = t.Value(1); - let n2 = t.Value(2); - const n3 = t.Value(3); - if (orient !== oc.TopAbs_Orientation.TopAbs_FORWARD) { - const tmp = n1; - n1 = n2; - n2 = tmp; - } - - thisFace.tri_indexes[validFaceTriCount * 3 + 0] = n1 - 1; - thisFace.tri_indexes[validFaceTriCount * 3 + 1] = n2 - 1; - thisFace.tri_indexes[validFaceTriCount * 3 + 2] = n3 - 1; - validFaceTriCount++; - } - thisFace.number_of_triangles = validFaceTriCount; - faceList.push(thisFace); - triangulations.push(myT); - expl.Next(); - } - }); - - return { faceList, edgeList }; -} - function buildModel( model: IJCadContent ): { shapeData: IOperatorFuncOutput; jcObject: IJCadObject }[] { diff --git a/packages/occ-worker/src/occapi.ts b/packages/occ-worker/src/occapi.ts index 227be08d..d0207b04 100644 --- a/packages/occ-worker/src/occapi.ts +++ b/packages/occ-worker/src/occapi.ts @@ -1,4 +1,4 @@ -import { TopoDS_Shape } from '@jupytercad/opencascade'; +import { OCC } from '@jupytercad/opencascade'; import { v4 as uuid } from 'uuid'; import { @@ -25,13 +25,13 @@ import { IAllOperatorFunc, IOperatorArg } from './types'; import { toRad } from './utils'; function setShapePlacement( - shape: TopoDS_Shape, + shape: OCC.TopoDS_Shape, placement?: { Position: number[]; Axis: number[]; Angle: number; } -): TopoDS_Shape { +): OCC.TopoDS_Shape { if (!placement) { return shape; } @@ -52,11 +52,11 @@ function setShapePlacement( ) ); const loc = new oc.TopLoc_Location_2(trsf); - shape.Location_2(loc); + shape.Location_2(loc, true); return shape; } -function _Box(arg: IBox, _: IJCadContent): TopoDS_Shape | undefined { +function _Box(arg: IBox, _: IJCadContent): OCC.TopoDS_Shape | undefined { const { Length, Width, Height, Placement } = arg; const oc = getOcc(); const box = new oc.BRepPrimAPI_MakeBox_2(Length, Width, Height); @@ -64,7 +64,10 @@ function _Box(arg: IBox, _: IJCadContent): TopoDS_Shape | undefined { return setShapePlacement(shape, Placement); } -function _Cylinder(arg: ICylinder, _: IJCadContent): TopoDS_Shape | undefined { +function _Cylinder( + arg: ICylinder, + _: IJCadContent +): OCC.TopoDS_Shape | undefined { const { Radius, Height, Angle, Placement } = arg; const oc = getOcc(); const cylinder = new oc.BRepPrimAPI_MakeCylinder_2( @@ -76,7 +79,7 @@ function _Cylinder(arg: ICylinder, _: IJCadContent): TopoDS_Shape | undefined { return setShapePlacement(shape, Placement); } -function _Sphere(arg: ISphere, _: IJCadContent): TopoDS_Shape | undefined { +function _Sphere(arg: ISphere, _: IJCadContent): OCC.TopoDS_Shape | undefined { const { Radius, Angle1, Angle2, Angle3, Placement } = arg; const oc = getOcc(); const sphere = new oc.BRepPrimAPI_MakeSphere_4( @@ -89,7 +92,7 @@ function _Sphere(arg: ISphere, _: IJCadContent): TopoDS_Shape | undefined { return setShapePlacement(shape, Placement); } -function _Cone(arg: ICone, _: IJCadContent): TopoDS_Shape | undefined { +function _Cone(arg: ICone, _: IJCadContent): OCC.TopoDS_Shape | undefined { const { Radius1, Radius2, Height, Angle, Placement } = arg; const oc = getOcc(); const cone = new oc.BRepPrimAPI_MakeCone_2( @@ -102,7 +105,7 @@ function _Cone(arg: ICone, _: IJCadContent): TopoDS_Shape | undefined { return setShapePlacement(shape, Placement); } -function _Torus(arg: ITorus, _: IJCadContent): TopoDS_Shape | undefined { +function _Torus(arg: ITorus, _: IJCadContent): OCC.TopoDS_Shape | undefined { const { Radius1, Radius2, Angle1, Angle2, Angle3, Placement } = arg; const oc = getOcc(); const torus = new oc.BRepPrimAPI_MakeTorus_4( @@ -116,7 +119,7 @@ function _Torus(arg: ITorus, _: IJCadContent): TopoDS_Shape | undefined { return setShapePlacement(shape, Placement); } -function _Cut(arg: ICut, content: IJCadContent): TopoDS_Shape | undefined { +function _Cut(arg: ICut, content: IJCadContent): OCC.TopoDS_Shape | undefined { const { Placement, Base, Tool } = arg; const oc = getOcc(); const baseObject = content.objects.filter(obj => obj.name === Base); @@ -143,7 +146,11 @@ function _Cut(arg: ICut, content: IJCadContent): TopoDS_Shape | undefined { if (base && tool) { baseObject[0].visible = false; toolObject[0].visible = false; - const operator = new oc.BRepAlgoAPI_Cut_3(base.occShape, tool.occShape); + const operator = new oc.BRepAlgoAPI_Cut_3( + base.occShape, + tool.occShape, + new oc.Message_ProgressRange_1() + ); if (operator.IsDone()) { return setShapePlacement(operator.Shape(), Placement); } @@ -151,10 +158,13 @@ function _Cut(arg: ICut, content: IJCadContent): TopoDS_Shape | undefined { } } -function _Fuse(arg: IFuse, content: IJCadContent): TopoDS_Shape | undefined { +function _Fuse( + arg: IFuse, + content: IJCadContent +): OCC.TopoDS_Shape | undefined { const oc = getOcc(); const { Shapes, Placement } = arg; - const occShapes: TopoDS_Shape[] = []; + const occShapes: OCC.TopoDS_Shape[] = []; Shapes.forEach(Base => { const baseObject = content.objects.filter(obj => obj.name === Base); if (baseObject.length === 0) { @@ -172,7 +182,11 @@ function _Fuse(arg: IFuse, content: IJCadContent): TopoDS_Shape | undefined { } } }); - const operator = new oc.BRepAlgoAPI_Fuse_3(occShapes[0], occShapes[1]); + const operator = new oc.BRepAlgoAPI_Fuse_3( + occShapes[0], + occShapes[1], + new oc.Message_ProgressRange_1() + ); if (operator.IsDone()) { return setShapePlacement(operator.Shape(), Placement); } @@ -182,10 +196,10 @@ function _Fuse(arg: IFuse, content: IJCadContent): TopoDS_Shape | undefined { function _Intersection( arg: IIntersection, content: IJCadContent -): TopoDS_Shape | undefined { +): OCC.TopoDS_Shape | undefined { const oc = getOcc(); const { Shapes, Placement } = arg; - const occShapes: TopoDS_Shape[] = []; + const occShapes: OCC.TopoDS_Shape[] = []; Shapes.forEach(Base => { const baseObject = content.objects.filter(obj => obj.name === Base); if (baseObject.length === 0) { @@ -203,7 +217,11 @@ function _Intersection( } } }); - const operator = new oc.BRepAlgoAPI_Common_3(occShapes[0], occShapes[1]); + const operator = new oc.BRepAlgoAPI_Common_3( + occShapes[0], + occShapes[1], + new oc.Message_ProgressRange_1() + ); if (operator.IsDone()) { return setShapePlacement(operator.Shape(), Placement); } @@ -213,7 +231,7 @@ function _Intersection( export function _SketchObject( arg: ISketchObject, content: IJCadContent -): TopoDS_Shape | undefined { +): OCC.TopoDS_Shape | undefined { const oc = getOcc(); const builder = new oc.BRep_Builder(); const compound = new oc.TopoDS_Compound(); @@ -241,7 +259,7 @@ export function _SketchObject( function _Extrude( arg: IExtrusion, content: IJCadContent -): TopoDS_Shape | undefined { +): OCC.TopoDS_Shape | undefined { const { Base, Dir, LengthFwd, LengthRev, Placement, Solid } = arg; const oc = getOcc(); const baseObject = content.objects.filter(obj => obj.name === Base); @@ -270,7 +288,7 @@ function _Extrude( const mov = new oc.gp_Trsf_1(); mov.SetTranslation_1(dirVec.Multiplied(-LengthRev)); const loc = new oc.TopLoc_Location_2(mov); - baseCopy.Move(loc); + baseCopy.Move(loc, true); } if (Solid) { @@ -309,7 +327,7 @@ function _Extrude( export function _Any( arg: IAny, content: IJCadContent -): TopoDS_Shape | undefined { +): OCC.TopoDS_Shape | undefined { const { Shape, Placement } = arg; const result = _loadBrep({ content: Shape }); if (result) { @@ -317,7 +335,9 @@ export function _Any( } } -export function _loadBrep(arg: { content: string }): TopoDS_Shape | undefined { +export function _loadBrep(arg: { + content: string; +}): OCC.TopoDS_Shape | undefined { const oc = getOcc(); const fakeFileName = `${uuid()}.brep`; oc.FS.createDataFile('/', fakeFileName, arg.content, true, true, true); diff --git a/packages/occ-worker/src/occparser.ts b/packages/occ-worker/src/occparser.ts index 8d05eb92..0229a5f7 100644 --- a/packages/occ-worker/src/occparser.ts +++ b/packages/occ-worker/src/occparser.ts @@ -1,8 +1,4 @@ -import { - Handle_Poly_Triangulation, - OpenCascadeInstance, - TopoDS_Shape -} from '@jupytercad/opencascade'; +import { OCC } from '@jupytercad/opencascade'; import { IJCadObject } from '@jupytercad/schema'; import { @@ -20,7 +16,7 @@ interface IShapeList { export class OccParser { private _shapeList: IShapeList[]; - private _occ: OpenCascadeInstance = (self as any).occ; + private _occ: OCC.OpenCascadeInstance = (self as any).occ; private _showEdge = true; constructor(shapeList: IShapeList[]) { this._shapeList = shapeList; @@ -59,7 +55,7 @@ export class OccParser { } private _build_wire_mesh( - shape: TopoDS_Shape, + shape: OCC.TopoDS_Shape, maxDeviation: number ): Array { const edgeList: Array = []; @@ -103,9 +99,9 @@ export class OccParser { return edgeList; } - private _build_face_mesh(shape: TopoDS_Shape): Array { + private _build_face_mesh(shape: OCC.TopoDS_Shape): Array { const faceList: Array = []; - const triangulations: Array = []; + const triangulations: Array = []; const oc = this._occ; const expl = new oc.TopExp_Explorer_2( shape, @@ -121,7 +117,7 @@ export class OccParser { while (expl.More()) { const face = oc.TopoDS.Face_1(expl.Current()); const aLocation = new oc.TopLoc_Location_1(); - const myT = oc.BRep_Tool.Triangulation(face, aLocation); + const myT = oc.BRep_Tool.Triangulation(face, aLocation, 0); if (myT.IsNull()) { console.error('Encountered Null Face!'); expl.Next(); @@ -134,11 +130,14 @@ export class OccParser { numberOfTriangles: 0 }; const pc = new oc.Poly_Connect_2(myT); - const nodes = myT.get().Nodes(); + const triangulation = myT.get(); + const nbNodes = triangulation.NbNodes(); - thisFace.vertexCoord = new Array(nodes.Length() * 3); - for (let i = 0; i < nodes.Length(); i++) { - const p = nodes.Value(i + 1).Transformed(aLocation.Transformation()); + thisFace.vertexCoord = new Array(nbNodes * 3); + for (let i = 0; i < nbNodes; i++) { + const p = triangulation + .Node(i + 1) + .Transformed(aLocation.Transformation()); thisFace.vertexCoord[i * 3 + 0] = p.X(); thisFace.vertexCoord[i * 3 + 1] = p.Y(); thisFace.vertexCoord[i * 3 + 2] = p.Z(); @@ -147,11 +146,7 @@ export class OccParser { const orient = face.Orientation_1(); // Write normal buffer - const myNormal = new oc.TColgp_Array1OfDir_2( - nodes.Lower(), - nodes.Upper() - ); - // let SST = new oc.StdPrs_ToolTriangulatedShape(); + const myNormal = new oc.TColgp_Array1OfDir_2(1, nbNodes); oc.StdPrs_ToolTriangulatedShape.Normal(face, pc, myNormal); thisFace.normalCoord = new Array(myNormal.Length() * 3); for (let i = 0; i < myNormal.Length(); i++) { @@ -161,12 +156,13 @@ export class OccParser { thisFace.normalCoord[i * 3 + 2] = d.Z(); } + const nbTriangles = triangulation.NbTriangles(); + // Write triangle buffer - const triangles = myT.get().Triangles(); - thisFace.triIndexes = new Array(triangles.Length() * 3); + thisFace.triIndexes = new Array(nbTriangles * 3); let validFaceTriCount = 0; for (let nt = 1; nt <= myT.get().NbTriangles(); nt++) { - const t = triangles.Value(nt); + const t = triangulation.Triangle(nt); let n1 = t.Value(1); let n2 = t.Value(2); const n3 = t.Value(3); @@ -188,7 +184,7 @@ export class OccParser { } return faceList; } - private _build_edge_mesh(shape: TopoDS_Shape): IEdge[] { + private _build_edge_mesh(shape: OCC.TopoDS_Shape): IEdge[] { const oc = this._occ; const edgeList: IEdge[] = []; const mapOfShape = new oc.TopTools_IndexedMapOfShape_1(); @@ -225,8 +221,9 @@ export class OccParser { if (!aLoc.IsIdentity()) { myTransf = aLoc.Transformation(); } + const poly = aPoly.get(); - nbNodesInFace = aPoly.get().NbNodes(); + nbNodesInFace = poly.NbNodes(); theEdge.numberOfCoords = nbNodesInFace; theEdge.vertexCoord = new Array(nbNodesInFace * 3); @@ -240,7 +237,7 @@ export class OccParser { } } else { const aFace = oc.TopoDS.Face_1(edgeMap.FindFromIndex(iEdge).First_1()); - const aPolyTria = oc.BRep_Tool.Triangulation(aFace, aLoc); + const aPolyTria = oc.BRep_Tool.Triangulation(aFace, aLoc, 0); if (!aLoc.IsIdentity()) { myTransf = aLoc.Transformation(); } @@ -257,12 +254,12 @@ export class OccParser { theEdge.vertexCoord = new Array(nbNodesInFace * 3); const indices = aPoly.get().Nodes(); - const nodeListOfFace = aPolyTria.get().Nodes(); + const nodeListOfFace = aPolyTria.get(); for (let jj = indices.Lower(); jj <= indices.Upper(); jj++) { - const v = nodeListOfFace.Value(indices.Value(jj)); + const v = nodeListOfFace.Node(indices.Value(jj)); v.Transform(myTransf); - const locIndex = jj - nodeListOfFace.Lower(); + const locIndex = jj - 1; theEdge.vertexCoord[locIndex * 3 + 0] = v.X(); theEdge.vertexCoord[locIndex * 3 + 1] = v.Y(); diff --git a/packages/occ-worker/src/operatorcache.ts b/packages/occ-worker/src/operatorcache.ts index 01811f41..ce19de9a 100644 --- a/packages/occ-worker/src/operatorcache.ts +++ b/packages/occ-worker/src/operatorcache.ts @@ -1,4 +1,4 @@ -import { TopoDS_Shape } from '@jupytercad/opencascade'; +import { OCC } from '@jupytercad/opencascade'; import { IJCadContent, IShapeMetadata, Parts } from '@jupytercad/schema'; import { getOcc } from './actions'; @@ -7,7 +7,7 @@ import { hashCode } from './utils'; const SHAPE_CACHE = new Map< string, - { occShape: TopoDS_Shape; metadata?: IShapeMetadata | undefined } + { occShape: OCC.TopoDS_Shape; metadata?: IShapeMetadata | undefined } >(); const PRIMITIVE_OPERATORS = [ @@ -112,7 +112,7 @@ export function expand_operator( return expanded_args; } -export function shape_meta_data(shape: TopoDS_Shape): IShapeMetadata { +export function shape_meta_data(shape: OCC.TopoDS_Shape): IShapeMetadata { const occ = getOcc(); const system = new occ.GProp_GProps_1(); occ.BRepGProp.VolumeProperties_1(shape, system, false, false, false); @@ -144,13 +144,13 @@ export function shape_meta_data(shape: TopoDS_Shape): IShapeMetadata { } export function operatorCache( name: Parts | 'BrepFile', - ops: (args: T, content: IJCadContent) => TopoDS_Shape | undefined + ops: (args: T, content: IJCadContent) => OCC.TopoDS_Shape | undefined ) { return ( args: T, content: IJCadContent ): - | { occShape: TopoDS_Shape; metadata?: IShapeMetadata | undefined } + | { occShape: OCC.TopoDS_Shape; metadata?: IShapeMetadata | undefined } | undefined => { const expandedArgs = expand_operator(name, args, content); const hash = `${hashCode(JSON.stringify(expandedArgs))}`; diff --git a/packages/occ-worker/src/types.ts b/packages/occ-worker/src/types.ts index c4309a51..ec20098a 100644 --- a/packages/occ-worker/src/types.ts +++ b/packages/occ-worker/src/types.ts @@ -1,4 +1,4 @@ -import { TopoDS_Shape } from '@jupytercad/opencascade'; +import { OCC } from '@jupytercad/opencascade'; import { IAny, IBox, @@ -89,7 +89,7 @@ export interface IWorkerInitialized { export type IMainMessage = IDisplayShape | IWorkerInitialized; export interface IOperatorFuncOutput { - occShape: TopoDS_Shape; + occShape: OCC.TopoDS_Shape; metadata?: IShapeMetadata | undefined; } diff --git a/packages/occ-worker/src/worker.ts b/packages/occ-worker/src/worker.ts index 3fe198ff..3593b5fd 100644 --- a/packages/occ-worker/src/worker.ts +++ b/packages/occ-worker/src/worker.ts @@ -1,4 +1,4 @@ -import initOpenCascade, { OpenCascadeInstance } from '@jupytercad/opencascade'; +import { initializeOpenCascade, OCC } from '@jupytercad/opencascade'; import WorkerHandler from './actions'; import { @@ -9,11 +9,11 @@ import { WorkerAction } from './types'; -let occ: OpenCascadeInstance; +let occ: OCC.OpenCascadeInstance; const ports: IDict = {}; console.log('Initializing OCC...'); -initOpenCascade().then(occInstance => { +initializeOpenCascade().then(occInstance => { console.log('Done!'); occ = occInstance; diff --git a/packages/occ-worker/worker.webpack.config.js b/packages/occ-worker/worker.webpack.config.js index 24914d80..81e89136 100644 --- a/packages/occ-worker/worker.webpack.config.js +++ b/packages/occ-worker/worker.webpack.config.js @@ -12,7 +12,10 @@ const rules = [ { test: /\.wasm$/, type: 'javascript/auto', - loader: 'file-loader' + loader: 'file-loader', + options: { + name: '[name].[ext]', + } } ]; diff --git a/packages/opencascade/.gitignore b/packages/opencascade/.gitignore new file mode 100644 index 00000000..bcd9f3ac --- /dev/null +++ b/packages/opencascade/.gitignore @@ -0,0 +1,5 @@ +src/*.wasm +src/*.js +src/*.d.ts +src/*.yml +src/*.version \ No newline at end of file diff --git a/packages/opencascade/build_opencascade.js b/packages/opencascade/build_opencascade_wasm.js similarity index 96% rename from packages/opencascade/build_opencascade.js rename to packages/opencascade/build_opencascade_wasm.js index 440f8510..5fb95ca3 100644 --- a/packages/opencascade/build_opencascade.js +++ b/packages/opencascade/build_opencascade_wasm.js @@ -10,8 +10,8 @@ const { const yaml = require('js-yaml'); const path = require('path'); -const IMAGE_NAME = 'donalffons/opencascade.js:2.0.0-beta.371bbb0'; -const OPEN_CASCADE_DIR = 'lib'; +const IMAGE_NAME = 'donalffons/opencascade.js:2.0.0-beta.b5ff984'; +const OPEN_CASCADE_DIR = 'src'; const VERSION_FILE_NAME = 'jupytercad.opencascade.version'; const VERSION_FILE_PATH = path.join(OPEN_CASCADE_DIR, VERSION_FILE_NAME); const BUILD_FILE_NAME = 'build.yml'; diff --git a/packages/opencascade/package.json b/packages/opencascade/package.json index 74b5d2a9..adfbd3fa 100644 --- a/packages/opencascade/package.json +++ b/packages/opencascade/package.json @@ -15,27 +15,30 @@ "name": "JupyterCad contributors" }, "files": [ + "lib/index.js", + "lib/index.d.ts", "lib/jupytercad.opencascade.js", "lib/jupytercad.opencascade.d.ts", "lib/jupytercad.opencascade.wasm" ], - "main": "lib/jupytercad.opencascade.js", - "types": "lib/jupytercad.opencascade.d.ts", + "main": "lib/index.js", + "types": "lib/index.d.ts", "repository": { "type": "git", "url": "https://github.com/jupytercad/jupytercad.git" }, "scripts": { - "build": "node build_opencascade.js", - "build:prod": "node build_opencascade.js", - "clean": "rimraf ./lib", - "clean:all": "rimraf ./lib" + "build": "node build_opencascade_wasm.js && tsc && copyfiles --up 1 src/*.d.ts src/*.js src/*.wasm lib", + "build:prod": "node build_opencascade_wasm.js && tsc && copyfiles --up 1 src/*.d.ts src/*.js src/*.wasm lib" }, "devDependencies": { - "js-yaml": "^4.1.0", - "rimraf": "^3.0.2" + "copyfiles": "^2.4.1", + "js-yaml": "^4.1.0" }, "publishConfig": { "access": "public" + }, + "dependencies": { + "opencascade.js": "beta" } } diff --git a/packages/opencascade/src/index.ts b/packages/opencascade/src/index.ts new file mode 100644 index 00000000..32989ce8 --- /dev/null +++ b/packages/opencascade/src/index.ts @@ -0,0 +1,16 @@ +import initOpenCascade from 'opencascade.js'; + +import opencascade from './jupytercad.opencascade.js'; +// eslint-disable-next-line no-undef +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore +import opencascadeWasm from './jupytercad.opencascade.wasm'; + +export * as OCC from './jupytercad.opencascade.js'; + +export async function initializeOpenCascade() { + return initOpenCascade({ + mainJS: opencascade, + mainWasm: opencascadeWasm + }); +} diff --git a/packages/opencascade/tsconfig.json b/packages/opencascade/tsconfig.json new file mode 100644 index 00000000..2a939247 --- /dev/null +++ b/packages/opencascade/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfigbase.json", + "compilerOptions": { + "outDir": "lib", + "rootDir": "src" + }, + "include": ["src/**/*"] +} diff --git a/python/jupytercad-core/extension.webpack.config.js b/python/jupytercad-core/extension.webpack.config.js index 03a1194d..dd9e4f0b 100644 --- a/python/jupytercad-core/extension.webpack.config.js +++ b/python/jupytercad-core/extension.webpack.config.js @@ -8,7 +8,7 @@ const occPath = [ 'node_modules', '@jupytercad/opencascade', 'lib', - '*.wasm' + 'jupytercad.opencascade.wasm' ]; const staticPath = [ __dirname, @@ -19,16 +19,6 @@ const staticPath = [ ]; module.exports = { - module: { - rules: [ - { - test: /\.wasm$/, - type: 'javascript/auto', - loader: 'file-loader' - } - // { test: /\.js$/, loader: 'source-map-loader' } - ] - }, resolve: { fallback: { fs: false, diff --git a/yarn.lock b/yarn.lock index 4fc4ec39..53cce75e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1117,8 +1117,9 @@ __metadata: version: 0.0.0-use.local resolution: "@jupytercad/opencascade@workspace:packages/opencascade" dependencies: + copyfiles: ^2.4.1 js-yaml: ^4.1.0 - rimraf: ^3.0.2 + opencascade.js: beta languageName: unknown linkType: soft @@ -5176,6 +5177,24 @@ __metadata: languageName: node linkType: hard +"copyfiles@npm:^2.4.1": + version: 2.4.1 + resolution: "copyfiles@npm:2.4.1" + dependencies: + glob: ^7.0.5 + minimatch: ^3.0.3 + mkdirp: ^1.0.4 + noms: 0.0.0 + through2: ^2.0.1 + untildify: ^4.0.0 + yargs: ^16.1.0 + bin: + copyfiles: copyfiles + copyup: copyfiles + checksum: aea69873bb99cc5f553967660cbfb70e4eeda198f572a36fb0f748b36877ff2c90fd906c58b1d540adbad8afa8ee82820172f1c18e69736f7ab52792c12745a7 + languageName: node + linkType: hard + "core-js-pure@npm:^3.6.5": version: 3.33.2 resolution: "core-js-pure@npm:3.33.2" @@ -6824,7 +6843,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6": +"glob@npm:^7.0.5, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6": version: 7.2.3 resolution: "glob@npm:7.2.3" dependencies: @@ -7354,7 +7373,7 @@ __metadata: languageName: node linkType: hard -"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3": +"inherits@npm:2, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.1, inherits@npm:~2.0.3": version: 2.0.4 resolution: "inherits@npm:2.0.4" checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1 @@ -7757,6 +7776,13 @@ __metadata: languageName: node linkType: hard +"isarray@npm:0.0.1": + version: 0.0.1 + resolution: "isarray@npm:0.0.1" + checksum: 49191f1425681df4a18c2f0f93db3adb85573bcdd6a4482539d98eac9e705d8961317b01175627e860516a2fc45f8f9302db26e5a380a97a520e272e2a40a8d4 + languageName: node + linkType: hard + "isarray@npm:^2.0.5": version: 2.0.5 resolution: "isarray@npm:2.0.5" @@ -8837,7 +8863,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": +"minimatch@npm:^3.0.3, minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" dependencies: @@ -9270,6 +9296,16 @@ __metadata: languageName: node linkType: hard +"noms@npm:0.0.0": + version: 0.0.0 + resolution: "noms@npm:0.0.0" + dependencies: + inherits: ^2.0.1 + readable-stream: ~1.0.31 + checksum: a05f056dabf764c86472b6b5aad10455f3adcb6971f366cdf36a72b559b29310a940e316bca30802f2804fdd41707941366224f4cba80c4f53071512245bf200 + languageName: node + linkType: hard + "nopt@npm:^6.0.0": version: 6.0.0 resolution: "nopt@npm:6.0.0" @@ -9685,6 +9721,15 @@ __metadata: languageName: node linkType: hard +"opencascade.js@npm:beta": + version: 2.0.0-beta.b5ff984 + resolution: "opencascade.js@npm:2.0.0-beta.b5ff984" + peerDependencies: + ws: ^8.5.0 + checksum: 751fa25e3625497fb562d4c586e884020478b9c5aeae61c43ce10bac9a011826f5c7518c2126fc6b1f79792c83bbc4d43069bff40dfbee4e48137cb9a496424e + languageName: node + linkType: hard + "optionator@npm:^0.9.1, optionator@npm:^0.9.3": version: 0.9.3 resolution: "optionator@npm:0.9.3" @@ -10620,6 +10665,18 @@ __metadata: languageName: node linkType: hard +"readable-stream@npm:~1.0.31": + version: 1.0.34 + resolution: "readable-stream@npm:1.0.34" + dependencies: + core-util-is: ~1.0.0 + inherits: ~2.0.1 + isarray: 0.0.1 + string_decoder: ~0.10.x + checksum: 85042c537e4f067daa1448a7e257a201070bfec3dd2706abdbd8ebc7f3418eb4d3ed4b8e5af63e2544d69f88ab09c28d5da3c0b77dc76185fddd189a59863b60 + languageName: node + linkType: hard + "readable-stream@npm:~2.3.6": version: 2.3.8 resolution: "readable-stream@npm:2.3.8" @@ -11469,6 +11526,13 @@ __metadata: languageName: node linkType: hard +"string_decoder@npm:~0.10.x": + version: 0.10.31 + resolution: "string_decoder@npm:0.10.31" + checksum: fe00f8e303647e5db919948ccb5ce0da7dea209ab54702894dd0c664edd98e5d4df4b80d6fabf7b9e92b237359d21136c95bf068b2f7760b772ca974ba970202 + languageName: node + linkType: hard + "string_decoder@npm:~1.1.1": version: 1.1.1 resolution: "string_decoder@npm:1.1.1" @@ -11913,7 +11977,7 @@ __metadata: languageName: node linkType: hard -"through2@npm:^2.0.0": +"through2@npm:^2.0.0, through2@npm:^2.0.1": version: 2.0.5 resolution: "through2@npm:2.0.5" dependencies: @@ -12268,21 +12332,21 @@ __metadata: "typescript@patch:typescript@>=3 < 6#~builtin, typescript@patch:typescript@^5#~builtin": version: 5.2.2 - resolution: "typescript@patch:typescript@npm%3A5.2.2#~builtin::version=5.2.2&hash=f3b441" + resolution: "typescript@patch:typescript@npm%3A5.2.2#~builtin::version=5.2.2&hash=85af82" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 0f4da2f15e6f1245e49db15801dbee52f2bbfb267e1c39225afdab5afee1a72839cd86000e65ee9d7e4dfaff12239d28beaf5ee431357fcced15fb08583d72ca + checksum: 07106822b4305de3f22835cbba949a2b35451cad50888759b6818421290ff95d522b38ef7919e70fb381c5fe9c1c643d7dea22c8b31652a717ddbd57b7f4d554 languageName: node linkType: hard "typescript@patch:typescript@~5.0.2#~builtin": version: 5.0.4 - resolution: "typescript@patch:typescript@npm%3A5.0.4#~builtin::version=5.0.4&hash=b5f058" + resolution: "typescript@patch:typescript@npm%3A5.0.4#~builtin::version=5.0.4&hash=85af82" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: d26b6ba97b6d163c55dbdffd9bbb4c211667ebebc743accfeb2c8c0154aace7afd097b51165a72a5bad2cf65a4612259344ff60f8e642362aa1695c760d303ac + checksum: bb309d320c59a26565fb3793dba550576ab861018ff3fd1b7fccabbe46ae4a35546bc45f342c0a0b6f265c801ccdf64ffd68f548f117ceb7f0eac4b805cd52a9 languageName: node linkType: hard @@ -13057,7 +13121,7 @@ __metadata: languageName: node linkType: hard -"yargs@npm:16.2.0, yargs@npm:^16.2.0": +"yargs@npm:16.2.0, yargs@npm:^16.1.0, yargs@npm:^16.2.0": version: 16.2.0 resolution: "yargs@npm:16.2.0" dependencies: