# Fitting NURBS surface from point cloud

Hi All,

I am new to OpenCascade and I am looking at options to fit a BSpline/NURBS surface in OpenCascade from a set of points in 3D space.

The points that I have are a rectangular array in space. The number of points may vary from a few hundred to over 3000 points(10-20 streamlines of points).
i. When I try fitting a single surface through the points, I see the surface deforming at the edges and folding onto itself. I am using GeomAPI_PointsToBSplineSurface for fitting surface.

ii. When I create the surface as a set of patches instead of a single surface, the surface at the junction of two patches appears torn and there is no continuity. I am looking to get a C1 or C2 continuity between each patch surface.

iii. In between two streamlines of points I see large oscillation in surface if I create a surface covering many streamlines(of points).

Is there a way to

1. Getting the surface right in single patch without edge deformation.
2. Local modification of the surface at the patch junctions to get a C1 or C2 continuity between adjoining patches.
3. Reduce surface oscillations in the surface.

I looked into the documentation but could not find anything that might help. I would he highly obliged if anyone could help me with this problem or could point me into the right direction.

Dear Willis,

1)
unfortunately, GeomAPI_PointsToBSplineSurface sometimes produces oscillations.

The problem of oscillations has complex reasons (discussed in math books and papers). Of course, "irregular" (for example, sharp changing of distance between points or sharp changing of direction (Pi,Pi+1) in compare with (Pi-1,Pi) ) positions of sampling points increase probability of undulations, but "regular" position of points is not 100% guarantee of absence of undulations.

In my experience it helps to keep the number of points low (<100 in one parametric direction) and the distribution of points relatively homogeneous. It can also help to have a higher density of points at the boundaries of the surface.

The shape of the surface depends on points distribution, parametrization of points, degree, continuity and knot distribution.

Probably, this problem results from undulations produced by AppDef_BSplineCompute algorithm which is used internally by GeomAPI_PointsToBSplineSurface class. To suppress undulations in each particular case (in fact, there is no general solution for all cases) it is possible to try to tune the parameters of AppDef_BSplineCompute algorithm. Since they are not accessible from GeomAPI_PointsToBSplineSurface you might need to create a special class repeating the functionality of GeomAPI_PointsToBSplineSurface but providing access to lower level class.

Alternatively, probably the better aprroach would be to create curves from the points and then create a surface from curves.

In OCCT, such functionality is accessible via the API class GeomFill_AppSurf. The use of this class can be illustrated with help of a Draw command 'appsurf' that is implemented in the source file GeometryTest_SurfaceCommands.cxx. The syntax of the command is quite simple:

appsurf ...

On the level of shapes, the functionality of building shells connecting several contours / sections is accessible via the API class BRepOffsetAPI_ThruSections. The use of this class can be illustrated with help of a Draw command 'thrusections' that is implemented in the source file BRepTest_SweepCommands.cxx. The syntax of the command can be checked in Draw with help of the command:

help thrusections

Other options would be:
- sweeping through sections using BRepOffsetAPI_MakePipeShell
- plating using GeomPlate_BuildPlateSurface or BRepOffsetAPI_MakeFilling (but this algorithm is not very stable in complex cases)

3)
Probably, it won't solve the problem of oscillations but there are also methods to "simplify" a b-spline surface to make it more "nice" for the algorithms. For example, the method ShapeCustom::BSplineRestriction can modify b-spline geometry in the shape to "fit" it within the defined range of parameters such as continuity, degree etc. This functionality is accessible in Draw via command 'bsplres' so you may try to play with it... Of course, the conversion always require tolerance value, to tell how far the result can be from the original.

Regards