# Clipping of models is too slow

**URL:** <https://discourse.slicer.org/t/clipping-of-models-is-too-slow/8788>\
**Category:** Support\
**Created:** [October 15, 2019, 10:35pm UTC](https://discourse.slicer.org/t/clipping-of-models-is-too-slow/8788 "2019-10-15T22:35:26Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Prashant\_Pandey](https://avatars.discourse-cdn.com/v4/letter/p/c0e974/32.png) [@Prashant\_Pandey](https://discourse.slicer.org/u/Prashant_Pandey)\
**Post date:** [October 15, 2019, 6:12pm UTC](https://discourse.slicer.org/t/clipping-of-models-is-too-slow/8788/1 "2019-10-15T18:12:59Z")

</div>

I’m also trying to clip models as a tracked tool is being moved around, by combining the models module and the volume reslice driver. However it seems that models cannot be clipped in real-time - I manage to get only 1 frame/second. I tried decimating the model, but I have to decimate by 99% to get anywhere near real-time (20/30 FPS) model clipping. Is there a solution to this?

---

<div class="post-metadata">

**Author:** ![Prashant\_Pandey](https://avatars.discourse-cdn.com/v4/letter/p/c0e974/32.png) [@Prashant\_Pandey](https://discourse.slicer.org/u/Prashant_Pandey)\
**Post date:** [October 15, 2019, 10:35pm UTC](https://discourse.slicer.org/t/clipping-of-models-is-too-slow/8788/2 "2019-10-15T22:35:26Z")

</div>

Another issue I’ve come across with clipping modules from the models module is that if you have two different 3D views (‘View1’ and ‘View2’) each showing a different model, and you set both models to be clipped, the clipping parameters will be shared between the two models and views. I think this is a bug, as clipping parameters should be separated by models and views.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [October 15, 2019, 10:53pm UTC](https://discourse.slicer.org/t/clipping-of-models-is-too-slow/8788/3 "2019-10-15T22:53:15Z")

</div>

We have implemented many navigation systems over the years and I don’t remember model clipping ever came up as a requirement. Could you write a bit more about your use case? How do you envision to utilize model clipping?

> [@Prashant\_Pandey](#):
>
> if you have two different 3D views (‘View1’ and ‘View2’) each showing a different model, and you set both models to be clipped, the clipping parameters will be shared between the two models and views

This is the intended behavior.

You can always add an observer to a slice node and use it to clip your polydata with a filter. You can then choose what to cut and what to show in each view. If you don’t need straight cut then maybe you can find a filter that can clip faster.

How many points and cells are in your data set before and after decimation?

---

<div class="post-metadata">

**Author:** ![Prashant\_Pandey](https://avatars.discourse-cdn.com/v4/letter/p/c0e974/32.png) [@Prashant\_Pandey](https://discourse.slicer.org/u/Prashant_Pandey)\
**Post date:** [October 16, 2019, 12:04am UTC](https://discourse.slicer.org/t/clipping-of-models-is-too-slow/8788/4 "2019-10-16T00:04:38Z")

</div>

> [@lassoan](#):
>
> We have implemented many navigation systems over the years and I don’t remember model clipping ever came up as a requirement. Could you write a bit more about your use case? How do you envision to utilize model clipping?

We want to use model clipping to visualize in 3D how the tool lines up with the preoperatively planned path for orthopaedic surgery. Here are two images showing the preop model with pre-op screw plans, and the same model clipped by two orthogonal planes defined by the tool tip.

 ![clippingdemo](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/6/6/66c6a1ad97633710f1018fe3b049d3157821fab1.jpeg)  
 ![clippingdemo2](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/b/a/ba1edc996b0d1157cc4c04203bb51fa93891d1f6.jpeg)

This is to aid the volume reslice views which only show 2D visualizations of the tool relative to the patient.

> [@lassoan](#):
>
> This is the intended behavior.

Could you explain why this is the intended behaviour? I would expect different models and views to have independent properties, especially as other model and view properties are not shared (lighting, surface/point rendering, etc.)

> [@lassoan](#):
>
> You can always add an observer to a slice node and use it to clip your polydata with a filter. You can then choose what to cut and what to show in each view. If you don’t need straight cut then maybe you can find a filter that can clip faster.

I’m not sure what you mean by cutting/clipping with a filter? Do you have any examples? We would like cuts defined by the tracked tool’s planes.

> [@lassoan](#):
>
> How many points and cells are in your data set before and after decimation?

Before decimation: ~1 million points and 2 million cells.  
After decimation: 55,000 points and 20,000 cells but the anatomic detail is not sufficient

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [October 16, 2019, 5:03am UTC](https://discourse.slicer.org/t/clipping-of-models-is-too-slow/8788/5 "2019-10-16T05:03:28Z")

</div>

It seems that your use case is not a good match for what model clipping offers. However, Slicer is so flexible that there are always many alternative options. You can only clip a 1M point model efficiently at the end of the rendering pipeline, in the mapper. So, instead of using model clipping, you can go one level lower: get the polydata mapper from the displayable manager and then add a clipping plane manually:

```python

modelNode = getNode('SpinePhantom2Model')
threeDWidgetIndex = 0

# Get model displayable manager
threeDViewWidget = slicer.app.layoutManager().threeDWidget(threeDWidgetIndex)
managers = vtk.vtkCollection()
threeDViewWidget.getDisplayableManagers(managers)
for i in range(managers.GetNumberOfItems()):
  obj = managers.GetItemAsObject(i)
  if obj.IsA('vtkMRMLModelDisplayableManager'):
    modelDisplayableManager = obj
    break

# Get polydata mapper for the model node
modelMapper = modelDisplayableManager.GetActorByID(modelNode.GetDisplayNode().GetID()).GetMapper()

# Add a clipping plane
clippingPlane = vtk.vtkPlane()
modelMapper.AddClippingPlane(clippingPlane)

# Set clipping plane position
clippingPlane.SetOrigin(30,30,30)
clippingPlane.SetNormal(0,0,1)
threeDViewWidget.threeDView().scheduleRender()

# Move clipping plane to a different position
clippingPlane.SetOrigin(30,30,80)
threeDViewWidget.threeDView().scheduleRender()

```

---

<div class="post-metadata">

**Author:** ![Prashant\_Pandey](https://avatars.discourse-cdn.com/v4/letter/p/c0e974/32.png) [@Prashant\_Pandey](https://discourse.slicer.org/u/Prashant_Pandey)\
**Post date:** [October 17, 2019, 4:39am UTC](https://discourse.slicer.org/t/clipping-of-models-is-too-slow/8788/6 "2019-10-17T04:39:21Z")

</div>

> [@lassoan](#):
>
> `# Set clipping plane position clippingPlane.SetOrigin(30,30,30) clippingPlane.SetNormal(0,0,1)`

I tried the above snippet and it can clip the example model in a static way, but how would I change the quoted lines above so that clipping is done dynamically based on my red and yellow slice planes (which are being computed using the volume reslice driver)?

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [October 17, 2019, 4:43am UTC](https://discourse.slicer.org/t/clipping-of-models-is-too-slow/8788/7 "2019-10-17T04:43:22Z")

</div>

You can [add an observer to the tool’s transform node](https://www.slicer.org/wiki/Documentation/Nightly/ScriptRepository#Get_a_notification_if_a_transform_is_modified) and update the clipping plane position and orientation whenever the transform is modified.

---

<div class="post-metadata">

**Author:** ![Prashant\_Pandey](https://avatars.discourse-cdn.com/v4/letter/p/c0e974/32.png) [@Prashant\_Pandey](https://discourse.slicer.org/u/Prashant_Pandey)\
**Post date:** [October 17, 2019, 5:56am UTC](https://discourse.slicer.org/t/clipping-of-models-is-too-slow/8788/8 "2019-10-17T05:56:07Z")

</div>

Thanks!  
I’m new to using observers. How do I pass more arguments to the AddObserver function - for example adapting your above snippet I want :

```
def onTransformNodeModified(transformNode, unusedArg2=None, unusedArg3=None):
	transformMatrix = vtk.vtkMatrix4x4()
	transformNode.GetMatrixTransformToWorld(transformMatrix)
	clippingPlane.SetTransform([transformMatrix.GetElement(0,0), transformMatrix.GetElement(0,1), transformMatrix.GetElement(0,2),transformMatrix.GetElement(0,3),
		transformMatrix.GetElement(1,0), transformMatrix.GetElement(1,1),transformMatrix.GetElement(1,2),transformMatrix.GetElement(1,3),
		transformMatrix.GetElement(2,0), transformMatrix.GetElement(2,1),transformMatrix.GetElement(2,2),transformMatrix.GetElement(2,3),
		transformMatrix.GetElement(3,0), transformMatrix.GetElement(3,1),transformMatrix.GetElement(3,2),transformMatrix.GetElement(3,3)])
	threeDViewWidget.threeDView().scheduleRender() 	

tNode = slicer.mrmlScene.GetNodeByID('vtkMRMLLinearTransformNode4')
tNode.AddObserver(slicer.vtkMRMLTransformNode.TransformModifiedEvent, onTransformNodeModified)

```

When I try this and change the transform, the model remains unclipped.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [October 17, 2019, 11:16am UTC](https://discourse.slicer.org/t/clipping-of-models-is-too-slow/8788/9 "2019-10-17T11:16:44Z")

</div>

I don’t think `SetTransform` is taken into account when using the plane to define a clipping plane in the mapper. Instead, set the origin (from the 4th column of the transform) and normal (3rd column) as I showed in my example above.

---

<div class="post-metadata">

**Author:** ![Prashant\_Pandey](https://avatars.discourse-cdn.com/v4/letter/p/c0e974/32.png) [@Prashant\_Pandey](https://discourse.slicer.org/u/Prashant_Pandey)\
**Post date:** [October 17, 2019, 8:15pm UTC](https://discourse.slicer.org/t/clipping-of-models-is-too-slow/8788/10 "2019-10-17T20:15:51Z")

</div>

Thanks, that worked great!

So now I’m trying to extend this by having two 3D viewers side-by-side, where the same model is in both viewers but is being clipped by different planes in each viewer. Is this possible? I tried changing the 'threeDWidgetIndex from 0 to 1 or 2 but this either crashes Slicer or does not appear to do anything.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [October 17, 2019, 8:47pm UTC](https://discourse.slicer.org/t/clipping-of-models-is-too-slow/8788/11 "2019-10-17T20:47:25Z")

</div>

> [@Prashant\_Pandey](#):
>
> I tried changing the 'threeDWidgetIndex from 0 to 1 or 2

You can ask the number of threeDWidgets from the layout manager. If you try to get an index that goes beyond that number-1 then you’ll make Slicer crash. If you ask for a valid index then it should work well.

---

<div class="post-metadata">

**Author:** ![Prashant\_Pandey](https://avatars.discourse-cdn.com/v4/letter/p/c0e974/32.png) [@Prashant\_Pandey](https://discourse.slicer.org/u/Prashant_Pandey)\
**Post date:** [October 17, 2019, 10:11pm UTC](https://discourse.slicer.org/t/clipping-of-models-is-too-slow/8788/12 "2019-10-17T22:11:48Z")

</div>

Thanks, it’s working perfectly now! See: [https://drive.google.com/open?id=1dpjrrUuoFvtAltOaN\_RfPkhyqnYpleU6](https://drive.google.com/open?id=1dpjrrUuoFvtAltOaN_RfPkhyqnYpleU6)

Just wondering if it’s possible to clip volumes with a clipping plane too (as opposed to a ROI annotation)? We have a powerful GPU machine and Slicer renders medical volumes very nicely so it would be nice to be able to use that in the same way.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [October 17, 2019, 11:25pm UTC](https://discourse.slicer.org/t/clipping-of-models-is-too-slow/8788/13 "2019-10-17T23:25:48Z")

</div>

Volume rendering displayable manager already uses the mapper’s clipping plane for clipping. You can simply apply the tool transform to the clipping ROI node.

---

<div class="post-metadata">

**Author:** ![Prashant\_Pandey](https://avatars.discourse-cdn.com/v4/letter/p/c0e974/32.png) [@Prashant\_Pandey](https://discourse.slicer.org/u/Prashant_Pandey)\
**Post date:** [October 18, 2019, 9:37pm UTC](https://discourse.slicer.org/t/clipping-of-models-is-too-slow/8788/14 "2019-10-18T21:37:55Z")

</div>

If I understand, for volume rendering it’s a ROI not a plane? Can I apply a plane instead?  
I tried transforming the ROI with the tool transform, and manually adjusting the extents of the ROI to make it like a plane, but that isn’t ideal.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [October 28, 2019, 9:15pm UTC](https://discourse.slicer.org/t/clipping-of-models-is-too-slow/8788/15 "2019-10-28T21:15:27Z")

</div>

If you just want to clip with a single plane then move the other clipping planes very far (this is what we usually do).

You can manipulate the mapper at lower level at replace the clipping plane set with a single plane but then you will fight with the volume rendering displayable manager (time to time the displayable manager will reset the clipping plane set that is stored in MRML).
