# How to display the label (or Name) of ControlPoint of vtkMRMLMarkupsCurveNode?

**URL:** <https://discourse.slicer.org/t/how-to-display-the-label-or-name-of-controlpoint-of-vtkmrmlmarkupscurvenode/25142>\
**Category:** Support\
**Tags:** python, markups, display\
**Created:** [September 7, 2022, 3:34pm UTC](https://discourse.slicer.org/t/how-to-display-the-label-or-name-of-controlpoint-of-vtkmrmlmarkupscurvenode/25142 "2022-09-07T15:34:13Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![sunshine](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@sunshine](https://discourse.slicer.org/u/sunshine)\
**Post date:** [September 7, 2022, 3:34pm UTC](https://discourse.slicer.org/t/how-to-display-the-label-or-name-of-controlpoint-of-vtkmrmlmarkupscurvenode/25142/1 "2022-09-07T15:34:13Z")

</div>

Hi everyone,

I have a question about the module Markups. In a PointList, I can see the label (or Name) of each ControlPoint, and I can choose to display or hide it.

How can I do the same thing for the MarkupsCurveNode? I was not able to display the label (or Name) of a ControlPoint of a MarkupsCurveNode.  
If it is possible to display, what is the function to toggle that using python code?

Thank you so much in advance!

---

<div class="post-metadata">

**Author:** ![Sunderlandkyl](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sunderlandkyl/32/79987_2.png) [@Sunderlandkyl](https://discourse.slicer.org/u/Sunderlandkyl)\
**Post date:** [September 7, 2022, 3:38pm UTC](https://discourse.slicer.org/t/how-to-display-the-label-or-name-of-controlpoint-of-vtkmrmlmarkupscurvenode/25142/2 "2022-09-07T15:38:53Z")

</div>

Yes, using [vtkMRMLMarkupsDisplayNode::SetPointLabelsVisibility](https://apidocs.slicer.org/master/classvtkMRMLMarkupsDisplayNode.html#a43df1ecfc13afd84ede7b39c2c8d2469):

```python
curveNode.GetDisplayNode().SetPointLabelsVisibility(True)

```

---

<div class="post-metadata">

**Author:** ![sunshine](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@sunshine](https://discourse.slicer.org/u/sunshine)\
**Post date:** [September 7, 2022, 3:44pm UTC](https://discourse.slicer.org/t/how-to-display-the-label-or-name-of-controlpoint-of-vtkmrmlmarkupscurvenode/25142/3 "2022-09-07T15:44:13Z")

</div>

Hi Kyle,

Thank you so much for your reply!

Would it be possible to trigger the label visibility of only one ControlPoint?

I am trying to create a CurveNode, and would like to add an observer that whenever my mouse hovers over a ControlPoint, its label displays. Could you please let me know the Event or Signal I should use and the function to trigger the one-ControlPoint Visibility?

Thank you again!

---

<div class="post-metadata">

**Author:** ![Sunderlandkyl](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sunderlandkyl/32/79987_2.png) [@Sunderlandkyl](https://discourse.slicer.org/u/Sunderlandkyl)\
**Post date:** [September 7, 2022, 4:17pm UTC](https://discourse.slicer.org/t/how-to-display-the-label-or-name-of-controlpoint-of-vtkmrmlmarkupscurvenode/25142/4 "2022-09-07T16:17:15Z")

</div>

No, it looks like it’s currently only applied to all control points.

A workaround could be to set the control point labels that you don’t want displayed to an empty string with `curveNode.SetNthControlPointLabel(i, "")`.

---

<div class="post-metadata">

**Author:** ![sunshine](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@sunshine](https://discourse.slicer.org/u/sunshine)\
**Post date:** [September 7, 2022, 4:24pm UTC](https://discourse.slicer.org/t/how-to-display-the-label-or-name-of-controlpoint-of-vtkmrmlmarkupscurvenode/25142/5 "2022-09-07T16:24:20Z")

</div>

Thank you so much, Kyle!

I have two more questions that may need your help:

1. Do we have an Event / Signal for ControlPoint Mouse Hover detection?
2. Can we initialize empty ControlPoints as place-holder in the CurveNode, so that the number of Control Points counts but the empty CurveNode has nothing to display? In this way, I can add/remove the ControlPoints without messing up the sequential significance of each ControPoint.

---

<div class="post-metadata">

**Author:** ![Sunderlandkyl](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sunderlandkyl/32/79987_2.png) [@Sunderlandkyl](https://discourse.slicer.org/u/Sunderlandkyl)\
**Post date:** [September 7, 2022, 4:50pm UTC](https://discourse.slicer.org/t/how-to-display-the-label-or-name-of-controlpoint-of-vtkmrmlmarkupscurvenode/25142/6 "2022-09-07T16:50:35Z")

</div>

1. You can attach a vtk.vtkCommand.ModifiedEvent observer to the display node, and can tell what control point is active using GetActiveComponentType to make sure it is a control point that is active (slicer.vtkMRMLMarkupsDisplayNode.ComponentControlPoint), and GetActiveComponentIndex to get the index of the active control point.

2. You can initialize the control points and use curveNode.UnsetNthControlPointPosition to mark them as unplaced.

---

<div class="post-metadata">

**Author:** ![sunshine](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@sunshine](https://discourse.slicer.org/u/sunshine)\
**Post date:** [September 7, 2022, 8:50pm UTC](https://discourse.slicer.org/t/how-to-display-the-label-or-name-of-controlpoint-of-vtkmrmlmarkupscurvenode/25142/7 "2022-09-07T20:50:13Z")

</div>

Hi Kyle,

Thank you so much for your help!

I just tested the function `curveNode.UnsetNthControlPointPosition()`, however, I am not sure this function can help my case.

I would like to create a CurveNode, and add ControlPoint directly to the Nth, because the sequential value N is important to me. Is it possible?

E.g., after calling

```auto
node_Curve = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLMarkupsCurveNode")

```

I would like to apply a function like this:

```auto
for idx_DataNode in range(10):
        node_Curve.UnsetNthControlPointPosition(idx_DataNode)

node_Curve.SetNthControlPoint(10, [2, 3, 4])

```

and I wish to get something like:

```auto
array = node_Curve.GetNthControlPoint(10)
print(array) : [2, 3, 4]

```

Could you please let me know how to achieve the above case?

---

<div class="post-metadata">

**Author:** ![Sunderlandkyl](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sunderlandkyl/32/79987_2.png) [@Sunderlandkyl](https://discourse.slicer.org/u/Sunderlandkyl)\
**Post date:** [September 8, 2022, 2:25pm UTC](https://discourse.slicer.org/t/how-to-display-the-label-or-name-of-controlpoint-of-vtkmrmlmarkupscurvenode/25142/8 "2022-09-08T14:25:04Z")

</div>

You’ll need to initialize the markups node with the desired number of control points. Something like this:  
[https://slicer.readthedocs.io/en/latest/developer\_guide/script\_repository.html#how-to-draw-a-curve-using-control-points-stored-in-a-numpy-array](https://slicer.readthedocs.io/en/latest/developer_guide/script_repository.html#how-to-draw-a-curve-using-control-points-stored-in-a-numpy-array)

If you know ahead of time how many control points you will need, you can create the markups node with the desired number of unset control points, save it as a json and load that template to populate the curve node.

---

<div class="post-metadata">

**Author:** ![sunshine](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@sunshine](https://discourse.slicer.org/u/sunshine)\
**Post date:** [September 8, 2022, 2:54pm UTC](https://discourse.slicer.org/t/how-to-display-the-label-or-name-of-controlpoint-of-vtkmrmlmarkupscurvenode/25142/9 "2022-09-08T14:54:29Z")

</div>

That looks nice! However, using this array will require all ControlPoints defined.

Is it possible that, I know the number of maximum ControlPoints, and fill in the CurveNode one by one while keeping the undefined ControlPoints with empty place-holders?

---

<div class="post-metadata">

**Author:** ![Sunderlandkyl](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sunderlandkyl/32/79987_2.png) [@Sunderlandkyl](https://discourse.slicer.org/u/Sunderlandkyl)\
**Post date:** [September 8, 2022, 4:13pm UTC](https://discourse.slicer.org/t/how-to-display-the-label-or-name-of-controlpoint-of-vtkmrmlmarkupscurvenode/25142/10 "2022-09-08T16:13:13Z")

</div>

If you initialize the curve using the array and unset the control points using UnsetNthControlPointPosition, then you can allow the user place the Nth control point at a later time.

Markups also have a “MaximumNumberOfControlPoints” variable that would limit the number of control points that can be placed, however it doesn’t seem to be exposed for curve nodes.

---

<div class="post-metadata">

**Author:** ![sunshine](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@sunshine](https://discourse.slicer.org/u/sunshine)\
**Post date:** [September 12, 2022, 7:03pm UTC](https://discourse.slicer.org/t/how-to-display-the-label-or-name-of-controlpoint-of-vtkmrmlmarkupscurvenode/25142/11 "2022-09-12T19:03:28Z")

</div>

Hi Kyle,

I really like the idea of combining array initialization `updateMarkupsControlPointsFromArray` and `UnsetNthControlPointPosition` together, however, it is unfortunately not user-friendly in practice.

![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/2/2/2206c0a2da962acc7b8d4e1acfe465090a4410bc.png)

As you can see from the screenshot, it cost about **6 seconds** for `updateMarkupsControlPointsFromArray` to initialize the CurveNode with a zero array size (640, 3), and **4.5 seconds** for `UnsetNthControlPointPosition`to do Unset.  
During the test, the Slicer interface freezes for **half a minute** to initialize 3 curves, which is too long.

---

<div class="post-metadata">

**Author:** ![Sunderlandkyl](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sunderlandkyl/32/79987_2.png) [@Sunderlandkyl](https://discourse.slicer.org/u/Sunderlandkyl)\
**Post date:** [September 12, 2022, 7:13pm UTC](https://discourse.slicer.org/t/how-to-display-the-label-or-name-of-controlpoint-of-vtkmrmlmarkupscurvenode/25142/12 "2022-09-12T19:13:40Z")

</div>

Interesting. updateMarkupsControlPointsFromArray is instantaneous on my computer (with a numpy array of size [640, 3]), although UnsetAllControlPoints takes several seconds.

You can save the templated landmarks to a json file after they are initialized and load that file into the curve node rather than using updateMarkupsControlPointsFromArray and UnsetNthControlPointPosition every time.

---

<div class="post-metadata">

**Author:** ![sunshine](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@sunshine](https://discourse.slicer.org/u/sunshine)\
**Post date:** [September 12, 2022, 7:17pm UTC](https://discourse.slicer.org/t/how-to-display-the-label-or-name-of-controlpoint-of-vtkmrmlmarkupscurvenode/25142/13 "2022-09-12T19:17:02Z")

</div>

That may not fit my case 😅

“640” is not a fixed number, but the length of an ultrasound sequence, which is variable as we load different sequences. 😜

---

<div class="post-metadata">

**Author:** ![Sunderlandkyl](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sunderlandkyl/32/79987_2.png) [@Sunderlandkyl](https://discourse.slicer.org/u/Sunderlandkyl)\
**Post date:** [September 12, 2022, 7:19pm UTC](https://discourse.slicer.org/t/how-to-display-the-label-or-name-of-controlpoint-of-vtkmrmlmarkupscurvenode/25142/14 "2022-09-12T19:19:54Z")

</div>

Ok, you can try wrapping your calls using:

```python
with slicer.util.NodeModify(curveNode):
  # Node updates here

```

This will prevent node modification events while you are updating the node.

---

<div class="post-metadata">

**Author:** ![sunshine](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@sunshine](https://discourse.slicer.org/u/sunshine)\
**Post date:** [September 12, 2022, 7:32pm UTC](https://discourse.slicer.org/t/how-to-display-the-label-or-name-of-controlpoint-of-vtkmrmlmarkupscurvenode/25142/15 "2022-09-12T19:32:25Z")

</div>

> [@Sunderlandkyl](#):
>
> `with slicer.util.NodeModify(curveNode):`

Brilliant! You saved my day!  
Before this, I have to write dichotomy algorithm to calculate the index, then insert/remove/replace ControlPoint one by one. Now everything is simplified!

Thank you so much!
