donalffons / opencascade.js

Port of the OpenCascade CAD library to JavaScript and WebAssembly via Emscripten.
https://ocjs.org/
GNU Lesser General Public License v2.1
617 stars 88 forks source link

Selection of rendered objects #5

Closed ancorasir closed 4 years ago

ancorasir commented 4 years ago

Thanks for the great work!

I’m able to run the example repo to read and render my step files. I’m wondering if it’s possible to render each part in the step file separately so that I can select a solid or a face with mouse click?

I did some research and found there are two possible ways to do it. One is using the AIS_InteractiveContext class in OCC. The other way is generate all the edges and faces in three.js and do the selection in three.js. The shortcoming of the latter is I can not do operations such as measurement in three.js.

Do you have any suggestions on the choice? Would it be possible to expose the AIS_InteractiveContext class through emScripten. Thanks. @donalffons

donalffons commented 4 years ago

I’m wondering if it’s possible to render each part in the step file separately

As far as I understand, STEP files can contain several solids, faces, edges etc. These entities can also be defined in a product structure (i.e. different parts and assemblies), depending on the version of the STEP file format.

OpenCascade has two classes for reading and writing STEP files: STEPControl_Reader (which is already implemented) and STEPCAFControl_Reader (which is not yet implemented). It seems like STEPCAFControl_Reader can read product structure trees and also color / material information of different parts, while STEPControl_Reader only reads the raw geometry.

However, its probably (hopefully) not too hard to add STEPCAFControl_Reader to the library, if you need the extra functionality.

I did some research and found there are two possible ways to do it. One is using the AIS_InteractiveContext class in OCC. The other way is generate all the edges and faces in three.js and do the selection in three.js. The shortcoming of the latter is I can not do operations such as measurement in three.js.

  1. I did have a look into AIS_InteractiveContext. In my understanding, if you're using this module, you also should do anything else which is 3D-viewport related through OpenCascade. As you probably know, Emscripten is capable of handling OpenGL via WebGL. However, I haven't seen it being used in such a way like you suggest (i.e. to create a JavaScript API to WASM, which runs a WebGL context). So, I'm not sure if its possible or feasible to do this. If you're planning to do some experiments in that area, I would definitely be interested in hearing your experience.

  2. As you said, the alternative is to use OpenCascade only for the algorithmic stuff and to use something like ThreeJS to display the resulting geometry. With this approach, you probably have to do more implementation work yourself than if you could use AIS_InteractiveContext for the same tasks. For example, for picking things in 3D space with a mouse cursor, you probably want to cast a ray from the camera origin through the mouse cursor and see if it hits any 3D geometry. OpenCascade has functions that will do the heavy lifting for you. From there, you could start implementing your measurement tool.

  3. There is another potential alternative. OpenCascade has a Emscripten / WebGL example in their code repository (although I haven't managed to make it work). I think the approach here is that certain parts of the application will be written in C++, i.e. the viewer, the picking algorithm, etc. They then interact with that C/C++ code from JavaScript via something like ccall. If I understand that correctly, that probably means that half of your code base will be in JavaScript and the other half in C/C++ (with obvious drawbacks)

So, if you're asking for my recommendation, I think

That's just my view and I might be wrong. Maybe @zalo has more views on the subject?! :-)

donalffons commented 4 years ago

...you might also want to look at the CascadeStudio (code) for examples on how to do picking / selecting.

zalo commented 4 years ago

I accomplished "picking" in CascadeStudio by modifying the openCascadeHelper.js to render each face and edge to a different Three.js Mesh or Line object, and then appending the "enumeration index" of the feature to the object itself.

Three.js has built-in support for raycasting against Meshes, and "near" raycasting against lines, so it's easy to get the hit object, and then the "index" of that feature within the original OpenCascade object.

So my modification of the example code is split between these files: https://github.com/zalo/CascadeStudio/blob/master/js/openCascadeHelper.js - Output list of faces + edges https://github.com/zalo/CascadeStudio/blob/master/js/CascadeView.js#L109-L172 - Turn them into three.js objects https://github.com/zalo/CascadeStudio/blob/master/js/CascadeView.js#L220-L241 - Raycast against them

You can see the results of that path here: https://github.com/donalffons/opencascade.js/pull/4#issuecomment-664564828 :-)

ancorasir commented 4 years ago

@zalo , Thanks for the info. I've read your codes and it's very well written and easy to follow. But in this way, the Brep data and the data in three.js are decoupled. Have you considered to combine the two data information so that the user can do interactive operations such as measuring distance using the brep data? I actually found another repository named JSketcher which seems to have accomplished this. But the code is really hard to digest without any documentation...

zalo commented 4 years ago

Rather than just appending the index of the edge or face to the three.js object like I’m doing, you can always include a reference to the full OpenCascade Edge/Face itself on the three.js object.

I didn’t do it in my app because I needed a short textual identifier that the user could select the edge with in code, but if you’re doing a full GUI, all the state is internal anyway, so you don’t need to decouple it like that.

JSketcher doesn’t use a CAD Kernel or export STEP files, so its results may be comparable to just measuring the arc length of the triangulated edges/faces.

ancorasir commented 4 years ago

@zalo Thank for the suggestions. I think will try to implement based on your work.

BTW, JSketcher also uses opencascade which is put under https://github.com/xibyte/jsketcher/tree/master/web/wasm/e0. I have tested their step reader and it's not always working...

With your work, everything works well so far. So thanks again for sharing your work and it really help me a lot. @zalo @donalffons

zalo commented 4 years ago

Oh wow; I guess I was mistaken! Weird that they don’t claim to export step in the readme; and cool to see alternative OpenCascade based web projects!