Strange Behaviour Scripting with Curve Maker Extension [Solved]

I’m working with the 3D slicer extension CurveMaker that makes line/curve models based on fiducials. I wrote a simple convenience function (below) in python that sends all of the sets of MarkupsFiducial in the scene to CurveMaker and the function works but only if, since opening Slicer, I have first navigated to the CurveMaker module. If I haven’t, attempting to access ‘slicer.modules.CurveMakerWidget’ returns, "object has no attribute ‘CurveMakerWidget’ ".

How do I avoid this problem without requiring user interaction? Am I breaking best-practices by trying to access the logic through the widget? or is this simply a bug/shortcoming in the module?

def sendAllFiducialsToCurveMaker():
  N = slicer.mrmlScene.GetNumberOfNodesByClass('vtkMRMLMarkupsFiducialNode')
  ####
  #line below returns "AttributeError: 'module' object has no attribute 'CurveMakerWidget' " 
  #unless I have first navigated to the Curve Maker module
  cml = slicer.modules.CurveMakerWidget.logic 
  ####
  for i in xrange(N):
    cml.SourceNode = slicer.mrmlScene.GetNthNodeByClass(i,'vtkMRMLMarkupsFiducialNode')
    outputModel = slicer.vtkMRMLModelNode()
    slicer.mrmlScene.AddNode(outputModel)
    cml.DestinationNode = outputModel
    cml.generateCurveOnce()

The module widget is created “lazily” so as you saw it only exists after visiting the module once.

You can do this programmatically with something like this:

mainWindow = slicer.util.mainWindow()
mainWindow.moduleSelector().selectModule('CurveMaker')

HTH,
Steve

I would recommend to use “Markups to model” module in SlicerIGT extension.

It does everything that CurveMaker but much more (for example it can handle any number of models, not just one; it can also generate surfaces) and it is a full-featured module: saving/reloading state to the scene works well, initialization is done properly (no need to open the module GUI), it is faster (fully implemented in C++), etc.

1 Like

@pieper and @lassoan, both excellent solutions. Also re-assuring to know I hadn’t missed something obvious.

Thanks for your help!