How to bulid a sweep geometry in Netgen.OCC

I want to create a sweep geometry with variable profiles like this.


However, the function “Pipe” in OCC can not use variable cross-sections. How to achieve this target?
Thanks so much.

Netgen.OCC wraps functionality from OpenCascade to Python.
Check if OpenCascade itself supports what you want to do.

If only the wrapping is missing it’s easy to add to Netgen.OCC.
If not, we are not able to help.

Joachim

Prof. Joachim Schöberl

Thank you so much.
I have searched in OpenCascade and found that the variable cross-section can be implemented, as
"GeomFill_Pipe::GeomFill_Pipe
(const Handle< Geom_Curve > & Path,
const TColGeom_SequenceOfCurve & NSections
)
"
but I am not sure how to add it in python. It would be very nice if NGsolve could add these functions.
Thanks

Zhaowei

Hello, I actually have exactly the same problem, I would like to sweep between circles of varying diameters. Did you find a solution @zzw90 ?
If your profiles do not contain rounded sections, I guess you could use an approach based on the way the threading works in the OCC Bottle-tutorial where you define wires for all “edges” of the resulting sweep geometry. For circular profiles I also struggle to find a way around it.

My workaround for the moment is to use ThruSections with different circles, but this is not exactly what I want as it does not result in circular cross-sections everywhere in the resulting geometry when your circles are not on a straight axis.

I also think that the reference to GeomFill_Pipe from @zzw90 is correct, according to Open CASCADE Technology: Modeling Algorithms this allows for

pipes with a section evolving between two given curves.

I think this is what we need. I am however new to OCCT so I can’t say for sure, but I looked at this for two days now.

You can newly use pyocc directly and convert a pyocc topods shape into a netgen one using From_PyOCC function in netgen.occ. if you then have a nice example what you want to do we can add it as functionality directly in netgen.occ as well :slight_smile:

@christopher Thanks for the hint! I just realised that you typed “pyocc”, I think this does not exist? I used pyOCCT now because I thought this was what you typed, but there is also PythonOCC (which is bigger). Did you mean PythonOCC or pyOCCT?
I could not use pyOCCT together with Netgen in the same conda environment due to some DLL conflicts, so if you meant PythonOCC this could explain this. So maybe I could have saved myself a lot of pain by asking earlier haha.

In any case I think I managed to use GeomFill_Pipe in pyOCCT to do what I want, but I cannot figure out how to make the resulting NURBS solid (transform to a TopoDS_Shape). I asked on the OCCT forum if and how this can be done. Without more help on this step I think I have to give up on this. In case you meant PythonOCC, I might try again there, the documentation on PythonOCC seemed a lot better than for pyOCCT.

I used this one:

here an example:


from OCC.Core.BRepOffsetAPI import BRepOffsetAPI_MakePipeShell
from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeEdge, BRepBuilderAPI_MakeWire
from OCC.Core.Geom import Geom_BezierCurve
from OCC.Core.Law import Law_Linear
from OCC.Core.TColgp import TColgp_Array1OfPnt
from OCC.Core.gp import gp_Circ, gp_Pnt, gp_ZOX
from OCC.Core.TopoDS import TopoDS_Shape

# from OCC.Display.SimpleGui import init_display

# display, start_display, add_menu, add_function_to_menu = init_display()


def thicken_spline(event=None):
    # Creation of points for the spine
    array = TColgp_Array1OfPnt(1, 5)
    array.SetValue(1, gp_Pnt(1, 4, 0))
    array.SetValue(2, gp_Pnt(2, 2, 0))
    array.SetValue(3, gp_Pnt(3, 3, 0))
    array.SetValue(4, gp_Pnt(4, 3, 0))
    array.SetValue(5, gp_Pnt(5, 5, 0))

    # Creation of a Bezier Curve as the spine
    bz_curv = Geom_BezierCurve(array)
    bz_curv_edge = BRepBuilderAPI_MakeEdge(bz_curv).Edge()
    bz_curv_wire = BRepBuilderAPI_MakeWire(bz_curv_edge).Wire()
    # display.DisplayShape(bz_curv_wire)

    # Creation of profile to sweep along the spine
    circle = gp_Circ(gp_ZOX(), 1)
    circle.SetLocation(array[0])
    circle_edge = BRepBuilderAPI_MakeEdge(circle).Edge()
    circle_wire = BRepBuilderAPI_MakeWire(circle_edge).Wire()

    # Creation of the law to dictate the evolution of the profile
    brep1 = BRepOffsetAPI_MakePipeShell(bz_curv_wire)
    law_f = Law_Linear()
    law_f.Set(0, 0.5, 1, 1)
    brep1.SetLaw(circle_wire, law_f, False, True)
    return brep1.Shape()


if __name__ == "__main__":
    from netgen.occ import From_PyOCC, OCCGeometry
    geo = OCCGeometry(From_PyOCC(TopoDS_Shape(thicken_spline())))
    from ngsolve import *
    Draw(geo)
    mesh = Mesh(geo.GenerateMesh())
    mesh.Curve(4)
    Draw(mesh)

@christopher Thanks for the clarification! I tried to follow your example, but I think I have to install Ngsolve from source in order to use From_PyOCC, right? At least I cannot import this when installing via pip. I sadly could not manage to build Ngsolve from source, I have all kinds of issues with the configuration

Hi, I’ve started some pip nightlies now, in an hour or so you should be able to update to a nightly version that includes this with

pip install --pre --upgrade ngsolve

best