Create nurbsurface with vvtk

Hello, I would like to know if it is possible to create nurbs surfaces with vtk? If possible, could you guide me with a simple example?

Thank you for your feedback.

VTK does not support nurbs surfaces.

1 Like

We have developed VTK classes for NURBS surface visualization and interactive editing for 3D Slicer. We released everything with a non-restrictive license, so you can copy-paste these everything into your project but if you are working in the medical domain probably you are better off using them in Slicer.

It supports both NURBS and Bezier surfaces, plane or tube topology, quad or triangle mesh output, visualization and interactive editing in 3D and slice views.

You can give it a try by installing 3D Slicer and then open the extensions manager in the application and install the SurfaceMarkup extension (takes just a few clicks). The new “Grid surface” markup type will show up in the “Markups” module.

We have modules for surface fitting, lofting, etc. that we’ll release as soon as corresponding papers are published.

3 Likes

Super @lassoan , please this code could work using python or java instance of c++?
Thank you for your feedback.

All the code is already Python-wrapped in 3D Slicer’s Python environment. There is no easy way to create community-maintained VTK modules (I don’t think VTK remote modules are not supported officially anymore), so if you want to use the code in other Python environments or in Java then you need to wrap it yourself.

If you want to use the interactive editing part, too, then there would be significant amount of additional code to take over from 3D Slicer (MRML data model and displayable manager classes), so in that case it is probably easier to use it within 3D Slicer (you can extend and customize Slicer in Python or C++ code in any way you want).

Hello @lassoan , Please can I have some example(minimal example) where you try to build vtkNURBSSurface with vtkRenderWindow. I would like to build my own vtkNURBSSurface but i don’t find any documentation about this topic.
Thank you for your feedback.

There are no standalone tests or simplified examples, but you can find the complete implementation of all the interactive 3D widgets and Qt GUI that demonstrate how to use the classes.

Hello @lassoan and thank youor for your feedback. Please I have one question I tried to adapt your code for build my NURBSSurface. First I define a constructor like that
public vtkNURBSSurfaceSource( int p, vtkPoints controlPoints, vtkDoubleArray knotVectors,
vtkPolyData outputPolyData )
{
this.p= p;
this.knotVectors= knotVectors;
this.controlPoints= controlPoints;
this.computeNurbsPolyData(controlPoints, outputPolyData);
}
In second here is my main method public static void main( String args )
{
int p= 3;
vtkPoints controlPoints= new vtkPoints();
controlPoints.InsertNextPoint(0.0, 0.0, 0.0);
controlPoints.InsertNextPoint(1.0, 0.0, 0.0);
controlPoints.InsertNextPoint(1.0, 1.0, 0.0);
controlPoints.InsertNextPoint(0.0, 1.0, 0.0);

  vtkDoubleArray knotVectors= new vtkDoubleArray();
  knotVectors.InsertNextValue(0.0);
  knotVectors.InsertNextValue(0.0);
  knotVectors.InsertNextValue(0.0);
  knotVectors.InsertNextValue(1.0);
  knotVectors.InsertNextValue(1.0);
  knotVectors.InsertNextValue(1.0);
  vtkPolyData outputPolyData= new vtkPolyData();

  vtkNURBSSurfaceSource nurbsSurfaceSource= new vtkNURBSSurfaceSource(p, controlPoints,knotVectors, outputPolyData);
  System.out.println(outputPolyData);
  vtkPolyDataMapper mapper= new vtkPolyDataMapper();
  mapper.SetInputData(outputPolyData);

  vtkActor actor= new vtkActor();
  actor.SetMapper(mapper);

  vtkRenderer renderer= new vtkRenderer();
  vtkRenderWindow renderWindow= new vtkRenderWindow();
  renderWindow.AddRenderer(renderer);
  vtkRenderWindowInteractor renderWindowInteractor= new vtkRenderWindowInteractor();
  renderWindowInteractor.SetRenderWindow(renderWindow);
  renderer.AddActor(actor);
  renderer.SetBackground(0, 1, 1);
  renderWindow.SetSize(800, 600);
  renderWindow.Render();
  renderWindowInteractor.Start();

}
after when I launced I got an message error; I checked and realised that there was an error at
following code public void getInterpolatingGridResolution( int resolutionUV )
{
int interpolatingOverlap= new int[2];
getInterpolatingOverlap(interpolatingOverlap);

  resolutionUV[0]= this.InputResolution[0] + 2 * interpolatingOverlap[0];
  resolutionUV[1]= this.InputResolution[1] + 2 * interpolatingOverlap[1];

}

public void getInterpolatingOverlap( int overlapUV )
{
if ( this.wrapAround == vtkMRMLMarkupsGridSurfaceNode.AlongU ) {
overlapUV[0]= this.interpolationDegrees[0] + 1;
//overlapUV[1]= 0;
}
else if ( this.wrapAround == vtkMRMLMarkupsGridSurfaceNode.AlongV ) {
overlapUV[0]= 0;
overlapUV[1]= this.interpolationDegrees[1] + 1;
}
else { // Disabled
overlapUV[0]= 0;
overlapUV[1]= 0;
if ( this.wrapAround != vtkMRMLMarkupsGridSurfaceNode.NoWrap ) { // Valid
// value
// for
// disabled
System.err.println(
"GetInterpolatingOverlap: Invalid WrapAround value " + this.wrapAround);
}
}
} The error is Index 1 out of bounds for length 1 when the getInterpolatingOverlap(interpolatingOverlap) méthode is called;

Thank you for your feedback.

@cpinter can you have a look at this if there is potentially an error in the code or it is just not used as expected?

ok

@lassoan I looked at your code but I don’t see any errors in this function.

but in your allocateMatrix( int m, int n ) method there is an error in your code sometimes you pass a parameter as input sometimes 2 or your method is not overloaded.

Signature of GetInterpolatingGridResolution method seems could be simplified to vtkNURBSSurfaceSource::GetInterpolatingGridResolution(int resolutionUV[2]). Please check if that solve

It looks correct. There is a default value for the second argument.

Overall, it seems that the issues are in the Java wrapping layer. If the API needs adjustments to be more Java-wrapping-friendly then feel free to send a pull request.

Ok @lassoan but I didn’t use a wraper, I have just written your code in java language. I have noticed that many functions are lost when I used the java wrapper so just tried to write in java code.
Thank uou for your feedback.

@lassoan I would like know how do you build a nurbssurface using your code.
Thank you for your feedback.

I’m afraid I cannot provide more guidance, but the implementation contains all the pieces and if you have any specific question then I may be able to answer. It may also help understanding how the code works if you build 3D Slicer and run the code in a debugger line by line.

1 Like

thank you for your feedback @lassoan and your help .