I wish to voxelize a complex shape composed of Tube[BSplineCurve[...]] objects, while maintaining the additional information of the (unvoxelated) surface normal directions at the surface voxels (for input into an already written C++ program).

I'll do the voxelization by repeating layer-by-layer rasterizations on 2D slices, similarly to here. In order to do this elegantly, and especially to extract the surface normals from VertexNormals in a GraphicsComplex, I'd like to turn the Tube[BSplineCurve[...]] objects into a GraphicsComplex composed of polygons. This is the kind of thing that Normal[ ] is advertised to do, but I presume that the BSplineCurve being the centre of the tube throws it off.

Note that my question is superficially similar to another that has been answered here, but it relates to a surface built using BSplineSurface, whereas I want a Tube around a BSplineCurve. I don't know how to build the analogous ParametricPlot3D from J.M.'s answer there.

Minimal working example:

pts = {{0, 0, 0}, {0, 1, 0}, {1, 1, 0}, {1, 1, 1}};

FullForm[Graphics3D[Tube[BSplineCurve[pts]]]] (*and *)
FullForm[Normal@Graphics3D[Tube[BSplineCurve[pts]]]] (*both return*)
Graphics3D[Tube[BSplineCurve[List[List[0, 0, 0], List[0, 1, 0], 
                                  List[1, 1, 0], List[1, 1, 1]]]]] 

rather than a GraphicsComplex composed of Polygons.


1 Answer 1


It's seems what you are asking for has already been done by J.M. :) in Extruding along a path:

Evaluate the definitions from the first code block up to TubePolygons.

Now, for the Tube you want a cross section which is a circle what can be done with TubePolygons[path, 20, "Scale" -> .2] or explicitly:

pointsPath = 10;
pointsCirc = 10;
radius = .1;
pts = {{0, 0, 0}, {0, 1, 0}, {1, 1, 0}, {1, 1, 1}};
path = First @ Cases[ParametricPlot3D[BSplineFunction[pts][u] // Evaluate, {u, 0, 1}, 
                                      MaxRecursion -> 1, PlotPoints -> pointsPath], 
                     Line[l_] :> l, ∞];

cs = First @ Cases[ParametricPlot[radius {Cos[u], Sin[u]}, {u, 0, 2 Pi}, 
                                  MaxRecursion -> 1, PlotPoints -> pointsCirc], 
                   Line[l_] :> l, ∞];

Graphics3D[{TubePolygons[path, cs]}, Boxed -> False]

enter image description here

Also closely related: Plotting a 2D shape along a 3D parametric function curve


Not the answer you're looking for? Browse other questions tagged or ask your own question.