Clip Polydata along a round surface


Hello! So i have this 2 pipes combination, and what im trying to do, is to seperate the second pipe out of the first one, to get 2 pipes ( the one on the base should be a perfect cylinder and the other should have a round base ). For that i extracted the feature_edge_loop with vtk (the loop connecting both cylinders), but i couldnt use it to cut the polydata. All i found is clipping polydata through a (planar) plan.
Did you guys have any idea how to cut polydata throught a non-planar object? I’ll be so greatfull for any tipps. Thanks
Im new at vtk, so please use simple explinations :sweat_smile:

It seems like a lot of people want to use vtk as a geometric modeling system, when it’s a visualization system :slight_smile:

Having said that, you might be able to hack something together along the following lines. I can’t swear it will work, but maybe…

  1. Use vtkPolyDataNormals with the proper FeatureAngle (and make sure you have SplittingOn).
  2. Use vtkPolyDataConnectivityFilter to extract the appropriate connected regions.

#1 will break the object apart due to sharp edges. #2 will extract the regions you want. This procedure depends on having a manifold mesh (i.e. no cracks, t-junctions, etc. unless the cracks occur where the pipe seams are located).

Good luck!

Basically you have three ways.

  1. Use the combination of vtkimplictfunction.
    you can clip the vertical one out using vtkcylinder as input for vtkclippolydata.

  2. In higher version of vtk, you can use booleanfilter, but it is slow.

  3. And at least, you can covert polydata to imagedata and do anything you want.

By the way, could you tell me what is your background and rendering setting? It looks pretty good.

1 Like

Hi Wailmer, Thanks for your answer.
To the Background: Im working on a 3d multi-directional Printing project, and what im trying to do, is to decompose the input (stl-file could be anything, not necessarily geometrical object) to multiple subvolumes, that could be printed in their own direction without support material. ( So for this example: first print the base cylinder, then rotate the printed object by 90° and print the attached cylinder) So my output should be a set of polydata and this should work totally automatically in the algorithm.

Im still stuck at that problem since a long time . I already tried the vtkimplicitfuntion approche but it didint work out. I’ll be glad if you could get a look at it.

#!/usr/bin/env python

import vtk

stl = vtk.vtkSTLReader()
stl.SetFileName("PATH_TO_STL_FILE/Pipe.stl")
stl.Update()
poly = stl.GetOutput()

colors = vtk.vtkNamedColors 

selectionPoints= vtk.vtkPoints() #got those point from 
selectionPoints.InsertPoint(0, -0.16553, 0.135971, 0.451972)
selectionPoints.InsertPoint(1, -0.0880123, -0.134952, 0.4747)
selectionPoints.InsertPoint(2, 0.00292618, -0.134604, 0.482459)
selectionPoints.InsertPoint(3, 0.0641941, 0.067112, 0.490947)
selectionPoints.InsertPoint(4, 0.15577, 0.0734765, 0.469245)
selectionPoints.InsertPoint(5, 0.166667, -0.129217, 0.454622)
selectionPoints.InsertPoint(6, 0.241259, -0.123363, 0.420581)
selectionPoints.InsertPoint(7, 0.240334, 0.0727106, 0.432555)
selectionPoints.InsertPoint(8, 0.308529, 0.0844311, 0.384357)
selectionPoints.InsertPoint(9, 0.32672, -0.121674, 0.359187)
selectionPoints.InsertPoint(10, 0.380721, -0.117342, 0.302527)
selectionPoints.InsertPoint(11, 0.387804, 0.0455074, 0.312375)
selectionPoints.InsertPoint(12, 0.43943, -0.111673, 0.211707)
selectionPoints.InsertPoint(13, 0.470984, -0.0801913, 0.147919)
selectionPoints.InsertPoint(14, 0.436777, 0.0688872, 0.233021)
selectionPoints.InsertPoint(15, 0.44874, 0.188852, 0.109882)
selectionPoints.InsertPoint(16, 0.391352, 0.254285, 0.176943)
selectionPoints.InsertPoint(17, 0.373274, 0.154162, 0.294296)
selectionPoints.InsertPoint(18, 0.274659, 0.311654, 0.276609)
selectionPoints.InsertPoint(19, 0.206068, 0.31396, 0.329702)
selectionPoints.InsertPoint(20, 0.263789, 0.174982, 0.387308)
selectionPoints.InsertPoint(21, 0.213034, 0.175485, 0.417142)
selectionPoints.InsertPoint(22, 0.169113, 0.261974, 0.390286)
selectionPoints.InsertPoint(23, 0.102552, 0.25997, 0.414814)
selectionPoints.InsertPoint(24, 0.131512, 0.161254, 0.454705)
selectionPoints.InsertPoint(25, 0.000192443, 0.156264, 0.475307)
selectionPoints.InsertPoint(26, -0.0392091, 0.000251724, 0.499943)
selectionPoints.InsertPoint(27, -0.096161, 0.159646, 0.46438)

loop = vtk.vtkImplicitSelectionLoop()
loop.SetLoop(selectionPoints)
#loop.GenerateSelectionScalarsOn()
#loop.Update()

clipper =vtk.vtkClipPolyData()
clipper.SetInputData(poly)
clipper.SetClipFunction(loop)
clipper.SetValue(0.0)
clipper.Update()

poly_connectivity =vtk.vtkPolyDataConnectivityFilter()
poly_connectivity.SetExtractionModeToLargestRegion()
poly_connectivity.SetInputData(poly)
poly_connectivity.Update()

clipMapper = vtk.vtkPolyDataMapper()
clipMapper.SetInputConnection(poly_connectivity.GetOutputPort())
clipMapper.ScalarVisibilityOff()

#backProp = vtk.vtkProperty()
#backProp.SetColor(colors.GetColor3d('Tomato'))

clipActor = vtk.vtkLODActor() 
clipActor.SetMapper(clipMapper)
#clipActor.SetBackfaceProperty(backProp)
#clipActor.GetProperty().SetColor(colors.GetColor3d("Banana").GetData())

renderer = vtk.vtkRenderer() 

renderWindow = vtk.vtkRenderWindow() 
renderWindow.AddRenderer(renderer)

interactor = vtk.vtkRenderWindowInteractor() 
interactor.SetRenderWindow(renderWindow)

# Add the actors to the renderer, set the background and size
renderer.AddActor(clipActor)
#renderer.SetBackground(colors.GetColor3d("SlateGray").GetData())

renderWindow.SetSize(500, 500)
renderWindow.SetWindowName("ImplicitSelectionLoop")

renderWindow.Render()
interactor.Start()

#if __name__ == '__main__':
#    main()


I also tried to use vtk booleanfilter, but i need first to extract one part, which is what i am trying to do.

To your third suggestion, do u have an example, to relay on? im pretty new in this hole vtk.
Thanks :)))

I cannot upload an attachment as im a new user, but you can use whatever stl-File :smiley:

Im getting a Error with that.

normals = vtk.vtkPolyDataNormals()
normals.SetInputData(poly)
normals.SetFeatureAngle(1) # i dont know which angle i need
#normals.AutoOrientNormalsOn()
normals.SplittingOn()
normals.Update()

connect=vtk.vtkPolyDataConnectivityFilter()
connect.SetInputData(normals)
connect.SetExtractionModeToSpecifiedRegions()
connect.Update()

i got this error:

connect.SetInputData(normals)
TypeError: SetInputData argument 1: method requires a vtkDataObject, a vtkPolyDataNormals was provided.

Im i doing something wrong here ?? :cold_sweat: