WolframResearch / OpenCascadeLink

Open source package for OpenCascadeLink, which is bundled with Wolfram Language products as of version 12.1
Other
31 stars 8 forks source link

Proper documentation needed #1

Closed ralphrmartin closed 3 years ago

ralphrmartin commented 3 years ago

While OpenCascadeLink is potentially a very useful tool, the current documentation is just a bunch of examples, and does not actually specify the arguments, options of each function. For example, we are shown the call bmesh1 = OpenCascadeShapeSurfaceMeshToBoundaryMesh[shape1] but for serious real world use, we need to be able to specify accuracy / tolerance of the conversion process. How is that controlled? (I am assuming that it can be controlled, which is of course essential).

A proper specification of each function is needed.

ruebenko commented 3 years ago

I hear you. Please have a look in the section: SurfaceMesh or in the help system OpenCascadeLink#2068564608. The standard programmatic method to explore options is to make use of the Options[] function. All information is in the tutorial. Correct, it's not in a ref page style. That would requite some work. I am currently not convinced is worth the effort, however. If you want to contribute something you are most welcome to do so.

ralphrmartin commented 3 years ago

Either this is a supported part of Wolfram products, or it is not. If it is, it needs documenting properly, and to the same standard as the rest. If it is not, it should not be advertised as part of the product. This is a commercial product, not "take it as you find it freeware".

Your comments do not help either:

In[1]:= Options[OpenCascadeShapeSurfaceMeshToBoundaryMesh]                                                                          
Out[1]= {}
ruebenko commented 3 years ago

OpenCascadeLink is not a comerical product, it's an open source link that links to an open source software. OpenCascadeLink does not provide system context symbols and as such does not provide ref pages for those. OpenCascadeLink is a low level programming interface to OpenCascade. The documentation the link provides is sufficient to do so. It contains information how how to build and load the link. For example it also explains that you need to use Needs to load the package. This works with Mathamtica versions 12.1 and 12.2

Needs["OpenCascadeLink`"]
Options[OpenCascadeShapeSurfaceMeshToBoundaryMesh]

There are various packages and objects in contexts that ship with Mathematica, some have no documentation what so ever and others have extensive documentation. OpenCascadeLink has good documentation (as I have been told by customers) the only thing it does not have is ref pages and I think this is not a major issue as opposed to having no documentation at all.

All options currently available are documented inn the tutorial.

Again, I am not opposed to have ref pages but this is nothing that is going to happen right away. Please have a look at the existing documentation, it's just not in the format you would like to see but the information is there.

If you are looking for something that has ref pages, perhaps you want to have a look at the Boolean operations in Mathematica?

ralphrmartin commented 3 years ago

If you want to see why proper reference pages are needed, consider this example:

Needs["OpenCascadeLink"] Needs["NDSolveFEM`"] shape = OpenCascadeShape[CapsuleShape[{{0, -2, 0}, {0, 0, 1}}, 1]] r = ImplicitRegion[x^4 + y^4 +z^4 -1 = 0, {x, y, z}]; bmesh = ToBoundaryMesh[r, {{-2, 2}, {-2, 2}, {-2, 2}}]; shape2=OpenCascadeShape[bmesh] union = OpenCascadeShapeUnion[shape2, shape]; OpenCascadeShapeSurfaceMeshToBoundaryMesh[union]["Wireframe"] intersection = OpenCascadeShapeIntersection[shape2, shape]; OpenCascadeShapeSurfaceMeshToBoundaryMesh[intersection]["Wireframe"] difference = OpenCascadeShapeDifference[shape2, shape]; OpenCascadeShapeSurfaceMeshToBoundaryMesh[difference]["Wireframe"]

With this code: OpenCascadeShapeUnon[shape2, shape] actually gives shape2 - shape1 OpenCascadeShapeIntersetcion[shape2, shape] actually gives shape1 - shape2 OpenCascadeShapeDifference[shape2, shape] actually gives their union

Where does the fault lie? I have followed the examples in the documentation. Is it a bug? I cannot believe something this fundamental is wrong in the code. So,it must be something I am missing. But I do not know what it is, as it is not documented.

ralphrmartin commented 3 years ago

The answer is that the two surfaces have inconsistent normals (one shape has inward normals, one has outward normals). Lacking control over accuracy and normal directions (no options to control them), what could potentially be a useful tool is actually little more than an interesting proof-of-concept.

ruebenko commented 3 years ago

That is a bug in OpenCacascdeShape[Polygon[]] that I need to fix. You can verify that the boolean functions to behave as documented when you use shape2 = OpenCascadeShape[Ball[]].

As a workaround for the issue at hand you can use


mp = MeshPrimitives[DiscretizeRegion[r], 2];
shape2 = OpenCascadeShapeSewing[
   OpenCascadeShape[Polygon[#]] & /@ (Reverse /@ mp[[All, 1]])];
ralphrmartin commented 3 years ago

Thanks for clarifying that there is a bug here.

ralphrmartin commented 3 years ago

Perhaps the workaround would be useful as a function in its own right, called FlipNormals{}.

ruebenko commented 3 years ago

The latest version has the orientation issue of OpenCascadeShape[ElementMesh[...]] fixed. If you want the update you have two choices:

  1. Find the OpenCascadeLink.m file on your computer, open it and replace the line faceCoords = NDSolveFEMGetElementCoordinates[coords, f]; with faceCoords = Reverse /@ NDSolveFEMGetElementCoordinates[coords, f];
  2. Build the latest version of the link yourself. Instructions are in the notebook BuildOpenCascadeLink.nb

You can also wait for the next release.

I am going to close this issue as the bugfix fixes the main issue brought up.

ralphrmartin commented 3 years ago

While the fix suggested does now give correct behaviour for the example above, it breaks a different example.

If in my example earlier I replace r = ImplicitRegion[x^4 + y^4 +z^4 -1 = 0, {x, y, z}]; by r = ImplicitRegion[x^4 + y^4 +z^4 -1 < 0, {x, y, z}]; I would expect to get the same results in each case, the latter being the region inside the surface.

Previously, the version with = was broken, but the version with < worked OK. Now, the version with = works OK, but the version with < is broken (showing the same wrong behaviour that = showed before).

It seems that a slightly more subtle fix is needed. Thanks.

ruebenko commented 3 years ago

OK, this is serious and I am not sure what the problem is. Very likely this is an issue not in the link per se but in the Wolfram Language. I am going to close this issue as it has become quite unfocused. However, I have opened a new issue #5 that captures the bug and a workaround.