SubD Vs T-splines surface conversion

I regularly have to convert (very) dense mesh into nurbs (from 50 000 to 500 000 polys).
It’s a slow process using T-spline but the results are always reliably good.
I tested with Rhino 7, I was surprised by the speed of conversion from flat to SubD smooth mode compared to T-Splines it is maybe 20 time faster But the conversion to surface is slow and invariably crash Rhino, I don’t run out of ram, it just crashes.


I have filed an issue (RH-62025) that I believe is the same as what you’re reporting. Can you please share a 3dm file that is failing with ToNURBS? Use Rhino - Upload to Support and reference this forum post please and I’ll check the file and add it to the bug report.

A workaround in the meantime is to use QuadRemesh with no more than 30,000 faces and then ToSubD > ToNURBS. I found this face count or less avoided the crash if you can handle the reduction without too much detail loss.

1 Like

T-Splines had a 50,000 poly ceiling. If you got a 500k poly model to convert I’d be excited to see it.

Here an example file
In it you’ll find:

  • A 480 000 poly mesh.

  • A surface that was converted form that mesh via T-Splines in V5
    Here a detail of it:

  • A surface created in V7 converting the mesh to SubD then ToNurbs, the attempt created bad surfaces:

  • And I extracted a small poly sample around the detail and re-ran the mesh to SubD → ToNurbs and it worked:

    It is too bad that the conversion from SubD to nurbs in V7 doesn’t have controls of how detailed the end surface is desired, in T-Splines Options, some control is available in the Smooth Objects Speed.

Other example file
This SubD is from a 160 000 poly that takes for ever to convert to nurbs in V7, I have to crash Rhino to get out of it. T-splines does the entire conversion in about 20 minutes.

So you’re not converting your TSpline in Compatible mode but Fast or Fastest Mode? This would explain the differences. Set T-Splines to Compatible Mode and convert it to a nurbs object. In the ToNurbs options you can set the ExtraodinaryVertex option to G0 - G2 which is similar to T-Splines Compatible / Fast / Fastest modes

No I don’t.
These are all in compatible mode. I like having the option.
Anyway, I fail to see a difference in Rhino conversions:

Are you able to convert your 450k poly tspline in compatible mode?

It would also be good to view the Zebra analysis on your cubes.


Yes, As I said, the resulting surface is in the first file I shared.

I admit I don’t understand your train of thought.
First you flatly stated that T-Splines is limited to sub 50k object therefore not subtly presuming I came here to troll, Then went on a tangent about T-splines conversion option, and now infer that something is wrong with what, the resulting surfaces?

I have no beef with T-Splines, it works and is reliable, thanks.

Some is wrong with ToNurbs with extreme lengthy conversion time and unreliable results.

easy tiger, I’m just making sure that we’re comparing similar setups, I know you’re not trolling. If your tspline was being converted in a G1 mode (Fast) it will have a much easier time and make far fewer faces. I was trying to make good and sure that you’re doing that. As to the 50k poly limit that’s their words, not mine. I didn’t do a wide search for the Rhino version but it appears the limit still exists even in Fusion. So I’m shocked you were able to get 450k out of thing.

Anyway I’ve tagged @pierrec and hopefully he can shed some light on the face packing for you since that’s his magic.


@Trav @laurentheid I’ve had a look at the example files and read this thread, I do not think this is about face packing, or the G0/G1/G1x/G2 options in the SubD ToNURBS command.

In the first example file, this is what I can reproduce:

  • Convert the mesh to SubD, default options
  • Run ToNURBS on the resulting SubD, with unpacked faces and G0 output
  • The conversion takes a long time (10 minutes?)
  • The result has missing faces as shown in the images above.
  • _Check reports an invalid Brep:

    Rhino polysurface object is not valid.

    ON_Brep.m_L[181042] loop has trim vertex mismatch:
    m_T[loop.m_ti[1]=724169].m_vi[1] = 99678 != m_T[loop.m_ti[2]=724170].m_vi[0]=439476.

Similar observations in the second example file, with an even longer conversion time (30 minutes?).

I do not see any crashes in these example files, just very long computation times where Rhino is unresponsive and the command cannot always be escaped. Would it help to have a way to stop the conversion at that point, even after the modal dialog that warns that the input is too big?

Face packing and smoothing options (G1 and above) are post-processes that happen after the “face-by-face” conversion of the SubD is done, and an initial Brep built from these faces. This first conversion step is @dalelear 's work.

I’ve made a YT issue to track this and we will look into it in more detail. RH-62751 ToNURBS: SubD with 450k faces fails to convert to NURBS, missing faces around extraordinary vertices

I’ll add two observations that do not directly solve your issue but that I think are relevant here:

  • The modal dialog that warns about the large SubD to convert is not just for show and we really do not expect good results on an input of this size. Maybe the wording on that dialog needs to be adjusted to warn about long runtime and bad outputs, on top of out-of-memory and crashes?
  • Your SubDs look like they could be adjusted to have far fewer faces yet keep the same level of detail as the input mesh. QuadRemesh that @Trav mentionned is a powerful tool here. A couple of things that could help reduce the amount of faces or extraordinary vertices, with or without QuadRemesh:
    • Mesh edges aligned with the main features and curvatures of the object.
    • Varying meshing density – the flat areas do not need as many SubD faces as the folds to be faithful to the initial mesh.
    • Edges without exceptional vertices. If it wasn’t for the edges, your meshes would be quad-only, and they can be easily made quad-only with almost the same shape.

Apologies in advance if these last points are not applicable here because what you showed is just an example and there are other constraints that you did not mention.

RH-62025 and RH-62751 are fixed in Rhino 7 Service Release 20

1 Like