-
Adrien Crovato authoredAdrien Crovato authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
cutter.py 3.50 KiB
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2020 University of Liège
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# @brief VTK cut plane post-processing
# @authors Adrien Crovato, Kim Liegeois
try:
import vtk
except:
raise Exception('VTK not found. Aborting!\n')
class Cutter:
def __init__(self, _grid):
self.grid = _grid
def cut(self, tag, cutO, cutN, tag_name="tag"):
"""Cut the physical group ided "tag" with a plane defined by point "cutO" and normal "cutN"
"""
# create a threshold containing the physical group (tag) to cut
thresh = vtk.vtkThreshold()
thresh.SetLowerThreshold(tag)
thresh.SetUpperThreshold(tag)
thresh.SetInputConnection(self.grid)
thresh.SetInputArrayToProcess(0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS, tag_name) # "tag" is the default name set in tboxVtk::VtkExport::save
thresh.Update()
# create cutting plane
plane = vtk.vtkPlane()
plane.SetOrigin(cutO[0], cutO[1], cutO[2])
plane.SetNormal(cutN[0], cutN[1], cutN[2])
# cut the threshold and get data
cutter = vtk.vtkCutter()
cutter.SetCutFunction(plane)
cutter.SetInputConnection(thresh.GetOutputPort())
cutter.Update()
return cutter.GetOutput()
def extract(self, cutData, tagDim, vname, atPoint = True):
"""Extract points "pts", connectivity list "elems" and data "vals" named "vname" from cutting plane data "cutData".
The physical group dimension is given by "tagDim" and "atPoint" is True if vname is defined at points.
"""
import numpy as np
# transfer point coordinates
_pts = cutData.GetPoints()
pts = np.zeros((_pts.GetNumberOfPoints(), 3))
for i in range(0, pts.shape[0]):
for j in range(0, 3):
pts[i][j] = _pts.GetPoint(i)[j]
# transfer connectivity
if tagDim == 3:
_elems = cutData.GetPolys().GetData()
nV = 3 # assumes that all Poly(gon)s are triangles
elif tagDim == 2:
_elems = cutData.GetLines().GetData()
nV = 2
else:
raise Exception('tagDim can only be 2 or 3 but ' + tagDim + ' was given!\n')
elems = np.zeros((_elems.GetNumberOfTuples() // (nV+1), nV), dtype=int)
for i in range(0, elems.shape[0]):
for j in range(0, nV):
elems[i][j] = _elems.GetTuple((nV+1)*i+j+1)[0]
# transfer variables
vals = {}
for name in vname:
if atPoint: # data at points
_vals = cutData.GetPointData().GetArray(name)
else: # data at elements
_vals = cutData.GetCellData().GetArray(name)
vals[name] = np.zeros((_vals.GetNumberOfTuples(), _vals.GetNumberOfComponents()))
for i in range(0, vals[name].shape[0]):
for j in range(0, vals[name].shape[1]):
vals[name][i][j] = _vals.GetTuple(i)[j]
return pts, elems, vals