Comments (12)
Hey guys, Really cool, nice work!
from opencascade.js.
I found a super silly workaround for the problem with webidl2ts
(will file an issue over there) and just added the type definition files in v0.1.16 this library. I tested it and it seems to work well. If you find any issues with it, let me know.
@guidovanhilst, I looked at your code. Unfortunately, one of the current limitations is that not all C++ methods can be exposed if they are overloaded by type of arguments only (vs by number of arguments). I randomly picked the following methods
void BRepBuilderAPI_MakeEdge([Const, Ref] Handle_Geom_Curve C);
void BRepBuilderAPI_MakeEdge(
[Const, Ref] Handle_Geom2d_Curve L,
[Const, Ref] Handle_Geom_Surface S
);
If you think, those methods should be changed to something else, let's start a new issue. I hope I will find a solution for this limitation soon.
@zalo, I agree - let's keep this thread from getting bigger and bigger.
Hope you don't mind if I will close this now.
from opencascade.js.
That sounds super cool! I will have a shot at using this tool and if it works well, I will add it to the project.
Long-term, I think it might be better to go with Emscripten's "Embind" workflow, instead of the "IDL" workflow (for reasons... But I'm just guessing, haven't used Embind before). But for the moment, this will be super helpful to have in this library.
from opencascade.js.
Here's the use-case:
https://zalo.github.io/CascadeStudio/
I was inspired by your port and made a simple web-frontend to play with the API.
These typescript definitions are profoundly useful for discovering OCC functionality while playing around and mousing over types.
(though it probably also makes sense to have a simplified "Standard Library" for more OpenSCAD like workflows...)
(By the way, could I trouble you to include STEPControl_Writer
in the main API as well? ๐ )
from opencascade.js.
Wow, that just made my day. Yes sir, I'll get you the STEPControl_Writer
stuff into the IDL + builds.
This tool looks super useful. I have also been thinking about publishing some examples using CodeSandbox but didn't have a chance yet to work that yet. I like the super fast response you get when making changes with your tool though and might actually use this for prototyping, myself.
And yes, auto-completion and type checking is super useful when prototyping with the library and speeds up the development process a lot. I have only started using typescript a few months ago and don't want to miss it anymore.
How do you integrate the VS code editor into your website? That's such a helpful tool for building web applications...
from opencascade.js.
Thank you! The VS Code editor is integrated via monaco-editor (Microsoft's browser-friendly version of VS Code).
I'm hoping to expand the tool's features a lot (particularly save/load/import functionality) so that the BRep workflow can be a viable competitor to OpenSCAD (and OpenJSCAD). :D
Also, not to be too much of a burden, but could you also consider including the other Make Primitive Functions and PolygonOnTriangulation? I had to do some unspeakable things to make a box earlier. ๐ (and it would be nice to read edge triangulations into three.js for picking and whatnot).
from opencascade.js.
Also, not to be too much of a burden, but could you also consider including the other Make Primitive Functions and PolygonOnTriangulation? I had to do some unspeakable things to make a box earlier.
The build is running right now. Will let you know as soon as its done. I think I captured the most important parts of those interfaces. If something important is missing, let me know.
and it would be nice to read edge triangulations into three.js for picking and whatnot
If I understand you correctly, that should already be possible. You can use the TopExp_Explorer
to iterate through different classes of geometry. Here is some example code that I used in some project recently:
getEdgesFromShape() {
const shape = this.shape;
const ExpEdge = new this.openCascade.TopExp_Explorer();
const edges = [];
for(ExpEdge.Init(shape, this.openCascade.TopAbs_EDGE); ExpEdge.More(); ExpEdge.Next()) {
const myEdge = this.openCascade.TopoDS.prototype.Edge(ExpEdge.Current());
const adaptorCurve = new this.openCascade.BRepAdaptor_Curve(myEdge);
const tangDef = new this.openCascade.GCPnts_TangentialDeflection(adaptorCurve, 0.1, 0.1);
const thisEdge = [];
for(let i = 0; i < tangDef.NbPoints(); i++) {
thisEdge.push({
x: tangDef.Value(i+1).X(),
y: tangDef.Value(i+1).Y(),
z: tangDef.Value(i+1).Z(),
})
}
edges.push(thisEdge);
}
return edges;
}
from opencascade.js.
New builds are up!
from opencascade.js.
@zalo, I also tried to run the webidl2ts
script against the idl file with no success. I used this command
$ yarn webidl2ts -i ./opencascade.idl -n opencascade -ed -o ./dist/opencascade.d.ts
yarn run v1.22.4
$ /home/sebastian/Projects/opencascade.js/node_modules/.bin/webidl2ts -i ./opencascade.idl -n opencascade -ed -o ./dist/opencascade.d.ts
(node:173512) UnhandledPromiseRejectionWarning: WebIDLParseError: Syntax error at line 107, since `interface BRepPrimAPI_MakeCylinder`:
BRepPrimAPI_MakeCylinder implements BRepPrimAPI_MakeOneAxis;
^ Unrecognised tokens
at tokeniser_Tokeniser.error (/home/sebastian/Projects/opencascade.js/node_modules/webidl2/dist/webidl2.js:1:20350)
at r (/home/sebastian/Projects/opencascade.js/node_modules/webidl2/dist/webidl2.js:1:33487)
at L (/home/sebastian/Projects/opencascade.js/node_modules/webidl2/dist/webidl2.js:1:34464)
at Module.q (/home/sebastian/Projects/opencascade.js/node_modules/webidl2/dist/webidl2.js:1:34604)
at Object.<anonymous> (/home/sebastian/Projects/opencascade.js/node_modules/webidl2ts/dist/parse-idl.js:47:43)
at step (/home/sebastian/Projects/opencascade.js/node_modules/webidl2ts/dist/parse-idl.js:33:23)
at Object.next (/home/sebastian/Projects/opencascade.js/node_modules/webidl2ts/dist/parse-idl.js:14:53)
at /home/sebastian/Projects/opencascade.js/node_modules/webidl2ts/dist/parse-idl.js:8:71
at new Promise (<anonymous>)
at __awaiter (/home/sebastian/Projects/opencascade.js/node_modules/webidl2ts/dist/parse-idl.js:4:12)
(node:173512) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:173512) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Done in 0.87s.
It seems like the IDL parser has an issue with BRepPrimAPI_MakeCylinder implements BRepPrimAPI_MakeOneAxis;
or any other statement of A implements B;
. Did you have the same error? How did you manage to resolve that?
from opencascade.js.
Thank you for the example code and exposing all the extra functions! I was busy today, but Iโm excited to get back into it and add it to CascadeStudio :)
I originally used a slightly different library for the typings and manually converted all of the โimplementโs to the colon inheritance syntax; however later in the readme for this idl parser, I noticed it explicitly mentions the -e parameter as enabling a preprocess that does that conversion... maybe itโs not activating for some reason?
from opencascade.js.
I tried to make the "make bottle". (see code below)
But goes wrong due to override of oc.BRepBuilderAPI_MakeEdge.
Would it be nice if the make bottle worked?
I have made a C# script app to run OCC C# from the browser(backend) See also: MakeBottle
function MakeBottle( myWidth, myHeight, myThickness)
{
var myNeckRadius = myThickness / 4;
var myNeckHeight = myHeight / 10;
let aPnt1 = new oc.gp_Pnt(-myWidth / 2, 0, 0);
let aPnt2 = new oc.gp_Pnt(-myWidth / 2, -myThickness / 4, 0);
let aPnt3 = new oc.gp_Pnt(0, -myThickness / 2, 0);
let aPnt4 = new oc.gp_Pnt(myWidth / 2, -myThickness / 4, 0);
let aPnt5 = new oc.gp_Pnt(myWidth / 2, 0, 0);
//Profile : Define the Geometry
let aArcOfCircle = new oc.GC_MakeArcOfCircle(aPnt2, aPnt3, aPnt4).Value();
//Profile : Define the Topology
let aEdge1 = new oc.BRepBuilderAPI_MakeEdge(aPnt1, aPnt2).Edge();
let aEdge2 = new oc.BRepBuilderAPI_MakeEdge(aArcOfCircle).Edge();
let aEdge3 = new oc.BRepBuilderAPI_MakeEdge(aPnt4, aPnt5).Edge();
let aWire = new oc.BRepBuilderAPI_MakeWire(aEdge1, aEdge2, aEdge3).Wire();
//Complete Profile
let xAxis = oc.gp.OX();
let aTrsf = new oc.gp_Trsf();
aTrsf.SetMirror(xAxis);
let aBRepTrsf = new oc.BRepBuilderAPI_Transform(aWire, aTrsf, false);
let aMirroredShape = aBRepTrsf.Shape();
let aMirroredWire = oc.TopoDS.Wire(aMirroredShape);
let mkWire = new oc.BRepBuilderAPI_MakeWire();
mkWire.Add(aWire);
mkWire.Add(aMirroredWire);
let myWireProfile = mkWire.Wire();
//Body : Prism the Profile
let myFaceProfile = new oc.BRepBuilderAPI_MakeFace(myWireProfile, true).Face();
let aPrismVec = new oc.gp_Vec(0, 0, myHeight);
let myBody = new oc.BRepPrimAPI_MakePrism(myFaceProfile, aPrismVec, true, false).Shape();
//Body : Apply Fillets
let mkFillet = new oc.BRepFilletAPI_MakeFillet(myBody, oc.ChFi3d_FilletShape.ChFi3d_Rational);
let aEdgeExplorer = new oc.TopExp_Explorer(myBody, oc.TopAbs_ShapeEnum.TopAbs_EDGE, oc.TopAbs_ShapeEnum.TopAbs_SHAPE);
while (aEdgeExplorer.More())
{
let aEdge = oc.TopoDS.Edge(aEdgeExplorer.Current());
//Add edge to fillet algorithm
mkFillet.Add(myThickness / 12, aEdge);
aEdgeExplorer.Next();
}
myBody = mkFillet.Shape();
//Body : Add the Neck
let neckLoc = new oc.gp_Pnt(0, 0, myHeight);
let neckNormal = oc.gp.DZ();
let neckAx2 = new oc.gp_Ax2(neckLoc.ation, neckNormal);
let MKCylinder = new oc.BRepPrimAPI_MakeCylinder(neckAx2, myNeckRadius, myNeckHeight);
let myNeck = MKCylinder.Shape();
myBody = new oc.BRepAlgoAPI_Fuse(myBody, myNeck).Shape();
//Body : Create a Hollowed Solid
let faceToRemove = null;
zMax = -1;
let aFaceExplorer = new oc.TopExp_Explorer(myBody, oc.TopAbs_ShapeEnum.TopAbs_FACE, oc.TopAbs_ShapeEnum.TopAbs_SHAPE);
while (aFaceExplorer.More())
{
let aFace = oc.TopoDS.Face(aFaceExplorer.Current());
//Check if <aFace> is the top face of the bottle's neck
let aSurface = oc.BRep_Tool.Surface(aFace);
//if (aSurface is oc.Geom_Plane)
if(aSurface.DynamicType().Name() == "Geom_Plane")
{
let aPlane = Handle_Geom_Plane.DownCast(aSurface);
//oc.Geom_Plane aPlane = aSurface as oc.Geom_Plane;
let aPnt = aPlane.Location();
var aZ = aPnt.Z();
if (aZ > zMax)
{
zMax = aZ;
faceToRemove = aFace;
}
}
aFaceExplorer.Next();
}
let facesToRemove = new oc.TopTools_ListOfShape();
facesToRemove.Append(faceToRemove);
myBody = new oc.BRepOffsetAPI_MakeThickSolid(
myBody,
facesToRemove,
-myThickness / 50,
1 / 1000,
oc.BRepOffset_Mode.BRepOffset_Pipe,
false, false,
oc.GeomAbs_JoinType.GeomAbs_Intersection).Shape();
//return myBody;
//Threading : Create Surfaces
let neckAx3 = new oc.gp_Ax3(neckAx2);
let aCyl1 = new oc.Geom_CylindricalSurface(neckAx3, myNeckRadius * 0.99);
let aCyl2 = new oc.Geom_CylindricalSurface(neckAx3, myNeckRadius * 1.05);
//Threading : Define 2D Curves
let aPntc = new oc.gp_Pnt2d(2.0 * Math.PI, myNeckHeight / 2);
let aDir = new oc.gp_Dir2d(2.0 * Math.PI, myNeckHeight / 4);
let aAx2d = new oc.gp_Ax2d(aPntc, aDir);
let aAx22d = new oc.gp_Ax22d(aPntc, aDir, true);
var aMajor = 2.0 * Math.PI;
var aMinor = myNeckHeight / 10;
let anEllipse1 = new oc.Geom2d_Ellipse(aAx22d, aMajor, aMinor);
let anEllipse2 = new oc.Geom2d_Ellipse(aAx22d, aMajor, aMinor / 4);
let aArc1 = new oc.Geom2d_TrimmedCurve(anEllipse1, 0, Math.PI, true);
let aArc2 = new oc.Geom2d_TrimmedCurve(anEllipse2, 0, Math.PI, true);
let anEllipsePnt1 = anEllipse1.Value(0);
let anEllipsePnt2 = anEllipse1.Value(Math.PI);
let aSegment = new oc.GCE2d_MakeSegment(anEllipsePnt1, anEllipsePnt2).Value();
//Threading : Build Edges and Wires
let aEdge1OnSurf1 = new oc.BRepBuilderAPI_MakeEdge(aArc1, aCyl1).Edge();
let aEdge2OnSurf1 = new oc.BRepBuilderAPI_MakeEdge(aSegment, aCyl1).Edge();
let aEdge1OnSurf2 = new oc.BRepBuilderAPI_MakeEdge(aArc2, aCyl2).Edge();
let aEdge2OnSurf2 = new oc.BRepBuilderAPI_MakeEdge(aSegment, aCyl2).Edge();
let threadingWire1 = new oc.BRepBuilderAPI_MakeWire(aEdge1OnSurf1, aEdge2OnSurf1).Wire();
let threadingWire2 = new oc.BRepBuilderAPI_MakeWire(aEdge1OnSurf2, aEdge2OnSurf2).Wire();
oc.BRepLib.BuildCurves3d(threadingWire1);
oc.BRepLib.BuildCurves3d(threadingWire2);
//Create Threading
let aTool = new oc.BRepOffsetAPI_ThruSections(true, true, 0.001);
aTool.AddWire(threadingWire1);
aTool.AddWire(threadingWire2);
aTool.CheckCompatibility(false);
let myThreading = aTool.Shape();
//Building the resulting compound
let aRes = new oc.TopoDS_Compound();
let aBuilder= new oc.BRep_Builder();
aBuilder.MakeCompound(aRes);
aBuilder.Add(aRes, myBody);
aBuilder.Add(aRes, myThreading);
return aRes;
}
function CompileModel() {
console.log("Model Compiling...");
// Create a Sphere
let spherePlane = new oc.gp_Ax2(new oc.gp_Pnt(0, 0, 50.), oc.gp.prototype.DZ());
let sphere = new oc.BRepPrimAPI_MakeSphere(spherePlane, 50.0).Shape();
// Create Cylinders to Subtract
let xCylinderPlane = new oc.gp_Ax2(new oc.gp_Pnt(-100, 0, 50), new oc.gp_Dir(1, 0, 0));
let yCylinderPlane = new oc.gp_Ax2(new oc.gp_Pnt(0, -100, 50), new oc.gp_Dir(0, 1, 0));
let zCylinderPlane = new oc.gp_Ax2(new oc.gp_Pnt(0, 0,-50), new oc.gp_Dir(0, 0, 1));
let xCylinder = new oc.BRepPrimAPI_MakeCylinder(xCylinderPlane, GUIState['Radius'], 200.0).Shape();
let yCylinder = new oc.BRepPrimAPI_MakeCylinder(yCylinderPlane, GUIState['Radius'], 200.0).Shape();
let zCylinder = new oc.BRepPrimAPI_MakeCylinder(zCylinderPlane, GUIState['Radius'], 200.0).Shape();
// Cut the Cylinders from the Sphere
sphere = new oc.BRepAlgoAPI_Cut(sphere, xCylinder).Shape();
sphere = new oc.BRepAlgoAPI_Cut(sphere, yCylinder).Shape();
sphere = new oc.BRepAlgoAPI_Cut(sphere, zCylinder).Shape();
// Convert to a mesh
console.log("Compilation Complete! Converting to Mesh...");
//cascadeViewport.updateShape(sphere, GUIState["Res"]);
//cascadeViewport.updateShape(externalShapes['Pipe cut profile test Rhino step AP203.stp'], GUIState["Res"]);
//Make bottle
var Width=30.0;
var Height=30.0;
var Thicknes=15.0;
let bottle = MakeBottle(Width, Height, Thicknes);
cascadeViewport.updateShape(bottle, GUIState["Res"]);
console.log("Generation Complete!");
}
// Define GUI State Variables here
Object.assign(GUIState, {
"Res" : 0.1, "ResRange" : [0.01, 1.00],
"Radius" : 30.0, "RadiusRange" : [27.0, 35.0] });
// GUI uses https://github.com/automat/controlkit.js
gui.addPanel({label: 'Cascade Control Panel'})
.addButton ('Generate Model' , () => { CompileModel(); } )
.addSlider (GUIState, 'Res', 'ResRange', { onFinish: () => { CompileModel(); }} )
.addSlider (GUIState, 'Radius', 'RadiusRange', { onFinish: () => { CompileModel(); }} );
from opencascade.js.
@guidovanhilst Perhaps better for another issue? (I feel bad about overloading this one so much already...)
MakeBottle (or a version of it) does appear to work, however; did you try the version from the example repo?
https://github.com/donalffons/opencascade.js-examples/blob/master/src/main.js#L46-L182
One of my goals with CascadeStudio is to expose better error handling inside the text editor... hopefully that extends to detecting type mismatches...
from opencascade.js.
Related Issues (20)
- Nuxt3 template
- Build emcc crashes HOT 4
- How to iterate over NCollection_List?
- MultiThreaded build on the browser gives errors related to node environment HOT 2
- CI costs too much time when building ocjs HOT 5
- Is there a better way to add cpp code? HOT 2
- How to import brep file with opencascade.js? HOT 1
- null function or function signature mismatch when building shell from solid HOT 2
- How to access data from .write() HOT 2
- Custom Build: XCAFDoc_DocumentTool.ShapeTool is not a function
- Is It possible to export a image to SVG?
- can i modify or replace a shape for an assembly ? (Adding new shape replacing the old opencascade shape)
- How to config opencascade.js in next.js? HOT 1
- How to build only a few specific modules of occ
- Cannot bind the library with Vite HOT 1
- Noob question : about .step export
- Update opencascade to 7.8.0 HOT 1
- Few errors during custom build
- Project Maintenance Status? HOT 1
- Custom build no-exceptions.yml failed. HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from opencascade.js.