Tutorial: Important basics for editing line contours in CPLs, Polybool, and Polyshape
Prof. Dr. Tim Lueth, Tim Lueth, Professor at Technical University of Munich, MIMED - Department of Mechanical Engineering, Munich July 2025
Since 1984, Matlab has used different concepts (now classes) for storing and editing line contours. "CPL" since 1984, "polybool" since 1999, "delaunay", R2006a, "DelaunayTri", R2009a, "delaunayTriangulation", R2013a, "polyshape", R2017b, to name just a few. As a general rule for all line contours, the [x y ] coordinates of the points are written as lines and the order of the points also describes the order of the edges between the lines. This is the most important difference to so-called point clouds, in which there is no order of points defined by edges. These ordered lists of points correspond to points of polygons.
Closed contours, in which the starting point and the end point are identical, are called closed contours CPL (Closed Polygon Lines) Polygons, or line segments that are connected but not closed, are also called paths. If it is clear that a closed contour is represented by a path, the missing connection between the first and last points is implicitly added. As long as the lines do not cross, they can also be cross-sections of geometric bodies. If there are intersection points, these are called split points because the contour must be separated at these points. Even an inserted split point does not mean that the contours are separated. A good example is a horizontal 8 as a loop.
CPL: Contours and intersections of contours, lines, and self-intersecting contours (loops)
We have an example CPL as a loop
CPLsample(45); CPL=ans
10.0000 0
8.5561 2.7782
5.7298 3.5193
3.2157 2.6921
1.2656 1.2268
-0.4143 -0.4129
-2.1847 -2.0007
-4.3943 -3.2330
-7.1704 -3.4128
-9.6034 -1.5807
An important function is to find the intersection point of lines with contours. This is what "PLcrossCPLline" does. Often, you only need to know whether there is an intersection point. The routines then only find the first point.
PLcrossCPLline(CPLsample(45),[-5 -5],[5 4])
If you want to find all points, not just the information that there is an intersection, you need to check all line segments completely.
PLcrossCPLline(CPLsample(45),[-5 -5],[5 4],'',true)
3.7376 2.8638
0.2710 -0.2561
Now we have both coordinates of the intersection of the loop and the line. Let's go back to the contour of the loop itself and look at the intersection point.
We see that there is no point at the intersection of the two lines in the middle. However, we can calculate this intersection point. The contour remains unchanged, of course. Split points, i.e., intersection points of a contour, are calculated differently.
PLsplitpointsofCPL(CPLsample(45)), PL=ans;
10.0000 0
8.5561 2.7782
5.7298 3.5193
3.2157 2.6921
1.2656 1.2268
-0.4143 -0.4129
-2.1847 -2.0007
-4.3943 -3.2330
-7.1704 -3.4128
-9.6034 -1.5807
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
10 11
It is important to understand that these intersection points actually occur twice in the contour line. Once between points 5 and 6 and once between 15 and 16.
[a,b,c]=PLcrossCPLline(CPLsample(45),PL,PL, true, true)
CPL: The separation of intersecting contours into several contours
It would also be possible to insert the split points. Each intersection point would then have to be inserted multiple times in the point list, meaning it would appear at least twice. However, we do not want to go into this in more detail at this point, as the use of contours with intersection points is almost always unsuitable for creating 3D geometries.
Since SGLib primarily uses closed contours as the basis for describing or creating spatial bodies, i.e. as cross-sections or circumferential edges, intersection points should generally be avoided in SG-Lib. Extruding a loop would result in two separate bodies, both of which would have an edge at the intersection point. This is physically impossible because every edge, even if almost infinitely thin, must share at least one atom at the same spatial position. Intersection points cannot always be ruled out due to numerical calculation errors when calculating contours, especially when IGES/STEP files are imported from CAD programs and processed, as well as during Boolean operations However, intersection points are typically used to separate overlapping contours into two or more contours.
CPLsplitpoints(CPL); CPL2=ans
10.0000 0
8.5561 2.7782
5.7298 3.5193
3.2157 2.6921
1.2656 1.2268
0.0087 0.0000
1.2656 -1.2268
3.2157 -2.6921
5.7298 -3.5193
8.5561 -2.7782
In the image, we see what was previously a loop, now two drop-shaped contours with different colors (Attention: rotation direction orientation) and, in the coordinates, a line NaN NaN separating the two contours. The change in the rotational orientation of the contour due to the resolution of a loop is noteworthy, since when converting contours into surfaces, the direction of rotation is the direction of the outer surfaces upwards (right-hand rule) and if the direction of rotation is incorrect, holes can appear or disappear, as we will see in a moment.
We now use a circular outer contour with a loop as the inner contour. The outer contour is red in a counterclockwise direction (ccw, right hand), the inner contour is green in a clockwise direction (cw, left hand).CPL3=[PLcircle(11);nan nan;CPLsample(45)];
CPL3=[PLcircle(11);nan nan;CPLsample(45)];
SGfigure; CPLplotcwccw(CPL3); textCPL(CPL3);
After separation with Split Point, the two inner contours now have different orientations, as we saw already before. Not paying attention to this can lead to problems during extrusion along spatial paths.
It is simply recommended to pay attention to this, even though many functions of the SG-Lib perform a plausibility check, there are cases where you do not automatically want the direction of rotation to be adjusted. The simple extrusion function, SGofCPLz, for example, also generates geometries that can cause problems in 3D printing.
The "CPLrepair" function, on the other hand, separates the contours, allows the split point to be separated spatially (here 0.5) and corrects the direction of rotation.
CPLrepair([PLcircle(11);nan nan;CPLsample(45)],0.5); CPLR=ans;
For technical reasons, the start and end points of the contour (here, the position where the contour number is located) are shifted for this function.
In any case, the cross-section of a catheter with two working channels can now be extruded more effectively.
CPL: Overlap of 2D contours
In the example CPLsample(12), we see two catheter cross-sections that may have been generated automatically or created when slicing an STl model. In this example, both contours have the correct rotation directions for inside and outside. Perhaps the distances between the two cross sections on the left and right were calculated automatically. There are 4 embedded contours in the CPL.
CPLsample(12)
9.8079 -1.9509
9.8079 1.9509
8.3147 5.5557
5.5557 8.3147
1.9509 9.8079
-1.9509 9.8079
-5.5557 8.3147
-8.3147 5.5557
-9.8079 1.9509
-9.8079 -1.9509
If the distance between the two catheter cross-sections becomes too narrow, the contours overlap. The same happens if two catheters were designed in CAD/SGLib, arranged to overlap and then a slicer prepares this contour for the 3D printer. There are 4 embedded contours in the CPL.
CPLsample(11)
9.8079 -1.9509
9.8079 1.9509
8.3147 5.5557
5.5557 8.3147
1.9509 9.8079
-1.9509 9.8079
-5.5557 8.3147
-8.3147 5.5557
-9.8079 1.9509
-9.8079 -1.9509
The result of extrusion or printing on a 3D printer is probably not what we wanted or expected in the first step.
SGofCPLz(CPLsample(11),0.5);
In such a case, the CPLsplitpoints function suggests that it is complicated.
CPLsplitpoints(CPLsample(11));
The CPLrepair function even delivers quite different results depending on the distance between the split points you choose.
CPLrepair(CPLsample(11),0.0);
CPLrepair(CPLsample(11),0.1);
CPLrepair(CPLsample(11),0.2);
CPLrepair(CPLsample(11),0.5);
In such a case, where we know that these are intersections of bodies, we must organize the individual contours into regions and determine whether one contour lies completely within another contour. This results in contour levels. The outer contours intersect, but both are clearly outer contours. The inner contours do not intersect, but are clearly within another contour For a more detailed explanation of the parameters, please use the Matlab help function We must therefore first examine whether there are contours that lie completely within other contours This is done with "CPLsortinout"
CPLsortinout(CPLsample(11));
[cind,CC]=CPLsortinout(CPLsample(11)), c=connectofmat(CC)
NaN 1 NaN NaN
-1 NaN NaN -1
NaN NaN NaN 1
NaN -1 -1 NaN
CPL: Overlap of cross-section contours of 3D-bodies (solid geometries)
Once the contours have been sorted into inner and outer contours, the individual contours can be merged or subtracted level by level. This is done with "CPLunitesorted."
CPLunitesorted(CPLsample(11)); CPLu=ans;
We recognize that the contours have been processed, but the starting point of the contours or the order has changed. We also recognize that the direction of rotation has changed. We can correct this with "CPLisccwcorrected."
Now we can extrude the catheter.
Just another complex example
CPLunitesorted(CPLsample(44)); CPLu=ans;
stamp
stamp: Mac OSX 15.6.1 | R2024b Update 6 | SG-Lib 5.6 | Java 1.8.0_202-b08 | i7-Intelx64 6-Core 64GByte RAM | 13-Sep-2025 18:56:45