tpaviot / pythonocc-core

Python package for 3D geometry CAD/BIM/CAM
GNU Lesser General Public License v3.0
1.32k stars 372 forks source link

Curve network interpolation #409

Open rainman110 opened 7 years ago

rainman110 commented 7 years ago

Hi. I am relatively sure, that OCC does not implement an algorithm for the interpolation of a curve network:

Curve Network Interpolation

BRepFill_Plate comes closest to what I mean with curve network interpolation, but it still does not quite to the right thing.

Does anyone of you made a implementation of it?

I know, that @jf--- was experimenting with the algorithms a while ago: http://opencascade.blogspot.com/2010/03/surface-modeling-part6.html?showComment=1267655666187#c863539559924934004

From my point of view, there are two ways to implement it:

I'd like to discuss here, whether there already is a (open source) solution and if not, how we could implement such a thing.

I am also wondering, whether the following patent https://www.google.com/patents/US6639592 permits us in implementing such an algorithm.

Update: Before I forget this. I'd like to have this algorithm work on a geometrical level, not on the topology. In my opinion, the resulting surface should have the outer curves as its natural limits. Even further, the curve network could end up beeing iso-curves of the resulting surface.

jf--- commented 7 years ago

hi @rainman110 ,

So the example can be found here. Actually, it generates a surfaces that is curvature continuous ( or tangent, I forgot, either G1 or G2 ) to the adjacent surfaces, which provide the bounding domain. The algorithm used is BRepOffsetAPI_MakeFilling. Is this what you're looking for? For me, it provided a satisfactory overlap with what Rhino provides as a curve network.

See this dicussion

Curious if this helps...

rainman110 commented 7 years ago

@jf--- If I understand your code correctly, you create several patches, each of them is bounded by 4 curves.

The creation process is done by BRepOffsetAPI_MakeFilling creates a Coons-like patch, that just interpolates the exterior curves. Thus, you'll have several surfaces which you combine on the topological level.

@jf--- please correct me, if my assumption is wrong!

In our case at the DLR, this approch has proven to be not optimal, as you can get pressure oscillations around wings, which come from slightly oscillating surfaces. The solution would be, to create one SINGLE surface that interpolates all curves instead of creating several surfaces.

This will be a global interpolation scheme, that hopefully provides numerically better results.

One algorithm to do this, are the so called Gordon Surfaces, where you have a linear combination of two skin surfaces (one skinning along the u axis, one skinning along the v axis) minus the tensor product surface of the intersection points. It turns out, that such a gordon surface can be converted back into a bspline by degree elevation and knot insertion.

The difficulty of the gordon algorithm is though, that the input curves must be compatible in the sense, that they could be iso-curves of the resulting surface. This is generally not the case.

rainman110 commented 7 years ago

@jf--- Sorry, after I looked into your code again, I realized, that you even take a different approach.

You are plating (fitting) a surface to the curves. This might work fine for you, but for us this has two major problems:

splinecage

You can clearly see, that the iso-curves are nowhere matching the face's boundaries.

Update: When you look at the image in the first post (made by @jf--- with rhino), you can see, that the curves of the network are becoming iso-curves of the surface. This is, what I'd like to achieve.

tpaviot commented 7 years ago

@rainman110 @jf--- see https://www.opencascade.com/content/geomplatebuildplatesurface-limitations

BTW, you can try a pythonocc-core nightly build that come with oce-0.18.1 support as well as smesh

rainman110 commented 7 years ago

BTW. I have a student now working on this feature. I'll show some result when we have something to show.

jf--- commented 7 years ago

@tpaviot wrt the link; do you mean porting plateAlgo ( last post ) to pyocc?

rainman110 commented 7 years ago

@jf--- , @tpaviot Hi. Here is our first result:

gordon-occ

The red crosses are the control points of the surface. The new algorithm uses much less control points as the Plating algorithm used in the splinecage example. The numbers:

The code is still work in progress, but I think about sharing it to the public, when it's ready.

What do you think about this?

jf--- commented 7 years ago

I'm duly impressed! WoW! Those isoparms looks a lot better distributed / smoother... Very curious to see the code @rainman110

rainman110 commented 6 years ago

@jf--- @tpaviot It's been a while since I wrote the last time. We finally have something to show / test for you.

We finished our curve network interpolation algorithm. We already tested it for a couple geometries, but it has not been used widely yet.

The algorithm can be tested by installing the tigl library. It is yet based on OCE 0.17.2, so please test this in a clean environment:

conda create -n tigl_test python=3.5 tigl3

I have right now only conda packages for win and macOS with python=3.5!

We have not yet decided, whether we want to publish the algorithm as an own library, or as part of the tigl library. The code is pretty hefty and is roughly 3000 lines of code long. Hence, you need tigl for now.

The following example script demonstrates, how to call the interpolation function: https://github.com/DLR-SC/tigl/blob/cf405ed1ba6c904ce55ec5c2b729e048b556f55c/examples/python_internal/example_gordon_surface.py#L54

I would be happy to get some feedback.

And here are some resulting images: helicopter fuselage engine occ_surface belly-fairing wing sprialwing

rainman110 commented 6 years ago

By the way, If you want to look at the code, please look here: https://github.com/DLR-SC/tigl/blob/cpacs_3/src/geometry/CTiglInterpolateCurveNetwork.cpp https://github.com/DLR-SC/tigl/blob/cpacs_3/src/geometry/CTiglGordonSurfaceBuilder.cpp https://github.com/DLR-SC/tigl/blob/cpacs_3/src/geometry/CTiglBSplineAlgorithms.cpp https://github.com/DLR-SC/tigl/blob/cpacs_3/src/geometry/CTiglBSplineApproxInterp.cpp https://github.com/DLR-SC/tigl/blob/cpacs_3/src/guide_curves/CTiglCurveNetworkSorter.cpp

mnesarco commented 2 years ago

Hi @rainman110 your demo images looks really nice. But the links to the code are broken. Have you published something anywhere else?

mnesarco commented 2 years ago

Don't mind. Updated links:

https://github.com/DLR-SC/tigl/blob/master/src/geometry/CTiglInterpolateCurveNetwork.cpp https://github.com/DLR-SC/tigl/blob/master/src/geometry/CTiglGordonSurfaceBuilder.cpp https://github.com/DLR-SC/tigl/blob/master/src/geometry/CTiglBSplineAlgorithms.cpp https://github.com/DLR-SC/tigl/blob/master/src/geometry/CTiglBSplineApproxInterp.cpp https://github.com/DLR-SC/tigl/blob/master/src/guide_curves/CTiglCurveNetworkSorter.cpp

rainman110 commented 2 years ago

@mnesarco Thanks for updating the links. If you have any question regarding the algorithm, don't hesitate to ask. The algorithm is also presented in the paper: https://doi.org/10.1007/s11786-019-00401-y . You can read it for free here: https://rdcu.be/bIGUH

mnesarco commented 2 years ago

@rainman110 Thanks to you for doing the hard work. I am just a beneficiary. I am just experimenting and I have successfully extracted the algorithm without tixi and tigl dependencies.

I am working on a small project for parametric guitar design:

image

It will be published soon (Open source).

As you can see in the image, the neck surface is non continuous right now, but I am sure I can solve it with your algorithm. All credits to original authors will be kept of course.

rainman110 commented 2 years ago

I am working on a small project for parametric guitar design:

image

This looks awesome! I hope, that the algorithm is able to model this. Great work!

tpaviot commented 2 years ago

That would be great to have the algorithm in python :smiley:

rainman110 commented 2 years ago

It's available via tigl3 and swig 😏 : https://github.com/DLR-SC/tigl-examples/blob/master/tigl/python/internal-api-3-geometry-modeling.ipynb

tpaviot commented 2 years ago

:+1:

mnesarco commented 2 years ago

The first part is working. I successfully ran the extracted algo without tigl and tixi dependencies. This is my first Gordon Surface:

image

o4fr commented 2 years ago

The first part is working. I successfully ran the extracted algo without tigl and tixi dependencies. This is my first Gordon Surface:

image

Nice work! Would you mind sharing the extracted algorithm? I've been looking for a python implementation of the algorithm without tigl and tixi, but I do not have the knowledge to do it myself as of yet.

mnesarco commented 2 years ago

Hello @o4fr I will publish my project that included the extracted algo, but it is a big project and I replaced some Tigl code with my internal classes but extracting it from Tigl code was not hard. These are the files you need:

CNamedShape.cpp
CNamedShape.h
CSharedPtr.h
CTiglApproxResult.h
CTiglBSplineAlgorithms.cpp
CTiglBSplineAlgorithms.h
CTiglBSplineApproxInterp.cpp
CTiglBSplineApproxInterp.h
CTiglCurveNetworkSorter.cpp
CTiglCurveNetworkSorter.h
CTiglCurvesToSurface.cpp
CTiglCurvesToSurface.h
CTiglError.cpp
CTiglError.h
CTiglGordonSurfaceBuilder.cpp
CTiglGordonSurfaceBuilder.h
CTiglInterpolateCurveNetwork.cpp
CTiglInterpolateCurveNetwork.h
CTiglIntersectBSplines.cpp
CTiglIntersectBSplines.h
CTiglIntersectionPoint.h
CTiglPoint.cpp
CTiglPoint.h
CTiglPointsToBSplineInterpolation.cpp
CTiglPointsToBSplineInterpolation.h
CTiglTransformation.cpp
CTiglTransformation.h
ListPNamedShape.h
PNamedShape.h
tigl.h
tiglcommonfunctions.cpp
tiglcommonfunctions.h
tigl_internal.h
tiglmathfunctions.cpp
tiglmathfunctions.h
tiglMatrix.cpp
tiglMatrix.h

I removed all unused functions from tiglcommonfunctions.h/cpp and redefined LOG and DLOG macros.

Then you can use it. It is a single function call thing:

    auto surface = tigl::curveNetworkToSurface(profiles.curves, guides.curves, interpolationTolerance);
    BRepBuilderAPI_MakeFace mkFace(surface, degeneratedEdgesTolerance);
    auto face = mkFace.Face();