Surface modeling. Part5

Time remains the most scarce resource but I feel obliged to share some new materials with you as you may expect continuation of the series. As usual, many thanks for your patience and interest !

Skinning and lofting
This is a technique to create a model (surface or shell, or solid body) using curve constraints which the surface passes through. Below is an example of a surface built using skinning:

Skinning and lofting are actually the same technique and Open CASCADE does not make a difference between them. ACIS kernel does make a little difference (in terms of types of the inputs parameters and way of constraints definition) but also stresses that these are very similar.

Here is how you would create a surface using skinning technique:
Handle(Geom_Surface) ACISAlgo::MakeSkinSurface (
const NCollection_List<Handle(Geom_Curve)>& theSections)
//populate section generator
GeomFill_SectionGenerator aSecGenerator;
for (NCollection_List<Handle(Geom_Curve)>::Iterator anIt (theSections); anIt.More();
anIt.Next()) {
const Handle(Geom_Curve)& aCurve = anIt.Value();
aSecGenerator.AddCurve (aCurve);
aSecGenerator.Perform (Precision::PConfusion());

Handle(GeomFill_Line) aLine = new GeomFill_Line (theSections.Size());

const Standard_Integer aMinDeg = 1, aMaxDeg = BSplCLib::MaxDegree(), aNbIt = 0;
Standard_Real aTol3d = 1e-4, aTol2d = Precision::Parametric (aTol3d);

GeomFill_AppSurf anAlgo (aMinDeg, aMaxDeg, aTol3d, aTol2d, aNbIt);
anAlgo.Perform (aLine, aSecGenerator);

Handle(Geom_Surface) aRes;
if (!anAlgo.IsDone()) {
return aRes;

aRes = new Geom_BSplineSurface(anAlgo.SurfPoles(), anAlgo.SurfWeights(),
anAlgo.SurfUKnots(), anAlgo.SurfVKnots(), anAlgo.SurfUMults(), anAlgo.SurfVMults(),
anAlgo.UDegree(), anAlgo.VDegree());


Curves must be bounded and consistently parameterized (so that parameter growth was in one direction). Final B-Spline will be parameterized [Umin, Umax; 0., 1.], where U parametrization is calculated depending on the curves parametrization. U parameter goes along the section curves, and V parameter goes across the curves.

When working at topological level you can use the following code:

Standard_Boolean anIsSolid = Standard_False;
Standard_Boolean anIsRuled = Standard_False;

BRepOffsetAPI_ThruSections aGenerator (anIsSolid,anIsRuled);

//add constraints
for (...) {
aGenerator.AddWire (TopoDS::Wire (aConstraint));

Standard_Boolean anIsCheck = ...;
aGenerator.CheckCompatibility (anIsCheck);


const TopoDS_Shape& aResult = Generator.Shape();

The topological algorithm may attempt to create a closed solid if the boundary constraints are planar.

Unlike ACIS, Open CASCADE only allows to specify curve constraints but does not give a way to specify tangential ones. So you will basically rely on underlying algorithms which try to smoothen the surface being built.

To be continued...


  1. Hi Roman,
    thank you very much for the nice article. Unfortunately I did not yet understood completely the difference between skinning and lofting. I expected that I need skinning when a surface is built with one single wire and I need the lofting technique when the surface is generated through a set of profiles. Personally I did not succeeded to apply your code for one single wire, but it seems to work very well with a set of profiles.


  2. Hi Chris,
    I am not sure if I understand your case of single wire. Do you mean to create a surface that has that wire as a boundary and lies "inside" that wire ? For instance if you have a circular wire, do you mean to have a planar face bounded by that circle ?

    If so, this is a totally different technique - ACIS calls it 'covering' if I remember correctly and OCC names it 'plating'. Skinning/lofting is when you have >=2 wires.

  3. Hi Roman,

    thank you for the explanation and the fast reply. Yes I mean to create a surface that has a wire which is the boundary, and the surface lies inside that wire. I already started to experiment with the GeomPlate_BuildPlateSurface class. Are there also other possible classes for covering or plating in Occ?

    By the way do you also plan to integrate a CATIA interface to your CAD Exchanger? I suppose this would make your exchanger very powerful.


  4. Hi Chris,
    Yes, GeomPlate_BuildPlateSurface is the one for a general case. For some particular cases (e.g. planar for a circular wire) you can use direct creation of plane.

    Regarding CATIA in CAD Exchanger, this seems like a FAQ. So I started a thread on the forum (http://cadexchanger.com/forum/viewtopic.php?f=3&t=191) to solicit feedback. I'd appreciate your comments there. Thanks!

  5. Hi Roman,
    I now managed to construct a surface spline using GeomPlate_BuildPlateSurface surrounded by a closed wire. I applied the class BRepFill_CurveConstraint to force the surface spline to touch the wire. However there still remains the problem to trim (to cut) the surface spline with the wire (the wire is not planar). Which is the easiest way to resolve this problem. Do you have an advice?
    Thank you in advance

  6. Hi Chris,
    You cannot (and need not) trim a surface itself by an arbitrary contour. Remember that a surface is a transformation of a 2D rectangle [Umin,Umax; Vmin, Vmax] into 3D space. Trimming is done at the topology level by creating a face from the surface and wire from the edges created from the boundary curves. IIRC, the Plate sample has a demo how to create face from boundary edges.

  7. Hi Roman,
    thank you for the fast reply!

  8. Hi Roman,
    thanks for sharing your knowledge! I just started using OCC to make a little program for turbomachinery blade design. I had problems to build up a surface using "BRepOffsetAPI_ThruSections" - I get an segmentation fault while all wires are compatible since being created with the same number of spline control points (in the OCC forum are several people reporting the same or similar problems). Anyway, how can I try your approach using ACIS - it is not part of OCC!?
    Thanks a lot,

  9. Hi Ulrich,
    Certainly, ACIS is an independent licensed modeling kernel. I was explaining how ACIS surfaces map to OCC in CAD Exchanger.
    Perhaps, you have encountered with a bug in OCC. Try to reproduce in DRAW as follows:

    > pload MODELING
    > help thrusections
    > restore wire1.brep w1
    > restore wiren.brep wn
    > thrusections result 0 0 w1 w2 ... wn
    If indeed, try to post on the forum to get it noticed by the OCC team.
    Luckily I have not meet any issues, perhaps due to ACIS model peculiarities: there is always 1 curve in each section.

    Hope this helps.

  10. Hi Roman,

    Thanks for all the helpful tips and discussions on your blog. I have trouble getting a reliable response from OCC when using BRepOffsetAPI_ThruSections or MakePipeShell in the sense that sometimes it creates "invalid" solids (incorrect volume and incorrect classification w.r.t. points). I build the solid using two wires (polygons) which have the same number of vertices. I find that depending on data and scale I can get non-closed solids or invalid solids. Do you have any recommendations on best-practice for building such solids and if any diagnostic + repair methods can be used to make them usable?


  11. Hi Harun,
    I don't remember all the details in those topo algorithms (and I don't use them in CAD Exchanger) but AFAIR, at least pipe used to produce a result depending on the input topology type. That is, to get a solid you need to sweep a face along the spine. If you sweep a wire/edge you will only get shell or face. Not sure if this applies to ThruSections where I only recall a requirement of same number of edges in sections (though not fully certain).
    You might want to experiment in DRAW using thrusections and *sweep* commands - see BRepTest_SweepCommands.cxx.

    Hope this helps in some way

  12. Hi,

    I am new to OpenCascade. I am using QT and C++. Need some info on how can I covert a set of points to BSpline and how to draw the spline in QT/OpenGL.

  13. Hi Roman,

    I have been working on developing a CAD model on OpenCASCADE. I tried to use the mfc sample TopologyBuilding with modifications for the data. I want to get data for points of the geometry from other .cpp files. So I implemented the other header and .cpp files with the sample and tried to create a point from the data.

    It compiled successsfully. But when I try to execute it through a button on the window, I get the error:
    "An unhandled Win32 exception occured in TopologyBuilding.exe [3292]"

    Following is the code I tried to implement in TopologyBuildingDoc.cpp:

    double p1 = myFuselagePt->referencePtx;
    double p2 = 0.5;

    BlueEdge = BRepBuilderAPI_MakeEdge(gp_Pnt(p1,-50,-20),gp_Pnt(-30,-60,-60));

    I declared the fuselage class (the class I want to take my data from) pointer object myFuselagePt in TopologyBuildingDoc.h

    Plz help me with this problem. Thanks.


  14. Hi Nitin,
    No real need to duplicate the questions from the forum - I get updates into the same mailbox ;-).
    The comments on the forum are just valid - you need to understand where you get the exception. Use asserts and/or debugger. You may likely end up understanding that you try to access some null pointer or alike.
    Good luck.

  15. Hi
    Sorry for that. I was not getting a reply so thought should put it up here too. :)
    Well I actually tried to get data of points from a text file and then use those values in a gp_Pnt function for the coordinates. I wrote the whole code in the same function this time.
    But still on running the .exe and clicking the button to run the geometry, the window crashes.
    I am not able to understand the problem. How should I get data of x.y.z coordinates from another class or file and use it in to create my geometry. I am really stuck.

  16. Hi Roman,
    I got the solution and found out what I was doing wrong. Thanks anyways.

  17. Hi Roman,
    I am working to create a CAD software for reading iges/step file. Is it possible to find the size of each surface. I mean getting the length and width of every surface if it was flattened to a rectangle... Thanks