def get_tpc_intersection(point, direction, box=None): """ Abstract class to calculate the TPC crossings """ if box is None: tpc_box = [ TPC.x_min, TPC.x_max, TPC.y_min, TPC.y_max, TPC.z_min, TPC.z_max ] else: tpc_box = box t1 = vtk.mutable(0) t2 = vtk.mutable(0) plane1 = vtk.mutable(0) plane2 = vtk.mutable(0) entry = [-1., -1., -1.] exit = [-1., -1., -1.] l = 5000 ray = [l * direction[0], l * direction[1], l * direction[2]] end_point = np.add(point, ray).tolist() vtk.vtkBox().IntersectWithLine(tpc_box, point, end_point, t1, t2, entry, exit, plane1, plane2) return [entry, exit]
def __init__(self): # POINTS self.points = vtk.vtkPoints() self.cell = vtk.vtkCellArray() self.poly = vtk.vtkPolyData() self.poly.SetPoints(self.points) self.poly.SetVerts(self.cell) # mapper = vtk.vtkPolyDataMapper() # mapper.SetInputData(self.poly) # self.actor = vtk.vtkActor() # self.actor.SetMapper(mapper) # CLIP box = vtk.vtkBox() box.SetBounds(0, 1, 0, 1, 0, 1) self.clipper = vtk.vtkClipPolyData() self.clipper.SetInputData(self.poly) self.clipper.SetClipFunction(box) self.clipper.Update() mapper_in = vtk.vtkPolyDataMapper() mapper_in.SetInputConnection(self.clipper.GetOutputPort(1)) actor_in = vtk.vtkActor() actor_in.SetMapper(mapper_in) actor_in.GetProperty().SetColor(1, 0, 0) mapper_out = vtk.vtkPolyDataMapper() mapper_out.SetInputConnection(self.clipper.GetOutputPort(0)) actor_out = vtk.vtkActor() actor_out.SetMapper(mapper_out) actor_out.GetProperty().SetColor(0, 1, 0) self.actor = vtk.vtkAssembly() self.actor.AddPart(actor_in) self.actor.AddPart(actor_out) for i in range(10000): self.points_grown_up()
def cutPolyData(dataSet, **kwargs): # Read options pt = kwargs.get('point') normal = kwargs.get('normal') delta = kwargs.get('maxDist') if pt == None: raise RuntimeError('No point provided') if normal == None: raise RuntimeError('No normal provided') # Create plane plane = vtk.vtkPlane() plane.SetOrigin(pt[0], pt[1], pt[2]) plane.SetNormal(normal[0], normal[1], normal[2]) cutter = vtk.vtkCutter() cutter.SetCutFunction(plane) cutter.SetInputData(dataSet) if delta == None: cutter.Update() return cutter.GetOutput() else: # Create a box box = vtk.vtkBox() box.SetBounds(pt[0]-delta, pt[0]+delta, pt[1]-delta, pt[1]+delta, pt[2]-delta, pt[2]+delta) # Clip data with a box clipper = vtk.vtkClipDataSet() clipper.SetClipFunction(box) clipper.SetInputConnection(cutter.GetOutputPort()) clipper.InsideOutOn() clipper.Update() return clipper.GetOutput()
def extractDataSetByBounds(fullvtkDataSet, boundvtkDataSet): """ Function to extract from a vtkDataSet within bounds of another vtkDataSet. Returns a extrct filter """ # Define a bounding box implicit if boundvtkDataSet.IsA('vtkDataSet'): impFunc = vtk.vtkBox() impFunc.SetBounds(boundvtkDataSet.GetBounds()) elif boundvtkDataSet.IsA('vtkImplicitFunction'): impFunc = boundvtkDataSet # Extract all inside and boundaries if fullvtkDataSet.IsA('vtkPolyData'): extractFilt = vtk.vtkExtractPolyDataGeometry() else: extractFilt = vtk.vtkExtractGeometry() extractFilt.SetExtractInside(1) extractFilt.SetExtractBoundaryCells(1) extractFilt.SetInputData(fullvtkDataSet) extractFilt.SetImplicitFunction(impFunc) extractFilt.Update() return extractFilt
def actor_clip(): sphere = vtk.vtkSphereSource() sphere.SetCenter(1, 1, 1) sphere.SetRadius(1) sphere.Update() box = vtk.vtkBox() box.SetBounds(0, 7, -1, 4, -3, 1) clipper = vtk.vtkClipPolyData() clipper.SetClipFunction(box) clipper.SetInputConnection(sphere.GetOutputPort()) clipper.GenerateClippedOutputOn() clipper.Update() mapper_in = vtk.vtkPolyDataMapper() mapper_in.SetInputConnection(clipper.GetOutputPort(1)) actor_in = vtk.vtkActor() actor_in.SetMapper(mapper_in) actor_in.GetProperty().SetColor(0, 255, 0) actor_in.GetProperty().SetPointSize(2) mapper_out = vtk.vtkPolyDataMapper() mapper_out.SetInputConnection(clipper.GetOutputPort(0)) actor_out = vtk.vtkActor() actor_out.SetMapper(mapper_out) actor_out.GetProperty().SetColor(255, 0, 0) actor_in.GetProperty().SetPointSize(2) return actor_in, actor_out
def __init__(self, parent): QVTKRenderWindowInteractor.__init__(self, parent) self.renderer = vtk.vtkRenderer() self.GetRenderWindow().AddRenderer(self.renderer) interactor = vtk.vtkInteractorStyleSwitch() self._Iren.SetInteractorStyle(interactor) self.surface = None # Remainng calls set up axes. tprop = vtk.vtkTextProperty() tprop.SetColor(1,1,1) # Create a faint outline to go with the axes. self.outline = vtk.vtkOutlineFilter() # Initially set up with a box as input. This will be changed # to a plot once the user clicks something. self.box = vtk.vtkBox() self.box.SetBounds(0,10,0,10,0,10) sample = vtk.vtkSampleFunction() sample.SetImplicitFunction(self.box) sample.SetSampleDimensions(2,2,2) sample.SetModelBounds(0,10,0,10,0,5) sample.ComputeNormalsOff() self.outline.SetInputConnection(sample.GetOutputPort()) mapOutline = vtk.vtkPolyDataMapper() mapOutline.SetInputConnection(self.outline.GetOutputPort()) self.outlineActor = vtk.vtkActor() self.outlineActor.SetMapper(mapOutline) self.outlineActor.GetProperty().SetColor(1,1,1) self.outlineActor.GetProperty().SetOpacity(.25) self.renderer.AddActor(self.outlineActor) self.axes = vtk.vtkCubeAxesActor2D() self.axes.SetCamera(self.renderer.GetActiveCamera()) self.axes.SetFlyModeToOuterEdges() self.axes.SetLabelFormat("%6.4g") self.axes.SetFontFactor(0.8) self.axes.SetAxisTitleTextProperty(tprop) self.axes.SetAxisLabelTextProperty(tprop) self.axes.SetXLabel("MPI Rank") self.axes.SetYLabel("Progress") self.axes.SetZLabel("Effort") self.axes.SetInput(sample.GetOutput()) self.renderer.AddViewProp(self.axes) # Keep original camera around in case it gets changed self.originalCamera = self.renderer.GetActiveCamera() self.renderer.GetActiveCamera().Pitch(90) # Want effort to be vertical self.renderer.GetActiveCamera().OrthogonalizeViewUp() self.renderer.ResetCamera() self.renderer.GetActiveCamera().Elevation(15) # Be slightly above the data
def _createTube(self): logging.debug("In MultiSliceContour::createTube()") points = vtk.vtkPoints() for point in self._originalPoints: points.InsertNextPoint(point) self._parametricSpline = vtk.vtkParametricSpline() self._parametricSpline.SetPoints(points) self._parametricFuntionSource = vtk.vtkParametricFunctionSource() self._parametricFuntionSource.SetParametricFunction(self._parametricSpline) self._parametricFuntionSource.SetUResolution(100) self._tubeFilter = vtk.vtkTubeFilter() self._tubeFilter.SetNumberOfSides(10) self._tubeFilter.SetRadius(self._radius) self._tubeFilter.SetInputConnection(self._parametricFuntionSource.GetOutputPort()) self._tubeActor = [] self._cubes = [] i = 0 for cutter in self._cutters: cutter.SetInputConnection(self._tubeFilter.GetOutputPort()) cutter.Update() cube = vtk.vtkBox() #TODO change imagebounds to planesourceRange cube.SetBounds(self._scene.slice[i].getBounds()) clip = vtk.vtkClipPolyData() clip.SetClipFunction(cube) clip.SetInputConnection(cutter.GetOutputPort()) clip.InsideOutOn() clip.Update() self._cubes.append(cube) tubeMapper=vtk.vtkPolyDataMapper() tubeMapper.ScalarVisibilityOff() tubeMapper.SetInputConnection(clip.GetOutputPort()) tubeMapper.GlobalImmediateModeRenderingOn() tubeActor = vtk.vtkActor() tubeActor.SetMapper(tubeMapper) tubeActor.GetProperty().LightingOff() tubeActor.GetProperty().SetColor(self.lineColor) tubeActor.SetUserTransform(self._scene.slice[i].resliceTransform.GetInverse()) self._tubeActor.append(tubeActor) self._scene.renderer.AddActor(tubeActor) i = i+1
def bound_polydata_by_image(image, poly, threshold): bound = vtk.vtkBox() image.ComputeBounds() b_bound = image.GetBounds() b_bound = [ b + threshold if (i % 2) == 0 else b - threshold for i, b in enumerate(b_bound) ] #print("Bounding box: ", b_bound) bound.SetBounds(b_bound) clipper = vtk.vtkClipPolyData() clipper.SetClipFunction(bound) clipper.SetInputData(poly) clipper.InsideOutOn() clipper.Update() return clipper.GetOutput()
def __init__(self,model=None): """Initilaization method for the MeshVisualization class This method initializes a new instance of the MeshVisualization class and visualizes the mesh of the passed GmshModel instance. Within the method, basic visualization settings are defined, before the visualization method is called. Parameters: model: GmshModel object instance model for which the mesh has to be visualized """ # plausibility checks for input arguments if model is None: raise TypeError("No model instance to visualize passed. For the visualization of a model, that model has to be known. Check your input data.") self.model=model # set plotting theme pv.set_plot_theme("paraview") # use Paraview style for plotting # get necessary model information for the default configuration physicalIDs=model.getIDsFromTags(model.gmshAPI.getPhysicalGroups(dim=model.dimension)) # get group IDs for physical groups of the highest dimension modelBBox=model._getGmshModelBoundingBox() # get the overall bounding box of the Gmsh model # define settings self.defaultSettings={ "lowerThreshold": min(physicalIDs), # set lower threshold value to minimum value of active scalar field "upperThreshold": max(physicalIDs), # set upper threshold value to minimum value of active scalar field "boxBounds": modelBBox.T.reshape(6) # define bounds of extraction box to match bounds of the model (factor 1.25 will be applied automatically) } self.currentSettings=cp.deepcopy(self.defaultSettings) # copy default settings as initial version of current settings # initialize arrays required for proper mesh visualization self.plotterObj=pv.Plotter(title="GmshModel Mesh Visualization") # initialize plotterObj from pyvista and set title self.mesh=None # initialize mesh self.thresholdAlgorithm=None # initialize threshold algorithm self.extractionBox=vtk.vtkBox() # initiliaze dummy extraction box to update information of boxWidget self.extractionBoxBounds=pv.PolyData() # initialize dummy extraction box bounds to store information of boxWidget bounds self.extractionAlgorithm=None # initialize extraction algorithm self.activeWidgets=[] # initialize list of active widgets # visualize the model mesh self.visualizeMesh()
def prepContinents(fnm): """ This converts vcs continents files to vtkpolydata Author: Charles Doutriaux Input: vcs continent file name """ if vcsContinents.has_key(fnm): return vcsContinents[fnm] poly =vtk.vtkPolyData() cells = vtk.vtkCellArray() pts = vtk.vtkPoints() f=open(fnm) ln=f.readline() while ln.strip().split()!=["-99","-99"]: # Many lines, need to know number of points N = int(ln.split()[0]) # Now create and store these points n=0 npts = pts.GetNumberOfPoints() while n<N: ln=f.readline() sp=ln.split() sn = len(sp) didIt = False if sn%2 == 0: try: spts = [] for i in range(sn/2): l,L = float(sp[i*2]),float(sp[i*2+1]) spts.append([l,L]) for p in spts: pts.InsertNextPoint(p[1],p[0],0.) n+=sn didIt = True except: didIt = False if didIt is False: while len(ln)>2: l,L=float(ln[:8]),float(ln[8:16]) pts.InsertNextPoint(L,l,0.) ln=ln[16:] n+=2 ln = vtk.vtkPolyLine() ln.GetPointIds().SetNumberOfIds(N/2) for i in range(N/2): ln.GetPointIds().SetId(i,i+npts) cells.InsertNextCell(ln) ln=f.readline() poly.SetPoints(pts) poly.SetLines(cells) # The dataset has some duplicate lines that extend outside of x=[-180, 180], # which will cause wrapping artifacts for certain projections (e.g. # Robinson). Clip out the duplicate data: box = vtk.vtkBox() box.SetXMin(-180., -90., 0.) box.SetXMax(180., 90., 1.) clipper = vtk.vtkClipPolyData() clipper.SetInputData(poly) clipper.InsideOutOn() clipper.SetClipFunction(box) clipper.Update() poly = clipper.GetOutput() vcsContinents[fnm]=poly return poly
def main(): colors = vtk.vtkNamedColors() # create a sphere sphere = vtk.vtkSphere() sphere.SetRadius(1) sphere.SetCenter(1, 0, 0) # create a box box = vtk.vtkBox() box.SetBounds(-1, 1, -1, 1, -1, 1) # combine the two implicit functions boolean = vtk.vtkImplicitBoolean() boolean.SetOperationTypeToDifference() # boolean.SetOperationTypeToUnion() # boolean.SetOperationTypeToIntersection() boolean.AddFunction(box) boolean.AddFunction(sphere) # The sample function generates a distance function from the implicit # function. This is then contoured to get a polygonal surface. sample = vtk.vtkSampleFunction() sample.SetImplicitFunction(boolean) sample.SetModelBounds(-1, 2, -1, 1, -1, 1) sample.SetSampleDimensions(40, 40, 40) sample.ComputeNormalsOff() # contour surface = vtk.vtkContourFilter() surface.SetInputConnection(sample.GetOutputPort()) surface.SetValue(0, 0.0) # mapper mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(surface.GetOutputPort()) mapper.ScalarVisibilityOff() actor = vtk.vtkActor() actor.SetMapper(mapper) actor.GetProperty().EdgeVisibilityOn() actor.GetProperty().SetColor(colors.GetColor3d('AliceBlue')) actor.GetProperty().SetEdgeColor(colors.GetColor3d('SteelBlue')) # A renderer and render window renderer = vtk.vtkRenderer() renderer.SetBackground(colors.GetColor3d('Silver')) # add the actor renderer.AddActor(actor) # render window renwin = vtk.vtkRenderWindow() renwin.AddRenderer(renderer) # An interactor interactor = vtk.vtkRenderWindowInteractor() interactor.SetRenderWindow(renwin) # Start interactor.Initialize() renwin.Render() # renderer.GetActiveCamera().AddObserver('ModifiedEvent', CameraModifiedCallback) renderer.GetActiveCamera().SetPosition(5.0, -4.0, 1.6) renderer.GetActiveCamera().SetViewUp(0.1, 0.5, 0.9) renderer.GetActiveCamera().SetDistance(6.7) renwin.Render() interactor.Start()
def getModelROIStencil(self): import time _t0 = time.time() t1 = self.__Transform.GetInverse() roi_type = self.getModelROIType() roi_orientation = self.getModelROIOrientation() # bounds, extent and center b = self.getModelROIBounds() # abort early if we haven't been fully set up yet if b is None: return None # determine transformed boundary _index = [[0, 2, 4], [0, 2, 5], [0, 3, 4], [0, 3, 5], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5]] b_t = [1e38, -1e38, 1e38, -1e38, 1e38, -1e38] is_identity = True # is transform identity? is_identity = self.__Transform.GetMatrix().Determinant() == 1.0 # is_identity = False for i in range(8): i2 = _index[i] pt = [b[i2[0]], b[i2[1]], b[i2[2]]] _temp = self.__Transform.TransformPoint(pt[0], pt[1], pt[2]) b_t[0] = min(_temp[0], b_t[0]) b_t[1] = max(_temp[0], b_t[1]) b_t[2] = min(_temp[1], b_t[2]) b_t[3] = max(_temp[1], b_t[3]) b_t[4] = min(_temp[2], b_t[4]) b_t[5] = max(_temp[2], b_t[5]) e_t = self._BoundsToExtent(b_t) # sanity check - check for inversion (caused by negative spacing) e_t = list(e_t) for i in range(3): if e_t[i * 2] > e_t[i * 2 + 1]: v = e_t[i * 2] e_t[i * 2] = e_t[i * 2 + 1] e_t[i * 2 + 1] = v # expand stencil extent by one pixel on all sides e_t = (e_t[0] - 1, e_t[1] + 1, e_t[2] - 1, e_t[3] + 1, e_t[4] - 1, e_t[5] + 1) # make sure we're dealing with ints e_t = map(int, e_t) if is_identity: # fast, but limited to canonical objects self._StencilGenerator = vtk.vtkROIStencilSource() else: # slow, but more generic self._StencilGenerator = vtk.vtkImplicitFunctionToImageStencil() self._StencilGenerator.SetOutputOrigin(self.getImageOrigin()) self._StencilGenerator.SetOutputSpacing(self.getImageSpacing()) # set extent of stencil - taking into account transformation self._StencilGenerator.SetOutputWholeExtent(e_t) if is_identity: # use DG's fast routines if roi_type == "box": self._StencilGenerator.SetShapeToBox() elif roi_type == "cylinder": if roi_orientation == "X": self._StencilGenerator.SetShapeToCylinderX() elif roi_orientation == "Y": self._StencilGenerator.SetShapeToCylinderY() elif roi_orientation == "Z": self._StencilGenerator.SetShapeToCylinderZ() elif roi_type == "ellipsoid": self._StencilGenerator.SetShapeToEllipsoid() self._StencilGenerator.SetBounds(b) else: # use JG's slow routines if roi_type == "box": obj = vtk.vtkBox() obj.SetTransform(t1) obj.SetBounds(b) elif roi_type == "cylinder": cyl = vtk.vtkCylinder() cyl.SetRadius(1.0) xc, yc, zc = (b[1] + b[0]) * 0.5, (b[3] + b[2]) * 0.5, (b[5] + b[4]) * 0.5 diam_a, diam_b, diam_c = (b[1] - b[0]), (b[3] - b[2]), (b[5] - b[4]) # The cylinder is infinite in extent, so needs to be cropped by using the intersection # of three implicit functions -- the cylinder, and two cropping # planes obj = vtk.vtkImplicitBoolean() obj.SetOperationTypeToIntersection() obj.AddFunction(cyl) clip1 = vtk.vtkPlane() clip1.SetNormal(0, 1, 0) obj.AddFunction(clip1) clip2 = vtk.vtkPlane() clip2.SetNormal(0, -1, 0) obj.AddFunction(clip2) t2 = vtk.vtkTransform() t2.Translate(xc, yc, zc) if roi_orientation == "X": # cylinder is infinite in extent in the y-axis t2.Scale(1, diam_b / 2.0, diam_c / 2.0) t2.RotateZ(90) r = diam_a / 2.0 elif roi_orientation == "Y": # cylinder is infinite in extent in the y-axis t2.Scale(diam_a / 2.0, 1, diam_c / 2.0) r = diam_b / 2.0 elif roi_orientation == "Z": # cylinder is infinite in extent in the y-axis t2.Scale(diam_a / 2.0, diam_b / 2.0, 1) t2.RotateX(90) r = diam_c / 2.0 clip1.SetOrigin(0, r, 0) clip2.SetOrigin(0, -r, 0) # combine transforms t2.SetInput(self.__Transform) obj.SetTransform(t2.GetInverse()) elif roi_type == "ellipsoid": obj = vtk.vtkSphere() obj.SetRadius(1.0) xc, yc, zc = (b[1] + b[0]) * 0.5, (b[3] + b[2]) * 0.5, (b[5] + b[4]) * 0.5 diam_a, diam_b, diam_c = (b[1] - b[0]), (b[3] - b[2]), (b[5] - b[4]) t2 = vtk.vtkTransform() t2.Translate(xc, yc, zc) t2.Scale(diam_a / 2.0, diam_b / 2.0, diam_c / 2.0) # combine transforms t2.SetInput(self.__Transform) obj.SetTransform(t2.GetInverse()) self._StencilGenerator.SetInput(obj) _t1 = time.time() self._StencilGenerator.Update() _t2 = time.time() return self._StencilGenerator.GetOutput()
def __init__(self, name, file_path="", density=0, volume=0, mass=0, J_zz=0, u_CAD=np.zeros(3), r_CAD=np.zeros(3), theta=np.zeros(3), dR=np.zeros(3), dtheta=np.zeros(3), color=np.ones(3, dtype="float32"), _dict={}, connected_to_ground=False, parent=None): """ Constructor of body class :param name: body name (string) :param filename: absolute path file of body properties :param density: density of the material of the body :param volume: volume of the body (as float) in m^3 :param mass: mass of the body (as float) in kg :param J_zz: mass moment of inertia of a body against z-axis (as float) in kg*m^2 :param u_CAD: a vector to mass center of a body in body CAD CS (as array) in m :param r_CAD: a vector to body CAD CS in GCS of a system (as array) in m :param theta: orientation angles (numpy array) in degrees :param dR: a vector of velocities (numpy array) in m/s :param dtheta: a vector of angular velocities (numpy array) in deg/s :param color: a color vector (RGB) :param properties_file: a path to mass and geometry properties data in .dat file (todo) :param geometry_data_file: a path to geometry .stl or .obj file (todo) """ super(RigidBody, self).__init__(name=name, file_path=file_path, parent=parent) # type of body self.body_type = "rigid body" # body id self.body_id = self._count() # body coordinates self.q_i_size = 3 # geometry and physical properties self.mass = mass self.J_zz = J_zz # size of mass matrix self.M_size = self.q_i_dim = 3 # material properties self.density = density self.volume = volume # visualization properties # size self.size = 1. # coordinate system properties self.u_CAD = u_CAD self.r_CAD = r_CAD # dynamic properties # transform with respect to selected CS # options: CAD, LCS self.transformCS = "CAD" self.R = self.u_CAD + self.r_CAD # (initial) coordinates and angles (in degrees) self.theta = theta # (initial) translational and rotational velocities self.dR = dR self.dtheta = dtheta # visualization properties self.color = color # connected to ground self._connected_to_ground = connected_to_ground # set directory to read body data from file self.file_path = file_path # os.chdir(MBD_folder_abs_path) # read body properties file if os.path.isfile(self.file_path): self._dict = read_body_data_file.read_body_data_file( self.file_path) self.add_attributes_from_dict(self._dict) # check if both files exist if not os.path.isfile(self.file_path): raise IOError, "Properties file not found!" if self._geometry_type == self.geometry_file_extension and self.geometry_filename is not None: if not os.path.isfile(self.geometry_filename): print "Geometry file %s not found!" % self.geometry_filename # additional translation due to rotation with respect to CAD CS # self.u_CAD[0:2] = Ai_ui_P_vector(self.u_CAD[0:2], 0)#self.theta[2] _R = self.u_CAD - Ai_ui_P_vector(self.u_CAD, self.theta[2]) #np.zeros(3)# # reevaluate R, based on body data from .dat file if all(self.u_CAD == np.zeros(3)) and all(self.r_CAD == np.zeros(3)): pass else: self.R = self.u_CAD + self.r_CAD # create geometry object # read geometry file and save vertices and normals if self._parent is not None: os.chdir(self._parent._parent.MBD_folder_abs_path) if self.geometry_filename is not None: if os.path.isfile(self.geometry_filename): # get extension self._geometry_type = os.path.splitext( self.geometry_filename)[1] if self._geometry_type == ".stl": self.geometry = Geometry(self.geometry_filename, parent=self) elif self._geometry_type == ".txt": self.geometry = Geometry2D(self.geometry_filename, parent=self) else: raise ValueError, "Object attribute _geometry_type not correct!" elif self._geometry_type == "line": self.geometry = Line(parent=self) elif self._geometry_type == "cylinder": self.geometry = vtk.vtkCylinderSource() self.geometry.SetRadius(self.R0) self.geometry.SetHeight(self.L) self.geometry.SetResolution(40) elif self._geometry_type == "box-cylinder": self.geometry_list = [None, None] # create a box box = vtk.vtkBox() box.SetBounds(-self.a, +self.a, -self.b, +self.b, -self.c, +self.c) # create a sphere cylinder = vtk.vtkCylinder() cylinder.SetRadius(self.R0) # cylinder.SetCenter(0,0,0) geometry_list = [box, cylinder] # combine the two implicit functions boolean = vtk.vtkImplicitBoolean() boolean.SetOperationTypeToDifference() # boolean.SetOperationTypeToUnion() # boolean.SetOperationTypeToIntersection() for geometry in geometry_list: boolean.AddFunction(geometry) # The sample function generates a distance function from the implicit # function. This is then contoured to get a polygonal surface. sample = vtk.vtkSampleFunction() sample.SetImplicitFunction(boolean) sample.SetModelBounds(-10E-3, +10E-3, -10E-3, +10E-3, -10E-3, +10E-3) sample.SetSampleDimensions(40, 40, 40) sample.ComputeNormalsOn() # contour self.surface = vtk.vtkContourFilter() self.surface.SetInputConnection(sample.GetOutputPort()) self.surface.SetValue(0, 0.0) else: if self.geometry is None: print "Body geometry file %s not found! Attribute self.geometry for body %s not created." % ( self.geometry_filename, self._name) # add additional attributes to geometry object _dict_geometry = extract_from_dictionary_by_string_in_key( _dict, "geometry.") if self.geometry is not None and _dict_geometry: self.geometry.add_attributes_from_dict(_dict_geometry) if (self.r_CAD == np.zeros(3)).all() and (self.u_CAD == np.zeros(3)).all(): self.r_CAD = self.R
def getModelROIStencil(self): import time _t0 = time.time() t1 = self.__Transform.GetInverse() roi_type = self.getModelROIType() roi_orientation = self.getModelROIOrientation() # bounds, extent and center b = self.getModelROIBounds() # abort early if we haven't been fully set up yet if b is None: return None # determine transformed boundary _index = [ [0, 2, 4], [0, 2, 5], [0, 3, 4], [0, 3, 5], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5], ] b_t = [1e38, -1e38, 1e38, -1e38, 1e38, -1e38] is_identity = True # is transform identity? is_identity = self.__Transform.GetMatrix().Determinant() == 1.0 #is_identity = False for i in range(8): i2 = _index[i] pt = [b[i2[0]], b[i2[1]], b[i2[2]]] _temp = self.__Transform.TransformPoint(pt[0], pt[1], pt[2]) b_t[0] = min(_temp[0], b_t[0]) b_t[1] = max(_temp[0], b_t[1]) b_t[2] = min(_temp[1], b_t[2]) b_t[3] = max(_temp[1], b_t[3]) b_t[4] = min(_temp[2], b_t[4]) b_t[5] = max(_temp[2], b_t[5]) e_t = self._BoundsToExtent(b_t) # sanity check - check for inversion (caused by negative spacing) e_t = list(e_t) for i in range(3): if e_t[i * 2] > e_t[i * 2 + 1]: v = e_t[i * 2] e_t[i * 2] = e_t[i * 2 + 1] e_t[i * 2 + 1] = v # expand stencil extent by one pixel on all sides e_t = (e_t[0] - 1, e_t[1] + 1, e_t[2] - 1, e_t[3] + 1, e_t[4] - 1, e_t[5] + 1) # make sure we're dealing with ints e_t = map(int, e_t) if is_identity: # fast, but limited to canonical objects self._StencilGenerator = vtk.vtkROIStencilSource() else: # slow, but more generic self._StencilGenerator = vtk.vtkImplicitFunctionToImageStencil() self._StencilGenerator.SetOutputOrigin(self.getImageOrigin()) self._StencilGenerator.SetOutputSpacing(self.getImageSpacing()) # set extent of stencil - taking into account transformation self._StencilGenerator.SetOutputWholeExtent(e_t) if is_identity: # use DG's fast routines if roi_type == 'box': self._StencilGenerator.SetShapeToBox() elif roi_type == 'cylinder': if roi_orientation == 'X': self._StencilGenerator.SetShapeToCylinderX() elif roi_orientation == 'Y': self._StencilGenerator.SetShapeToCylinderY() elif roi_orientation == 'Z': self._StencilGenerator.SetShapeToCylinderZ() elif roi_type == 'ellipsoid': self._StencilGenerator.SetShapeToEllipsoid() self._StencilGenerator.SetBounds(b) else: # use JG's slow routines if roi_type == 'box': obj = vtk.vtkBox() obj.SetTransform(t1) obj.SetBounds(b) elif roi_type == 'cylinder': cyl = vtk.vtkCylinder() cyl.SetRadius(1.0) xc, yc, zc = (b[1] + b[0]) * \ 0.5, (b[3] + b[2]) * 0.5, (b[5] + b[4]) * 0.5 diam_a, diam_b, diam_c = ( b[1] - b[0]), (b[3] - b[2]), (b[5] - b[4]) # The cylinder is infinite in extent, so needs to be cropped by using the intersection # of three implicit functions -- the cylinder, and two cropping # planes obj = vtk.vtkImplicitBoolean() obj.SetOperationTypeToIntersection() obj.AddFunction(cyl) clip1 = vtk.vtkPlane() clip1.SetNormal(0, 1, 0) obj.AddFunction(clip1) clip2 = vtk.vtkPlane() clip2.SetNormal(0, -1, 0) obj.AddFunction(clip2) t2 = vtk.vtkTransform() t2.Translate(xc, yc, zc) if roi_orientation == 'X': # cylinder is infinite in extent in the y-axis t2.Scale(1, diam_b / 2.0, diam_c / 2.0) t2.RotateZ(90) r = diam_a / 2.0 elif roi_orientation == 'Y': # cylinder is infinite in extent in the y-axis t2.Scale(diam_a / 2.0, 1, diam_c / 2.0) r = diam_b / 2.0 elif roi_orientation == 'Z': # cylinder is infinite in extent in the y-axis t2.Scale(diam_a / 2.0, diam_b / 2.0, 1) t2.RotateX(90) r = diam_c / 2.0 clip1.SetOrigin(0, r, 0) clip2.SetOrigin(0, -r, 0) # combine transforms t2.SetInput(self.__Transform) obj.SetTransform(t2.GetInverse()) elif roi_type == 'ellipsoid': obj = vtk.vtkSphere() obj.SetRadius(1.0) xc, yc, zc = (b[1] + b[0]) * \ 0.5, (b[3] + b[2]) * 0.5, (b[5] + b[4]) * 0.5 diam_a, diam_b, diam_c = ( b[1] - b[0]), (b[3] - b[2]), (b[5] - b[4]) t2 = vtk.vtkTransform() t2.Translate(xc, yc, zc) t2.Scale(diam_a / 2.0, diam_b / 2.0, diam_c / 2.0) # combine transforms t2.SetInput(self.__Transform) obj.SetTransform(t2.GetInverse()) self._StencilGenerator.SetInput(obj) _t1 = time.time() self._StencilGenerator.Update() _t2 = time.time() return self._StencilGenerator.GetOutput()
def Execute(args): print("clip surface") mesh_reader = vmtkscripts.vmtkMeshReader() mesh_reader.InputFileName = args.mesh_file mesh_reader.Execute() mesh2surf = vmtkscripts.vmtkMeshToSurface() mesh2surf.Mesh = mesh_reader.Mesh mesh2surf.CleanOutput = 0 mesh2surf.Execute() scale_cfd = vmtkscripts.vmtkSurfaceScaling() scale_cfd.ScaleFactor = args.scale # meters to mm scale_cfd.Surface = mesh2surf.Surface scale_cfd.Execute() surface = vtk.vtkPolyData() surface.DeepCopy(scale_cfd.Surface) reader_trim = vmtkscripts.vmtkSurfaceReader() reader_trim.InputFileName = args.polydata_trim reader_trim.Execute() br_trim = reader_trim.Surface reader_ext = vmtkscripts.vmtkSurfaceReader() reader_ext.InputFileName = args.polydata_ext reader_ext.Execute() br_ext = reader_ext.Surface # have to make sure that they both have the same number of GetNumberOfPoints assert br_trim.GetNumberOfPoints() == br_ext.GetNumberOfPoints() locator = vtk.vtkPointLocator() locator.SetDataSet(br_trim) locator.BuildLocator() point_ext = [0.0, 0.0, 0.0] pt_cross = [0.0, 0.0, 0.0] pt_dot = 0.0 count = 0 for trim_id in range(br_ext.GetNumberOfPoints()): # get extension point point_ext = br_ext.GetPoint(trim_id) #closest trim point point_trim_id = locator.FindClosestPoint(point_ext) point_trim = br_trim.GetPoint(point_trim_id) # check that the points are close to the same direction pt_trim_normal = br_trim.GetPointData().GetArray( "BoundaryNormals").GetTuple(point_trim_id) pt_ext_normal = br_ext.GetPointData().GetArray( "BoundaryNormals").GetTuple(trim_id) #print(pt_trim_normal, pt_ext_normal) pt_dot = vtk.vtkMath.Dot(pt_trim_normal, pt_ext_normal) #vtk.vtkMath.Cross(pt_trim_normal, pt_ext_normal, pt_cross) #print(pt_dot, vtk.vtkMath.Norm(pt_cross))#, pt_cross) if (pt_dot < 0.95): print("help the vectors aren't colinear") assert pt_dot > .95 v = np.array(point_ext) - np.array(point_trim) #pt1 - pt2 v_mag = np.linalg.norm(v) n = v / v_mag # print("should be 1.0", np.linalg.norm(n), n) b1, b2 = hughes_moeller(n) #orthogonal basis #Get maximum radius box_radius = br_ext.GetPointData().GetArray("BoundaryRadius").GetTuple( trim_id) box_radius_trim = br_trim.GetPointData().GetArray( "BoundaryRadius").GetTuple(point_trim_id) #print(box_radius_trim, box_radius) extra_room = args.margin extra_z = 0.0 r_max = extra_room * max([box_radius[0], box_radius_trim[0] ]) # max radius z_max = extra_room * v_mag #create transformation matrix R = np.zeros((4, 4), dtype=np.float64) R[:3, 0] = b1 #x R[:3, 1] = b2 #y R[:3, 2] = n #z R[:3, 3] = np.array(point_trim) # the beginning of the clip R[3, 3] = 1.0 trans_matrix = vtk.vtkTransform() trans_inverse = vtk.vtkTransform() trans_matrix.SetMatrix(list(R.ravel())) #print(trans_matrix.GetMatrix()) trans_inverse.DeepCopy(trans_matrix) trans_inverse.Inverse() # point to define bounds dims_min = [-r_max, -r_max, -extra_z * z_max] dims_max = [r_max, r_max, z_max] planes = vtk.vtkBox() planes.SetBounds(dims_min[0], dims_max[0], dims_min[1], dims_max[1], dims_min[2], dims_max[2]) planes.SetTransform(trans_inverse) clipper = vtk.vtkTableBasedClipDataSet() clipper.SetInputData(surface) clipper.SetClipFunction(planes) clipper.InsideOutOff() #clipper.SetMergeTolerance(1.0E-6) clipper.Update() #print(clipper.GetMergeTolerance()) surface = clipper.GetOutput() #test = vtk.vtkCubeSource() #test.SetBounds (dims_min[0], dims_max[0], dims_min[1], dims_max[1], dims_min[2], dims_max[2]) #trans_cube = vtk.vtkTransformPolyDataFilter() #trans_cube.SetInputConnection(test.GetOutputPort()) #trans_cube.SetTransform(trans_matrix) #trans_cube.Update() #writer2 = vmtkscripts.vmtkSurfaceWriter() #writer2.OutputFileName = os.path.join(os.path.split(args.out_file)[0], "test_clip_box_{0}.vtp".format(count)) #writer2.Input = trans_cube.GetOutput() #writer2.Execute() count += 1 geom = vtk.vtkGeometryFilter() geom.SetInputData(surface) geom.Update() writer = vmtkscripts.vmtkSurfaceWriter() writer.OutputFileName = args.out_file writer.Input = geom.GetOutput() writer.Execute()
def slice_polyplane(mesh,profile,updir='y'): transL1 = vtk.vtkTransform() if updir=='y': transL1.RotateX(90) elif updir=='x': transL1.RotateY(90) elif updir=='z': pass trans = vtk.vtkTransformFilter() trans.SetTransform(transL1) trans.SetInputData(mesh) trans.Update() pts = vtk.vtkPoints() for pt in profile.points: pts.InsertNextPoint((pt[0],pt[1],0)) # check if labels are between profile points: label_abscissae = [0 for k in profile.labels] x0 = 0 for kpt in range(len(profile.points)-1): pt0 = profile.points[kpt] pt1 = profile.points[kpt+1] dL = ((pt0[0]-pt1[0])**2+(pt0[1]-pt1[1])**2)**0.5 for kppt in range(len(profile.labels)): pt = profile.labels[kppt][:2] d0 = ((pt0[0]-pt[0])**2+(pt0[1]-pt[1])**2)**0.5 d1 = ((pt1[0]-pt[0])**2+(pt1[1]-pt[1])**2)**0.5 if d0<dL and d1<=dL: if abs((d0+d1-dL)/dL)>1e-2: print('check vtktools.slice_polyplane') label_abscissae[kppt] = x0+d0 x0 += dL pd = vtk.vtkPolyData() pd.SetPoints(pts) pl = vtk.vtkPolyLine() pl.GetPointIds().SetNumberOfIds(len(profile.points)) for kpt in range(len(profile.points)): pl.GetPointIds().SetId(kpt,kpt) ca = vtk.vtkCellArray() ca.InsertNextCell(pl) pd.SetLines(ca) pd.Allocate(1,1) pd.InsertNextCell(pl.GetCellType(),pl.GetPointIds()) pl = vtk.vtkPolyLine.SafeDownCast(pd.GetCell(0)) bounds = pl.GetBounds() box = vtk.vtkBox() box.SetBounds(bounds[0],bounds[1],bounds[2],bounds[3],-1000,1000) pplane = vtk.vtkPolyPlane() pplane.SetPolyLine(pl) cut = vtk.vtkCutter() cut.SetInputConnection(trans.GetOutputPort()) cut.SetCutFunction(pplane) cut.Update() clip = vtk.vtkClipPolyData() clip.SetInputConnection(cut.GetOutputPort()) clip.SetClipFunction(box) clip.InsideOutOn() clip.Update() output = clip.GetOutput() abscissae = [] for kp in range(output.GetNumberOfPoints()): pt = output.GetPoint(kp) abscissae.append(project_on_polyline(pt[0],pt[1],pts)) return abscissae,output,label_abscissae
def getvtkdata(self, ci, timestep): PI= 3.141592654 contour=False firstval = ci.datafields.split(',')[0] #print ("First: ", firstval) if ((firstval == 'vo') or (firstval == 'qc') or (firstval == 'cvo') or (firstval == 'pcvo') or (firstval == 'qcc')): datafields = 'u' computation = firstval #We are doing a computation, so we need to know which one. if ((firstval == 'cvo') or (firstval == 'qcc') or (firstval == 'pcvo')): overlap = 3 #This was 2, but due to rounding because of the spacing, 3 is required. #Save a copy of the original request oci = jhtdblib.CutoutInfo() oci.xstart = ci.xstart oci.ystart = ci.ystart oci.zstart = ci.zstart oci.xlen = ci.xlen oci.ylen = ci.ylen oci.zlen = ci.zlen ci = self.expandcutout(ci, overlap) #Expand the cutout by the overlap contour = True else: datafields = ci.datafields.split(',') #There could be multiple components, so we will have to loop computation = '' #Split component into list and add them to the image #Check to see if we have a value for vorticity or q contour fieldlist = list(datafields) image = vtk.vtkImageData() rg = vtk.vtkRectilinearGrid() for field in fieldlist: if (ci.xlen > 61 and ci.ylen > +61 and ci.zlen > 61 and ci.xstep ==1 and ci.ystep ==1 and ci.zstep ==1 and not contour): #Do this if cutout is too large #Note: we don't want to get cubed data if we are doing cubes for contouring. data=GetData().getcubedrawdata(ci, timestep, field) else: data=GetData().getrawdata(ci, timestep, field) vtkdata = numpy_support.numpy_to_vtk(data.flat, deep=True, array_type=vtk.VTK_FLOAT) components = Datafield.objects.get(shortname=field).components vtkdata.SetNumberOfComponents(components) vtkdata.SetName(Datafield.objects.get(shortname=field).longname) #We need to see if we need to subtract one on end of extent edges. image.SetExtent(ci.xstart, ci.xstart+((ci.xlen+ci.xstep-1)/ci.xstep)-1, ci.ystart, ci.ystart+((ci.ylen+ci.ystep-1)/ci.ystep)-1, ci.zstart, ci.zstart+((ci.zlen+ci.zstep-1)/ci.zstep)-1) #image.SetExtent(ci.xstart, ci.xstart+int(ci.xlen)-1, ci.ystart, ci.ystart+int(ci.ylen)-1, ci.zstart, ci.zstart+int(ci.zlen)-1) image.GetPointData().AddArray(vtkdata) if (Datafield.objects.get(shortname=field).longname == "Velocity"): #Set the Velocity Array as vectors in the image. image.GetPointData().SetVectors(image.GetPointData().GetArray("Velocity")) #Get spacing from database and multiply it by the step. Don't do this on the contour--it is performed later on. #if (contour): #We need to scale the threshold to the spacing of the dataset. This is because we build the cubes #on a 1 spacing cube in order to get proper overlap on the contours. #ci.threshold = ci.threshold*Dataset.objects.get(dbname_text=ci.dataset).xspacing #else: xspacing = Dataset.objects.get(dbname_text=ci.dataset).xspacing yspacing = Dataset.objects.get(dbname_text=ci.dataset).yspacing zspacing = Dataset.objects.get(dbname_text=ci.dataset).zspacing #Check if we need a rectilinear grid, and set it up if so. if (ci.dataset == 'channel'): ygrid = jhtdblib.JHTDBLib().getygrid() #print("Ygrid: ") #print (ygrid) #Not sure about contouring channel yet, so we are going back to original variables at this point. rg.SetExtent(ci.xstart, ci.xstart+((ci.xlen+ci.xstep-1)/ci.xstep)-1, ci.ystart, ci.ystart+((ci.ylen+ci.ystep-1)/ci.ystep)-1, ci.zstart, ci.zstart+((ci.zlen+ci.zstep-1)/ci.zstep)-1) #components = Datafield.objects.get(shortname=field).components #vtkdata.SetNumberOfComponents(components) #vtkdata.SetName(Datafield.objects.get(shortname=field).longname) rg.GetPointData().AddArray(vtkdata) #import pdb;pdb.set_trace() #This isn't possible--we will have to do something about this in the future. #rg.SetSpacing(ci.xstep,ci.ystep,ci.zstep) xg = np.arange(0,2047.0) zg = np.arange(0,1535.0) for x in xg: xg[x] = 8*PI/2048*x for z in zg: zg[z] = 3*PI/2048*z vtkxgrid=numpy_support.numpy_to_vtk(xg, deep=True, array_type=vtk.VTK_FLOAT) vtkzgrid=numpy_support.numpy_to_vtk(zg, deep=True, array_type=vtk.VTK_FLOAT) vtkygrid=numpy_support.numpy_to_vtk(ygrid, deep=True, array_type=vtk.VTK_FLOAT) rg.SetXCoordinates(vtkxgrid) rg.SetZCoordinates(vtkzgrid) rg.SetYCoordinates(vtkygrid) image = rg #we rewrite the image since we may be doing a #computation below else: image.SetSpacing(xspacing*ci.xstep,yspacing*ci.ystep,zspacing*ci.zstep) #See if we are doing a computation if (computation == 'vo'): start = time.time() vorticity = vtk.vtkCellDerivatives() vorticity.SetVectorModeToComputeVorticity() vorticity.SetTensorModeToPassTensors() vorticity.SetInputData(image) #print("Computing Vorticity") vorticity.Update() end = time.time() comptime = end-start print("Vorticity Computation time: " + str(comptime) + "s") return image elif (computation == 'cvo' or computation == 'pcvo'): start = time.time() vorticity = vtk.vtkCellDerivatives() vorticity.SetVectorModeToComputeVorticity() vorticity.SetTensorModeToPassTensors() vorticity.SetInputData(image) #print("Computing Voricity") vorticity.Update() vend = time.time() comptime = vend-start print("Vorticity Computation time: " + str(comptime) + "s") mag = vtk.vtkImageMagnitude() cp = vtk.vtkCellDataToPointData() cp.SetInputData(vorticity.GetOutput()) #print("Computing magnitude") cp.Update() mend = time.time() image.GetPointData().SetScalars(cp.GetOutput().GetPointData().GetVectors()) mag.SetInputData(image) mag.Update() comptime = mend-vend print("Magnitude Computation time: " + str(comptime) + "s") c = vtk.vtkContourFilter() c.SetValue(0,ci.threshold) c.SetInputData(mag.GetOutput()) print("Computing Contour with threshold", ci.threshold) c.Update() cend = time.time() comptime = cend-mend print("Contour Computation time: " + str(comptime) + "s") #Now we need to clip out the overlap box = vtk.vtkBox() #set box to requested size #The OCI deepcopy didn't seem to work. Manually taking the overlap again. box.SetBounds(oci.xstart*xspacing, (oci.xstart+oci.xlen)*xspacing, oci.ystart*yspacing, (oci.ystart+oci.ylen)*yspacing, oci.zstart*yspacing,(oci.zstart+oci.zlen)*yspacing) clip = vtk.vtkClipPolyData() clip.SetClipFunction(box) clip.GenerateClippedOutputOn() clip.SetInputData(c.GetOutput()) clip.InsideOutOn() clip.Update() #import pdb;pdb.set_trace() cropdata = clip.GetOutput() #Cleanup image.ReleaseData() #mag.ReleaseData() #box.ReleaseData() #clip.ReleaseData() #image.Delete() #box.Delete() #vorticity.Delete() end = time.time() comptime = end-start print("Total Computation time: " + str(comptime) + "s") #return cropdata #We need the output port for appending, so return the clip instead return clip elif (computation == 'qcc'): start = time.time() q = vtk.vtkGradientFilter() q.SetInputData(image) q.SetInputScalars(image.FIELD_ASSOCIATION_POINTS,"Velocity") q.ComputeQCriterionOn() q.Update() image.GetPointData().SetScalars(q.GetOutput().GetPointData().GetVectors("Q-criterion")) #mag = vtk.vtkImageMagnitude() #mag.SetInputData(image) #mag.Update() mend = time.time() comptime = mend-start #print("Magnitude Computation time: " + str(comptime) + "s") c = vtk.vtkContourFilter() c.SetValue(0,ci.threshold) c.SetInputData(image) print("Computing Contour with threshold", ci.threshold) c.Update() cend = time.time() comptime = cend-mend print("Q Contour Computation time: " + str(comptime) + "s") #clip out the overlap here box = vtk.vtkBox() #set box to requested size box.SetBounds(oci.xstart, oci.xstart+oci.xlen-1, oci.ystart, oci.ystart+oci.ylen-1, oci.zstart,oci.zstart+oci.zlen-1) clip = vtk.vtkClipPolyData() clip.SetClipFunction(box) clip.GenerateClippedOutputOn() clip.SetInputData(c.GetOutput()) clip.InsideOutOn() clip.Update() cropdata = clip.GetOutput() end = time.time() comptime = end-start print("Computation time: " + str(comptime) + "s") #return cropdata return clip else: return image
def __init__(self, parent = None): super(VTKFrame, self).__init__(parent) self.vtkWidget = QVTKRenderWindowInteractor(self) vl = QtGui.QVBoxLayout(self) vl.addWidget(self.vtkWidget) vl.setContentsMargins(0, 0, 0, 0) self.ren = vtk.vtkRenderer() self.vtkWidget.GetRenderWindow().AddRenderer(self.ren) self.iren = self.vtkWidget.GetRenderWindow().GetInteractor() resolution = 10 sphere = vtk.vtkSphereSource() sphere.SetCenter(0.75, 0, 0) sphere.SetThetaResolution(resolution) sphere.SetPhiResolution(resolution) sphere.Update() # Add ids to the points and cells of the sphere cellIdFilter = vtk.vtkIdFilter() cellIdFilter.SetInputConnection(sphere.GetOutputPort()) cellIdFilter.SetCellIds(True) cellIdFilter.SetPointIds(False) cellIdFilter.SetIdsArrayName("CellIds") cellIdFilter.Update() pointIdFilter = vtk.vtkIdFilter() pointIdFilter.SetInputConnection(cellIdFilter.GetOutputPort()) pointIdFilter.SetCellIds(False) pointIdFilter.SetPointIds(True) pointIdFilter.SetIdsArrayName("PointIds") pointIdFilter.Update() sphereWithIds = pointIdFilter.GetOutput() cube = vtk.vtkCubeSource() cube.Update() implicitCube = vtk.vtkBox() implicitCube.SetBounds(cube.GetOutput().GetBounds()) clipper = vtk.vtkClipPolyData() clipper.SetClipFunction(implicitCube) clipper.SetInput(sphereWithIds) clipper.InsideOutOn() clipper.Update() # Create a mapper and actor for clipped sphere clippedMapper = vtk.vtkPolyDataMapper() clippedMapper.SetInputConnection(clipper.GetOutputPort()) clippedMapper.ScalarVisibilityOff() clippedActor = vtk.vtkActor() clippedActor.SetMapper(clippedMapper) clippedActor.GetProperty().SetRepresentationToWireframe() # Create a mapper and actor for the cube cubeMapper = vtk.vtkPolyDataMapper() cubeMapper.SetInputConnection(cube.GetOutputPort()) cubeActor = vtk.vtkActor() cubeActor.SetMapper(cubeMapper) cubeActor.GetProperty().SetRepresentationToWireframe() cubeActor.GetProperty().SetOpacity(0.5) #create renderers and add actors of plane and cube self.ren.AddActor(clippedActor) self.ren.AddActor(cubeActor) self.ren.SetBackground(0.2, 0.3, 0.4) self.ren.ResetCamera() self._initialized = False
# create pipeline # points = vtk.vtkBoundedPointSource() points.SetNumberOfPoints(NPts) points.SetBounds(-3, 3, -1, 1, -1, 1) points.ProduceRandomScalarsOn() points.ProduceCellOutputOff() points.Update() # Create a cylinder cyl = vtk.vtkCylinder() cyl.SetCenter(-2, 0, 0) cyl.SetRadius(0.02) # Create a (thin) box implicit function box = vtk.vtkBox() box.SetBounds(-1, 0.5, -0.5, 0.5, -0.0005, 0.0005) # Create a sphere implicit function sphere = vtk.vtkSphere() sphere.SetCenter(2, 0, 0) sphere.SetRadius(0.8) # Boolean (union) these together imp = vtk.vtkImplicitBoolean() imp.SetOperationTypeToUnion() imp.AddFunction(cyl) imp.AddFunction(box) imp.AddFunction(sphere) # Extract points along sphere surface
def __init__(self): vtkViewImage.__init__(self) self.FirstRender = 1 self.FirstImage = 1 self.ShowCurrentPoint = True self.ShowDirections = True self.ShowSliceNumber = True self.Orientation = vtkViewImage.AXIAL_ID self.InteractionStyle = self.SELECT_INTERACTION self.LeftButtonInteractionStyle = self.SELECT_INTERACTION self.MiddleButtonInteractionStyle = self.SELECT_INTERACTION self.RightButtonInteractionStyle = self.SELECT_INTERACTION self.WheelInteractionStyle = self.SELECT_INTERACTION self.Conventions = self.RADIOLOGIC self.InitialParallelScale = 1.0 self.OverlappingImage = None self.ImageReslice = vtk.vtkImageReslice() self.ImageActor = vtk.vtkImageActor() self.WindowLevelForCorner = vtk.vtkImageMapToWindowLevelColors() self.WindowLevel = vtk.vtkImageMapToColors() #self.MaskFilter = vtk.vtkImageBlendWithMask() self.Blender = vtk.vtkImageBlend() self.HorizontalLineSource = vtk.vtkLineSource() self.VerticalLineSource = vtk.vtkLineSource() self.HorizontalLineActor = vtk.vtkActor() self.VerticalLineActor = vtk.vtkActor() self.DataSetCutPlane = vtk.vtkPlane() self.DataSetCutBox = vtk.vtkBox() self.DataSetCutPlane.SetOrigin(0,0,0) self.DataSetCutPlane.SetNormal(0,0,1) self.DataSetCutBox.SetBounds(0, 0, 0, 0, 0, 0) self.BoxThickness = 2 self.LinkCameraFocalAndPosition = 0 # set the filters properties self.Blender.SetBlendModeToNormal() self.Blender.SetOpacity(0, 0.25) self.Blender.SetOpacity(1, 0.75) # set up the vtk pipeline self.ImageReslice.SetOutputDimensionality(2) self.ImageReslice.InterpolateOff() self.ImageReslice.SetInputConnection(self.WindowLevel.GetOutputPort()) self.AuxInput = self.WindowLevel.GetOutput() self.ResliceInput = self.WindowLevel.GetOutput() # Interactor Style self.InitInteractorStyle(self.SELECT_INTERACTION) # Initialize cursor lines mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(self.HorizontalLineSource.GetOutputPort()) self.HorizontalLineActor.SetMapper(mapper) self.HorizontalLineActor.GetProperty().SetColor(1.0, 0.0, 0.0) #del mapper self.HorizontalLineActor.SetVisibility(0) mapper2 = vtk.vtkPolyDataMapper() mapper2.SetInputConnection(self.VerticalLineSource.GetOutputPort()) self.VerticalLineActor.SetMapper(mapper2) self.VerticalLineActor.GetProperty().SetColor(1.0, 0.0, 0.0) #del mapper2 self.VerticalLineActor.SetVisibility(0) self.CornerAnnotation.SetWindowLevel(self.WindowLevelForCorner) self.SetOrientation(vtkViewImage.AXIAL_ID) if self.GetViewImage2DDisplayConventions() == 0: self.SetConventionsToRadiological() else: self.SetConventionsToNeurological()
Log("Filtering node set by depth.") visibleBoneVertices.ComputeBounds() visibleNodesBounds = visibleBoneVertices.GetBounds() Log("Bounds of visible bone nodes:", ("%.4f" + " %.4f" * 5) % visibleNodesBounds) #TODO #remove last few shaft slices in order to have flat surface boxBounds = (visibleNodesBounds[0], visibleNodesBounds[1], visibleNodesBounds[2], visibleNodesBounds[3], visibleNodesBounds[4], visibleNodesBounds[4] + 10) Log("Limiting to box bounds:", ("%.4f" + " %.4f" * 5) % boxBounds) box = vtk.vtkBox() box.SetBounds(boxBounds) filter = vtk.vtkExtractGeometry() filter.SetImplicitFunction(box) filter.ExtractInsideOn() filter.ExtractBoundaryCellsOn() filter.SetInput(0, visibleBoneVertices) filter.Update() filteredSurfaceVertices = filter.GetOutput() Log("Found %d nodes in bounding box." % filteredSurfaceVertices.GetNumberOfCells()) filteredSurfaceVertices.ComputeBounds() filteredSurfaceVerticesBounds = filteredSurfaceVertices.GetBounds() # Save to file so we can examine in ParaView, etc... depthFilteredBoneNodesFile = os.path.splitext(
def doWrap(Act,wc,wrap=[0.,360], fastClip=True): if wrap is None: return Act Mapper = Act.GetMapper() data = Mapper.GetInput() xmn=min(wc[0],wc[1]) xmx=max(wc[0],wc[1]) if numpy.allclose(xmn,1.e20) or numpy.allclose(xmx,1.e20): xmx = abs(wrap[1]) xmn = -wrap[1] ymn=min(wc[2],wc[3]) ymx=max(wc[2],wc[3]) if numpy.allclose(ymn,1.e20) or numpy.allclose(ymx,1.e20): ymx = abs(wrap[0]) ymn = -wrap[0] ## Prepare MultiBlock and puts in oriinal data appendFilter =vtk.vtkAppendPolyData() appendFilter.AddInputData(data) appendFilter.Update() ## X axis wrappping Amn,Amx = Act.GetXRange() if wrap[1]!=0.: i=0 while Amn>xmn: i+=1 Amn-=wrap[1] Tpf = vtk.vtkTransformPolyDataFilter() Tpf.SetInputData(data) T=vtk.vtkTransform() T.Translate(-i*wrap[1],0,0) Tpf.SetTransform(T) Tpf.Update() appendFilter.AddInputData(Tpf.GetOutput()) appendFilter.Update() i=0 while Amx<xmx: i+=1 Amx+=wrap[1] Tpf = vtk.vtkTransformPolyDataFilter() Tpf.SetInputData(data) T = vtk.vtkTransform() T.Translate(i*wrap[1],0,0) Tpf.SetTransform(T) Tpf.Update() appendFilter.AddInputData(Tpf.GetOutput()) appendFilter.Update() # Y axis wrapping Amn,Amx = Act.GetYRange() if wrap[0]!=0.: i=0 while Amn>ymn: i+=1 Amn-=wrap[0] Tpf = vtk.vtkTransformPolyDataFilter() Tpf.SetInputData(data) T = vtk.vtkTransform() T.Translate(0,i*wrap[0],0) Tpf.SetTransform(T) Tpf.Update() appendFilter.AddInputData(Tpf.GetOutput()) appendFilter.Update() i=0 while Amx<ymx: i+=1 Amx+=wrap[0] Tpf = vtk.vtkTransformPolyDataFilter() Tpf.SetInputData(data) T = vtk.vtkTransform() T.Translate(0,-i*wrap[0],0) Tpf.SetTransform(T) Tpf.Update() appendFilter.AddInputData(Tpf.GetOutput()) appendFilter.Update() # Clip the data to the final window: clipBox = vtk.vtkBox() clipBox.SetXMin(xmn, ymn, -1.0) clipBox.SetXMax(xmx, ymx, 1.0) if fastClip: clipper = vtk.vtkExtractPolyDataGeometry() clipper.ExtractInsideOn() clipper.SetImplicitFunction(clipBox) clipper.ExtractBoundaryCellsOn() clipper.PassPointsOff() else: clipper = vtk.vtkClipPolyData() clipper.InsideOutOn() clipper.SetClipFunction(clipBox) clipper.SetInputConnection(appendFilter.GetOutputPort()) clipper.Update() Mapper.SetInputData(clipper.GetOutput()) return Act
actorC.GetProperty().SetAmbient(1) actorR = vtk.vtkActor() actorR.SetMapper(mapperR) actorR.GetProperty().SetRepresentationToWireframe() actorR.GetProperty().SetAmbient(1) ren.AddActor(actorL) ren.AddActor(actorC) ren.AddActor(actorR) # Now clip boxes origin = [0,0,0] xout = [0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0] bds = [0,0, 0,0, 0,0] clipBox = vtk.vtkBox() # Left normal = [1,1,1] origin = boxL.GetCenter() pdL = vtk.vtkPolyData() polyL = vtk.vtkCellArray() ptsL = vtk.vtkPoints() pdL.SetPoints(ptsL) pdL.SetPolys(polyL) ptsL.SetDataTypeToDouble() boxL.GetBounds(bds) numInts = clipBox.IntersectWithPlane(bds, origin, normal, xout) print("Num ints: ", numInts) ptsL.SetNumberOfPoints(numInts) polyL.InsertNextCell(numInts)
def compute_box_func(self, normal, plane_pt, radius): '''Compute a implicit function for a bounding box. ''' v = 3 * [0.0] v[0] = vtk.vtkMath.Random(-10, 10) v[1] = vtk.vtkMath.Random(-10, 10) v[2] = vtk.vtkMath.Random(-10, 10) v1 = 3 * [0.0] vtk.vtkMath.Cross(normal, v, v1) vtk.vtkMath.Normalize(v1) v2 = 3 * [0.0] vtk.vtkMath.Cross(normal, v1, v2) matrix = vtk.vtkMatrix4x4() matrix.Identity() for i in range(3): matrix.SetElement(i, 0, normal[i]) matrix.SetElement(i, 1, v1[i]) matrix.SetElement(i, 2, v2[i]) sphere = vtk.vtkSphereSource() rscale = 2.0 sphere_center = [ plane_pt[i] + rscale * radius * normal[i] for i in range(3) ] sphere.SetCenter(sphere_center) sphere.SetRadius(rscale * radius) sphere.Update() bounds = 6 * [0.0] sphere.GetOutput().GetBounds(bounds) box_func = vtk.vtkBox() box_func.SetBounds(bounds) transform = vtk.vtkTransform() transform.Translate(sphere_center) #transform.Translate(plane_pt[0], plane_pt[1], plane_pt[2]) transform.Concatenate(matrix) transform.Scale(1.0, 1.0, 1.0) transform.Translate(-sphere_center[0], -sphere_center[1], -sphere_center[2]) #transform.Translate(-plane_pt[0], -plane_pt[1], -plane_pt[2]) transform.Update() inverse_transform = transform.GetInverse() #ipt = transform.TransformPoint(plane_pt) ipt = inverse_transform.TransformPoint(plane_pt) box_func.SetBounds(bounds) #box.SetTransform(transform) box_func.SetTransform(inverse_transform) cube = vtk.vtkCubeSource() cube.SetBounds(bounds) cube.Update() cube_pd = cube.GetOutput() transform_pd = vtk.vtkTransformPolyDataFilter() #transform = vtk.vtkTransform() #transform.Translate(plane_pt[0], plane_pt[1], plane_pt[2]) #transform.Scale(1.0, 1.0, 1.0) #transform_pd.SetTransform(inverse_transform); transform_pd.SetTransform(transform) transform_pd.SetInputData(cube_pd) transform_pd.Update() gr_geom = self.graphics.add_geometry(self.renderer, transform_pd.GetOutput(), color=[1.0, 0.0, 1.0]) gr_geom.GetProperty().SetRepresentationToWireframe() return box_func
def getvtkimage(self, webargs, timestep): #Setup query DBSTRING = os.environ['db_connection_string'] conn = pyodbc.connect(DBSTRING, autocommit=True) cursor = conn.cursor() #url = "http://localhost:8000/cutout/getcutout/"+ token + "/" + dataset + "/" + datafield + "/" + ts + "," +te + "/" + xs + "," + xe +"/" + ys + "," + ye +"/" + zs + "," + ze w = webargs.split("/") ts = int(w[3].split(',')[0]) te = int(w[3].split(',')[1]) xs = int(w[4].split(',')[0]) xe = int(w[4].split(',')[1]) ys = int(w[5].split(',')[0]) ye = int(w[5].split(',')[1]) zs = int(w[6].split(',')[0]) ze = int(w[6].split(',')[1]) extent = (xs, ys, zs, xe, ye, ze) overlap = 2 #Used only on contours--vorticity and Q-criterion #Look for step parameters if (len(w) > 9): step = True; s = w[8].split(",") tstep = s[0] xstep = float(s[1]) ystep = float(s[2]) zstep = float(s[3]) filterwidth = w[9] else: step = False; xstep = 1 ystep = 1 zstep = 1 filterwidth = 1 cfieldlist = w[2].split(",") firstval = cfieldlist[0] maxrange = self.getmaxrange(w[1]) if ((firstval == 'vo') or (firstval == 'qc') or (firstval == 'cvo') or (firstval == 'qcc')): component = 'u' computation = firstval #We are doing a computation, so we need to know which one. #check to see if we have a threshold (only for contours) if (len(cfieldlist) > 1): threshold = float(cfieldlist[1]) else: threshold = .6 #New: We need an expanded cutout if contouring. Push the cutout out by 2 in all directions (unless at boundary). if ((firstval == 'cvo') or (firstval == 'qcc')): newextent = self.expandcutout(extent, maxrange[0], maxrange[1], maxrange[2], overlap) contour = True else: component = w[2] #There could be multiple components, so we will have to loop computation = '' #Split component into list and add them to the image #Check to see if we have a value for vorticity or q contour fieldlist = list(component) for field in fieldlist: print("Field = %s" % field) cursor.execute("{CALL turbdev.dbo.GetAnyCutout(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)}",w[1], field, timestep, extent[0], extent[1], extent[2], xstep, ystep, zstep, 1,1,extent[3], extent[4], extent[5],filterwidth,1) #If data spans across multiple servers, we get multiple sets, so concatenate them. row = cursor.fetchone() raw = row[0] part = 0 print ("First part size is %d" % len(row[0])) while(cursor.nextset()): row = cursor.fetchone() raw = raw + row[0] part = part +1 print ("added part %d" % part) print ("Part size is %d" % len(row[0])) print ("Raw size is %d" % len(raw)) data = np.frombuffer(raw, dtype=np.float32) conn.close() vtkdata = numpy_support.numpy_to_vtk(data, deep=True, array_type=vtk.VTK_FLOAT) components = self.numcomponents(field) vtkdata.SetNumberOfComponents(components) vtkdata.SetName(self.componentname(field)) image = vtk.vtkImageData() if (step): xes = int(extent[3])/int(xstep)-1 yes = int(extent[4])/int(ystep)-1 zes = int(extent[5])/int(zstep)-1 image.SetExtent(extent[0], extent[0]+extent[3], extent[1], extent[1]+extent[4], extent[2], extenet[2]+extenet[5]) print("Step extent=" +str(xes)) print("xs=" + str(xstep) + " ys = "+ str(ystep) +" zs = " + str(zstep)) else: image.SetExtent(extent[0], extent[0]+extent[3]-1, extent[1], extent[1]+extent[4]-1, extent[2], extent[2]+extent[5]-1) image.GetPointData().SetVectors(vtkdata) if (step): #Magnify to original size image.SetSpacing(xstep,ystep,zstep) #Check if we need a rectilinear grid, and set it up if so. if (w[1] == 'channel'): ygrid = self.getygrid() #print("Ygrid: ") #print (ygrid) rg = vtk.vtkRectilinearGrid() #Not sure about contouring channel yet, so we are going back to original variables at this point. rg.SetExtent(xs, xs+xe-1, ys, ys+ye-1, zs, zs+ze-1) rg.GetPointData().SetVectors(vtkdata) xg = np.arange(float(xs),float(xe)) zg = np.arange(float(zs),float(ze)) for x in xg: xg[x] = 8*3.141592654/2048*x for z in zg: zg[z] = 3*3.141592654/2048*z vtkxgrid=numpy_support.numpy_to_vtk(xg, deep=True, array_type=vtk.VTK_FLOAT) vtkzgrid=numpy_support.numpy_to_vtk(zg, deep=True, array_type=vtk.VTK_FLOAT) vtkygrid=numpy_support.numpy_to_vtk(ygrid, deep=True, array_type=vtk.VTK_FLOAT) rg.SetXCoordinates(vtkxgrid) rg.SetZCoordinates(vtkzgrid) rg.SetYCoordinates(vtkygrid) image = rg #we rewrite the image since we may be doing a #computation below #See if we are doing a computation if (computation == 'vo'): vorticity = vtk.vtkCellDerivatives() vorticity.SetVectorModeToComputeVorticity() vorticity.SetTensorModeToPassTensors() vorticity.SetInputData(image) print("Computing Vorticity") vorticity.Update() elif (computation == 'cvo'): vorticity = vtk.vtkCellDerivatives() vorticity.SetVectorModeToComputeVorticity() vorticity.SetTensorModeToPassTensors() vorticity.SetInputData(image) print("Computing Voricity") vorticity.Update() mag = vtk.vtkImageMagnitude() cp = vtk.vtkCellDataToPointData() cp.SetInputData(vorticity.GetOutput()) print("Computing magnitude") cp.Update() image.GetPointData().SetScalars(cp.GetOutput().GetPointData().GetVectors()) mag.SetInputData(image) mag.Update() c = vtk.vtkContourFilter() c.SetValue(0,threshold) c.SetInputData(mag.GetOutput()) print("Computing Contour") c.Update() #Now we need to clip out the overlap box = vtk.vtkBox() #set box to requested size box.SetBounds(xs, xs+xe-1, ys, ys+ye-1, zs,zs+ze-1) clip = vtk.vtkClipPolyData() clip.SetClipFunction(box) clip.GenerateClippedOutputOn() clip.SetInputData(c.GetOutput()) clip.InsideOutOn() clip.Update() cropdata = clip.GetOutput() return cropdata elif (computation == 'qcc'): q = vtk.vtkGradientFilter() q.SetInputData(image) q.SetInputScalars(image.FIELD_ASSOCIATION_POINTS,"Velocity") q.ComputeQCriterionOn() q.Update() #newimage = vtk.vtkImageData() image.GetPointData().SetScalars(q.GetOutput().GetPointData().GetVectors("Q-criterion")) mag = vtk.vtkImageMagnitude() mag.SetInputData(image) mag.Update() c = vtk.vtkContourFilter() c.SetValue(0,threshold) c.SetInputData(mag.GetOutput()) c.Update() #clip out the overlap here box = vtk.vtkBox() #set box to requested size box.SetBounds(xs, xs+xe-1, ys, ys+ye-1, zs,zs+ze-1) clip = vtk.vtkClipPolyData() clip.SetClipFunction(box) clip.GenerateClippedOutputOn() clip.SetInputData(c.GetOutput()) clip.InsideOutOn() clip.Update() cropdata = clip.GetOutput() return cropdata else: return image
except urllib2.HTTPError, e: #print("Error: %s" % (e.reason)) print("Download failed, trying again") attempts +=1 # check if file downloaded ok if attempts == 2: print("Too many retries. Network error or URL issue.") raise else: print("Cropping") #Crop out the overlap reader = vtk.vtkXMLPolyDataReader() reader.SetFileName("temp" +filename + '.vtp') reader.Update() polydata = reader.GetOutput() box = vtk.vtkBox() #set box to requested size box.SetBounds(x0, x0+xl-1, y0, y0+yl-1, z0,z0+zl-1) clip = vtk.vtkClipPolyData() clip.SetClipFunction(box) clip.GenerateClippedOutputOn() clip.SetInputData(polydata) clip.InsideOutOn() clip.Update() cropdata = clip.GetOutput() writer = vtk.vtkXMLPolyDataWriter() writer.SetFileName(filename + '-clip.vtp') writer.SetInputData(cropdata) writer.Write() #Remove temp file os.remove("temp" + filename + ".vtp")
def getcachedcontour(self, ci, timestep): #This is only called on qcc or cvo #cube size should be 256 or 512 for production, using 16 for testing. cubedimension = 256 fullcubesize = [math.ceil(float(ci.xlen)/float(cubedimension))*cubedimension, math.ceil(float(ci.ylen)/float(cubedimension))*cubedimension, math.ceil(float(ci.zlen)/float(cubedimension))*cubedimension] #print ("Full poly mesh cube size is: ", fullcubesize) #The corner of the cube must be a multiple of the cubedimension. corner = [ci.xstart-ci.xstart%cubedimension, ci.ystart-ci.xstart%cubedimension, ci.zstart-ci.xstart%cubedimension] cubesize = [cubedimension, cubedimension, cubedimension] #We will try to get cached data, or we will use getvtkdata if we miss. vtkdata does the overlap, so we don't worry about it here. start = time.time() cornermap = [] fullcube = vtk.vtkAppendPolyData() args = [] cubecount = 0 for xcorner in range (ci.xstart-ci.xstart%cubedimension,ci.xstart + ci.xlen, cubedimension): for ycorner in range (ci.ystart-ci.ystart%cubedimension,ci.ystart + ci.ylen, cubedimension): for zcorner in range (ci.zstart-ci.zstart%cubedimension,ci.zstart + ci.zlen, cubedimension): #cornermap.append([xcorner, ycorner, zcorner]) cubecount = cubecount+1 args.append([xcorner, ycorner, zcorner, ci, cubedimension,timestep]) #output = self.buildcube(corners, ci, cubedimension, timestep) #fullcube.AddInputConnection(output.GetOutputPort()) #Create a process pool for each cube #print ("Numcubes: ", cubecount) if (cubecount > 8): cubecount = 8 #limit to only 8 processes p = Pool(cubecount) #print("Pool created..mapping args", args) #connection.close() cubelist = p.map(self.buildcube, args) #p.join() #wait for processes to finish for filename in cubelist: r = vtk.vtkXMLPolyDataReader() r.SetFileName(filename) #r.Update() fullcube.AddInputConnection(r.GetOutputPort()) #print("Added:", filename) connection.close() #cleanup processes #p = None p.close() #free up the ram #cubelist = None end = time.time() comptime = end-start print("Final Computation time: " + str(comptime) + "s") print("Done processing.") xspacing = Dataset.objects.get(dbname_text=ci.dataset).xspacing yspacing = Dataset.objects.get(dbname_text=ci.dataset).yspacing zspacing = Dataset.objects.get(dbname_text=ci.dataset).zspacing box = vtk.vtkBox() box.SetBounds(ci.xstart*xspacing, (ci.xstart+ci.xlen-1)*xspacing, ci.ystart*yspacing, (ci.ystart+ci.ylen-1)*yspacing, ci.zstart*zspacing, (ci.zstart + ci.zlen-1)*zspacing) fullcube.Update() clip = vtk.vtkClipPolyData() clip.SetClipFunction(box) clip.GenerateClippedOutputOn() fco = fullcube.GetOutput() fco.GetPointData().SetScalars(fco.GetPointData().GetArray("Velocity")) clip.SetInputData(fco) clip.InsideOutOn() clip.Update() #print clip.GetOutput() #print("Cleaning cube (removing duplicate points)") clean = vtk.vtkCleanPolyData() clean.SetInputConnection(clip.GetOutputPort()) clean.Update() #Try to cleanup! clip = None fullcube = None box = None return clean.GetOutput()