From cd2ca05de15745cf285915d7b61e9e93b8cdfaa0 Mon Sep 17 00:00:00 2001 From: Wxwei <12221108@zju.edu.cn> Date: Sun, 29 Oct 2023 14:41:12 +0000 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=96=87=E4=BB=B6=E8=87=B3?= =?UTF-8?q?=20'Visualization'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Visualization/ConstrainedOpt.py | 19 ++ Visualization/application.py | 14 ++ Visualization/gui_main.py | 354 ++++++++++++++++++++++++++++++++ Visualization/gui_main.pyc | Bin 0 -> 10860 bytes Visualization/gui_viewer.py | 312 ++++++++++++++++++++++++++++ 5 files changed, 699 insertions(+) create mode 100644 Visualization/ConstrainedOpt.py create mode 100644 Visualization/application.py create mode 100644 Visualization/gui_main.py create mode 100644 Visualization/gui_main.pyc create mode 100644 Visualization/gui_viewer.py diff --git a/Visualization/ConstrainedOpt.py b/Visualization/ConstrainedOpt.py new file mode 100644 index 0000000..4d0e5f2 --- /dev/null +++ b/Visualization/ConstrainedOpt.py @@ -0,0 +1,19 @@ +from PyQt5.QtCore import * + +class ConstrainedOpt(QThread): + signal_update_voxels = pyqtSignal(str) + + def __init__(self, model,index): + QThread.__init__(self) + self.model = model['model'] + # self.model = model + self.name = model['name'] + + self.index = index + + def run(self): +# while True: + self.update_voxel_model() + + def update_voxel_model(self): + self.signal_update_voxels.emit('update_voxels') \ No newline at end of file diff --git a/Visualization/application.py b/Visualization/application.py new file mode 100644 index 0000000..1d7cb94 --- /dev/null +++ b/Visualization/application.py @@ -0,0 +1,14 @@ +import sys +import qdarkstyle +from gui_main import MainWindow +from PyQt5.QtWidgets import * + +if __name__ == "__main__": + app = QApplication(sys.argv) + desktopWidget = QApplication.desktop() + screenRect = desktopWidget.screenGeometry() + app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5()) + window = MainWindow(screenRect.width(),screenRect.height()) + window.setWindowTitle("model_view") + window.show() + sys.exit(app.exec_()) diff --git a/Visualization/gui_main.py b/Visualization/gui_main.py new file mode 100644 index 0000000..416cbfc --- /dev/null +++ b/Visualization/gui_main.py @@ -0,0 +1,354 @@ +import os +import scipy.io as sio + +from gui_viewer import * +from ConstrainedOpt import ConstrainedOpt + +from PyQt5.QtWidgets import * +from PyQt5.QtCore import * +from PyQt5.QtGui import * + +import sys +import qdarkstyle + +class MySubWindow(QMdiSubWindow): + signal_save_image = pyqtSignal(str) + +class MainWindow(QMainWindow): + signal_save_images = pyqtSignal(str) + signal_setCamera = pyqtSignal(float, float, float) + + def __init__(self, width, height, parent=None): + QMainWindow.__init__(self, parent) + self.width = width + self.height = height + self.resize(width, height) + self.mdi_Area = QMdiArea() + self.mdi_Area.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) + self.mdi_Area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) + + self.camerax = 0 + self.cameray = 0 + self.cameraz = 0 + + self.files = list() + self.models = list() + self.models_count = 0 + + self.setCentralWidget(self.mdi_Area) + + self.mdi_Win = list() + self.frame = list() + self.viewerWidget = list() + + self.banch = 8 + self.current_index = -1 + + self.file_ind = 0 + + # create openAction + openAction = QAction("&Open", self) + openAction.setShortcut(QKeySequence.Open) + openAction.setToolTip("Open files") + openAction.setStatusTip("Open files") + openAction.triggered.connect(self.open_file) + + openoneAction = QAction("&Openone", self) + openoneAction.setShortcut(QKeySequence.Open) + openoneAction.setToolTip("Open a file") + openoneAction.setStatusTip("Open a file") + openoneAction.triggered.connect(self.open_one_file) + + # preAction = QAction("&PreGroup", self) + # preAction.setShortcut(QKeySequence.Open) + # preAction.setToolTip("Show pre group model") + # preAction.setStatusTip("Show pre group model") + # preAction.triggered.connect(self.pre_group) + # # self.connect(preAction, SIGNAL("triggered()"), self.pre_group) + + nextAction = QAction("&NextGroup", self) + nextAction.setShortcut(QKeySequence.Open) + nextAction.setToolTip("Show next group model") + nextAction.setStatusTip("Show next group model") + nextAction.triggered.connect(self.next_group) + + saveAction = QAction("&SaveAll", self) + saveAction.setShortcut(QKeySequence.Open) + saveAction.setToolTip("Save all models as Image") + saveAction.setStatusTip("Save all models as Image") + saveAction.triggered.connect(self.save_group) + + saveOneAction = QAction("&SaveCurrent", self) + saveOneAction.setShortcut(QKeySequence.Open) + saveOneAction.setToolTip("Save current model") + saveOneAction.setStatusTip("Save current model") + saveOneAction.triggered.connect(self.save_one) + + # create toolbar + toolbar = self.addToolBar("tool") + toolbar.setMovable(False) + toolbar.setObjectName("ToolBar") + toolbar.addAction(openAction) + toolbar.addAction(openoneAction) + toolbar.addAction(nextAction) + toolbar.addAction(saveAction) + toolbar.addAction(saveOneAction) + + # toolbar.addAction(preAction) + + def closeEvent(self, event): + for i in range(len(self.mdi_Win)): + self.mdi_Win[i].opt_engine.quit() + + def open_all_file_for_model(self, file_name): + mat_list = [] + dir_name = "" + for i in range (5): + file_path = dir_name + file_name + "_" + str(i) + ".mat" + data = sio.loadmat(file_path) + mat_list.append(data) + + + def get_object_model(self, dir_path): + mat_file_list = [] + transform_file_list = [] + for file_name in os.listdir(dir_path): + if file_name.endswith('.mat'): + mat_file_list.append(file_name) + elif file_name.endswith('.txt'): + transform_file_list.append(file_name) + + if len(mat_file_list) != len(transform_file_list): + raise KeyError("The number of mat files don't match the number of transform files") + + label_list = [] + for mat_file in mat_file_list: + cur_label = mat_file[-5: -4] + label_list.append(cur_label) + + if len(mat_file_list[0]) == 5 and mat_file_list[0][0].isdigit(): + testing_samples = True + else: + testing_samples = False + + models = [] + cur_file_name = mat_file_list[0][0:-6] + for cur_label in label_list: + c_label = int(cur_label) + + if testing_samples: + current_mat_file_name = "%d.mat" % (c_label) + current_transform_file_name = "%d_transform_info.txt" % (c_label) + else: + current_transform_file_name = "%s_%d_transform_info.txt" % (cur_file_name, c_label) + current_mat_file_name = "%s_%d.mat" % (cur_file_name, c_label) + + part_name = "%s_%d" % (cur_file_name, c_label) + + current_mat_file_path = "%s/%s" % (dir_path, current_mat_file_name) + current_transform_file_path = "%s/%s" % (dir_path, current_transform_file_name) + + file = open(current_transform_file_path, 'r') + + is_bbox_vector = False + is_min_max_value = False + + file_lines = file.readlines() + for line in file_lines: + if line == "\r\n": + is_bbox_vector = False + is_min_max_value = False + continue + if line.find("vector for representation") != -1: + is_min_max_value = True + is_bbox_vector = False + continue + if line.find("Min_Max Value") != -1: + is_bbox_vector = False + is_min_max_value = True + continue + if is_bbox_vector: + value_list = line.split(' ') + if is_min_max_value: + line = line.strip() + line = line.strip(' \t\n\r') + value_list = line.split(' ') + break + + translate_vector = [float(value_list[0]), float(value_list[1]), float(value_list[2])] + + value_list[3] = abs(float(value_list[3])) + value_list[4] = abs(float(value_list[4])) + value_list[5] = abs(float(value_list[5])) + + min_max_value_list = [(float(value_list[0]) - float(value_list[3]) / 2), + (float(value_list[1]) - float(value_list[4]) / 2), + (float(value_list[2]) - float(value_list[5]) / 2), + (float(value_list[0]) + float(value_list[3]) / 2), + (float(value_list[1]) + float(value_list[4]) / 2), + (float(value_list[2]) + float(value_list[5]) / 2)] + + # These three values represent the length, width, height of a bounding box + dim_list = [float(value_list[3]), float(value_list[4]), float(value_list[5])] + + mat_data = sio.loadmat(current_mat_file_path) + array = mat_data['voxels3D'] + model = {'name': part_name, 'model': array, 'translate_vector': translate_vector, + 'dim_vecetor': dim_list, 'min_max_value': min_max_value_list} + models.append(model) + + model_dict = {'name': cur_file_name, 'model': models} + # self.models.append(model_dict) + + return model_dict + + def open_one_file(self): + self.models_count = 0 + dir_ = QFileDialog.getExistingDirectory(None, 'Select a folder:', '.', QFileDialog.ShowDirsOnly) + self.files.append(dir_) + + model_dict = self.get_object_model(dir_) + self.models.append(model_dict) + self.models_count = 1 + self.current_index = self.current_index + 1 + self.banch = 1 + self.view_model() + + def open_file(self): + self.banch = 8 + self.models_count = 0 + dir_ = QFileDialog.getExistingDirectory(None, 'Select a folder:', '.', QFileDialog.ShowDirsOnly) + for filename in os.listdir(dir_): + self.files.append(dir_ + '/' + filename) + obj_names = [f_path for f_path in os.listdir(dir_) if os.path.isdir(os.path.join(dir_, f_path))] + obj_names.sort() + + # fileList contains all the file pathes beyond a certain category + obj_file_pathes = [os.path.join(dir_, f_path) for f_path in obj_names if os.path.isdir(os.path.join(dir_, f_path))] + self.files = obj_file_pathes + + if obj_names[0].find('iter_') != -1: + def key_word(item): + return int(item.split('_')[-1]) + + self.files.sort(key=key_word) + + for idx in range(0, self.banch): + if (len(self.files) > 0): + obj_file_path = self.files.pop() + obj_file_path = obj_file_path.strip(' \t\n\r') + print( 'current path: ' + obj_file_path) + model_dict = self.get_object_model(obj_file_path) + self.models.append(model_dict) + self.models_count = self.models_count + 1 + + self.current_index = 0 + self.banch = self.models_count + self.view_model() + + # TODO This function is important + def view_model(self): + start = self.current_index + banch = self.banch + end = start + banch + + width = (self.width * 2 / 8) * 0.95 + height = (self.height / 2) * 0.95 + mainWidth = width + 10 + mainHeight = height + 10 + self.setWindowTitle("model_view models_count:" + str(len(self.files))) + + for index in range(start, end): + if (len(self.models) <= 0): + break + # Obtain one new model to display + model = self.models.pop() + # Update the number of models to show + self.models_count = self.models_count - 1 + # Add one more sub-frame to the main window + self.frame.append(QFrame()) + self.mdi_Win.append(MySubWindow()) + self.mdi_Win[index].opt_engine = ConstrainedOpt(model, index) + self.mdi_Win[index].setWindowTitle("model_" + model['name']) + self.mdi_Win[index].setGeometry(0, 0, mainWidth, mainHeight) + + self.viewerWidget.append( + GUIViewer(self.frame[index], self.mdi_Win[index].opt_engine)) + self.viewerWidget[index].resize(width, height) + + viewerBox = QVBoxLayout() + viewerBox.addWidget(self.viewerWidget[index]) + self.frame[index].setLayout(viewerBox) + self.mdi_Win[index].setWidget(self.frame[index]) + + self.viewerWidget[index].interactor.Initialize() + + self.mdi_Win[index].opt_engine.signal_update_voxels.connect(self.viewerWidget[index].update_actor) + self.mdi_Win[index].signal_save_image.connect(self.viewerWidget[index].save_image2) + self.signal_save_images.connect(self.viewerWidget[index].save_image1) + + self.mdi_Win[index].opt_engine.start() + self.mdi_Area.addSubWindow(self.mdi_Win[index]) + self.mdi_Win[index].show() + print('success') + + # def pre_group(self): + # self.current_index = self.current_index - self.banch + # if self.current_index < 0: + # self.current_index = 0 + # for i in range(len(self.mdi_Win)): + # self.mdi_Win[i].close() + # self.mdi_Win[:] = [] + # self.frame[:] = [] + # self.viewerWidget[:] = [] + # self.view_model() + # # self.models_count = 0 + + def next_group(self): + self.banch = 8 + for i in range(len(self.mdi_Win)): + self.mdi_Win[i].close() + self.mdi_Win[:] = [] + self.frame[:] = [] + self.viewerWidget[:] = [] + self.models[:] = [] + + for idx in range(0, self.banch): + if (len(self.files) > 0): + file_path = self.files.pop() + print( 'current path: ' + file_path) + file_path = file_path.strip(' \t\n\r') + model_dict = self.get_object_model(file_path) + self.models.append(model_dict) + self.models_count = 1 + self.models_count + + self.current_index = 0 + self.banch = self.models_count + self.view_model() + + def save_group(self): + file_path = QFileDialog.getExistingDirectory(self, "Open a folder", ".", QFileDialog.ShowDirsOnly) + self.signal_save_images.emit(file_path) + + def save_one(self): + self.mdi_Area.currentSubWindow().signal_save_image.emit('save_image') + + def setCamera(self): + self.camerax = float(unicode(self.valuex.text())) + self.cameray = float(unicode(self.valuey.text())) + self.cameraz = float(unicode(self.valuez.text())) + valuex = self.camerax + valuey = self.cameray + valuez = self.cameraz + self.signal_setCamera.emit(valuex, valuey, valuez) + + +if __name__ == "__main__": + app = QApplication(sys.argv) + desktopWidget = QApplication.desktop() + screenRect = desktopWidget.screenGeometry() + app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5()) + window = MainWindow(screenRect.width(),screenRect.height()) + window.setWindowTitle("model_view") + window.show() + sys.exit(app.exec_()) diff --git a/Visualization/gui_main.pyc b/Visualization/gui_main.pyc new file mode 100644 index 0000000000000000000000000000000000000000..afa68c103ee3e6b74cd0f570dc8959b572308745 GIT binary patch literal 10860 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 literal 0 HcmV?d00001 diff --git a/Visualization/gui_viewer.py b/Visualization/gui_viewer.py new file mode 100644 index 0000000..314eeef --- /dev/null +++ b/Visualization/gui_viewer.py @@ -0,0 +1,312 @@ +import vtk +from PyQt5.QtWidgets import * +# import PyQt5 +from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor + +class Color: + def __init__(self, r, g, b, alpha): + self.r = r + self.g = g + self.b = b + self.a = alpha + +class GUIViewer(QVTKRenderWindowInteractor): + def __init__(self, parent, engine): + QVTKRenderWindowInteractor.__init__(self, parent) + + self.part_num = 0 + self.part_list = [] + self.point_list = [] + self.color_list = [] + self.glyph3D_list = [] + + self.engine = engine + self.resetCamera = True + self.renderer = vtk.vtkRenderer() + self.GetRenderWindow().AddRenderer(self.renderer) + self.interactor = self.GetRenderWindow().GetInteractor() + self.create_actor() + + self.renderer.SetBackground(255, 255, 255) + camera = self.renderer.GetActiveCamera() + camera.SetViewUp(0.5, 0, 0) + camera.SetPosition(0.1245, 0.1139, 0.2932) + self.renderer.SetActiveCamera(camera) + + transform = vtk.vtkTransform() + transform.Translate(0.0, 0.0, 0.0) + + axes = vtk.vtkAxesActor() + # The axes are positioned with a user transform + axes.SetUserTransform(transform) + + + def create_voxel(self): + numberOfVertices = 8 + + points = vtk.vtkPoints() + points.InsertNextPoint(0, 0, 0) + points.InsertNextPoint(1, 0, 0) + points.InsertNextPoint(0, 1, 0) + points.InsertNextPoint(1, 1, 0) + points.InsertNextPoint(0, 0, 1) + points.InsertNextPoint(1, 0, 1) + points.InsertNextPoint(0, 1, 1) + points.InsertNextPoint(1, 1, 1) + + voxel = vtk.vtkVoxel() + for i in range(0, numberOfVertices): + voxel.GetPointIds().SetId(i, i) + + ugrid = vtk.vtkUnstructuredGrid() + ugrid.SetPoints(points) + ugrid.InsertNextCell(voxel.GetCellType(), voxel.GetPointIds()) + + gfilter = vtk.vtkGeometryFilter() + gfilter.SetInputData(ugrid) + gfilter.Update() + return gfilter + + def create_actor(self): + self.part_num = len(self.engine.model) + for i in range(self.part_num): + # Set up point_list and color_list + self.point_list.append(vtk.vtkPoints()) + self.color_list.append(vtk.vtkUnsignedCharArray()) + self.color_list[i].SetName("colors") + self.color_list[i].SetNumberOfComponents(4) + + # Create polydata by setting up points information and color information + polydata = vtk.vtkPolyData() + polydata.SetPoints(self.point_list[i]) + polydata.GetPointData().SetScalars(self.color_list[i]) + + # create cell + voxel = self.create_voxel() + + # Set up Glyph3D data representation: color, data representation form, input data and et. + self.glyph3D_list.append(vtk.vtkGlyph3D()) + self.glyph3D_list[i].SetColorModeToColorByScalar() + # self.glyph3D_list[i].SetSource(voxel.GetOutput()) # Set up data representation form + self.glyph3D_list[i].SetSourceConnection(voxel.GetOutputPort()) # Set up data representation form + # self.glyph3D_list[i].SetInput(polydata) # Set input data + self.glyph3D_list[i].SetInputData(polydata) # Set input data + self.glyph3D_list[i].ScalingOff() + self.glyph3D_list[i].Update() + + # mapper + mapper = vtk.vtkPolyDataMapper() + # mapper.SetInput(self.glyph3D_list[i].GetOutput()) + mapper.SetInputConnection(self.glyph3D_list[i].GetOutputPort()) + + # actor + actor = vtk.vtkActor() + actor.SetMapper(mapper) + actor.GetProperty() + self.renderer.AddActor(actor) + self.part_list.append(actor) + + transform = vtk.vtkTransform() + transform.Translate(0.0, 0.0, 0.0) + axes = vtk.vtkAxesActor() + # The axes are positioned with a user transform + axes.SetUserTransform(transform) + + # the actual text of the axis label can be changed: + axes.SetXAxisLabelText("") + axes.SetYAxisLabelText("") + axes.SetZAxisLabelText("") + + # self.renderer.AddActor(axes) + + def set_bb_color(self, model, ind, n, x_zero_index, y_zero_index, z_zero_index, r, g, b): + # alpha = 255 + alpha = 173 + for i in range(len(model[0])): + self.point_list[ind].InsertNextPoint(0 - x_zero_index, 0 - y_zero_index, i - z_zero_index) + self.color_list[ind].InsertTuple4(n, r, g, b, alpha) + n = n + 1 + + self.point_list[ind].InsertNextPoint(0 - x_zero_index, len(model[0]) - y_zero_index, i - z_zero_index) + self.color_list[ind].InsertTuple4(n, r, g, b, alpha) + n = n + 1 + + self.point_list[ind].InsertNextPoint(len(model[0]) - x_zero_index, 0 - y_zero_index, i - z_zero_index) + self.color_list[ind].InsertTuple4(n, r, g, b, alpha) + n = n + 1 + + self.point_list[ind].InsertNextPoint(len(model[0]) - x_zero_index, len(model[0]) - y_zero_index, + i - z_zero_index) + self.color_list[ind].InsertTuple4(n, r, g, b, alpha) + n = n + 1 + + self.point_list[ind].InsertNextPoint(0 - x_zero_index, i - y_zero_index, 0 - z_zero_index) + self.color_list[ind].InsertTuple4(n, r, g, b, alpha) + n = n + 1 + + self.point_list[ind].InsertNextPoint(0 - x_zero_index, i - y_zero_index, len(model[0]) - z_zero_index) + self.color_list[ind].InsertTuple4(n, r, g, b, alpha) + n = n + 1 + + self.point_list[ind].InsertNextPoint(len(model[0]) - x_zero_index, i - y_zero_index, 0 - z_zero_index) + self.color_list[ind].InsertTuple4(n, r, g, b, alpha) + n = n + 1 + + self.point_list[ind].InsertNextPoint(len(model[0]) - x_zero_index, i - y_zero_index, + len(model[0]) - z_zero_index) + self.color_list[ind].InsertTuple4(n, r, g, b, alpha) + n = n + 1 + + self.point_list[ind].InsertNextPoint(i - x_zero_index, 0 - y_zero_index, 0 - z_zero_index) + self.color_list[ind].InsertTuple4(n, r, g, b, alpha) + n = n + 1 + + self.point_list[ind].InsertNextPoint(i - x_zero_index, 0 - y_zero_index, len(model[0]) - z_zero_index) + self.color_list[ind].InsertTuple4(n, r, g, b, 173) + n = n + 1 + + self.point_list[ind].InsertNextPoint(i - x_zero_index, len(model[0]) - y_zero_index, 0 - z_zero_index) + self.color_list[ind].InsertTuple4(n, r, g, b, 173) + n = n + 1 + + self.point_list[ind].InsertNextPoint(i - x_zero_index, len(model[0]) - y_zero_index, + len(model[0]) - z_zero_index) + self.color_list[ind].InsertTuple4(n, r, g, b, 173) + n = n + 1 + + def update_actor(self): + models = self.engine.model + + colors = [] + colors.append(Color(241, 95, 45, 255)) # 0 + # colors.append(Color(246, 102, 39, 255)) # .........if(chair_2_legs),open this.......... # + colors.append(Color(0, 202, 122, 255)) # 1 + colors.append(Color(0, 141, 237, 255)) # 2 + colors.append(Color(36, 160, 191, 255)) # 3 + colors.append(Color(255, 130, 58, 255)) # 4 + colors.append(Color(140, 255, 128, 255)) # 5 + + for ind in range(len(models)): + self.point_list[ind].Reset() + self.color_list[ind].Reset() + + model = models[ind]['model'] + + part_name = models[ind]['name'] + part_label = int(part_name[-1]) + + translate_vector = models[ind]['translate_vector'] + dims_vector = models[ind]['dim_vecetor'] + + x_zero_index = 0 + y_zero_index = 0 + z_zero_index = 0 + + print( len(model[0]), len(model[0]), len(model[0])) + n = 0 + for i in range(len(model[0])): + for j in range(len(model[1])): + for k in range(len(model[2])): + c = model[i, j, k] + if c > 0.5: + if part_label == 0: + self.point_list[ind].InsertNextPoint(i - x_zero_index, j - y_zero_index, + k - z_zero_index) + self.color_list[ind].InsertTuple4(n, 241, 95, 45, 200) + if part_label == 1: + self.point_list[ind].InsertNextPoint(i - x_zero_index, j - y_zero_index, + k - z_zero_index) + self.color_list[ind].InsertTuple4(n, 0, 202, 122, 200) + if part_label == 2: + self.point_list[ind].InsertNextPoint(i - x_zero_index, j - y_zero_index, + k - z_zero_index) + self.color_list[ind].InsertTuple4(n, 0, 141, 237, 200) + if part_label == 3: + self.point_list[ind].InsertNextPoint(i - x_zero_index, j - y_zero_index, + k - z_zero_index) + self.color_list[ind].InsertTuple4(n, 36, 160, 191, 200) + if part_label == 4: + self.point_list[ind].InsertNextPoint(i - x_zero_index, j - y_zero_index, + k - z_zero_index) + self.color_list[ind].InsertTuple4(n, 255, 130, 58, 200) + if part_label == 5: + self.point_list[ind].InsertNextPoint(i - x_zero_index, j - y_zero_index, + k - z_zero_index) + self.color_list[ind].InsertTuple4(n, 140, 255, 128, 200) + if part_label == 6: + self.point_list[ind].InsertNextPoint(i - x_zero_index, j - y_zero_index, + k - z_zero_index) + self.color_list[ind].InsertTuple4(n, 200, 240, 255, 200) + n = n + 1 + pass + + self.set_bb_color(model, ind, n, x_zero_index, y_zero_index, z_zero_index, colors[part_label].r, colors[part_label].g, colors[part_label].b) + + trans = vtk.vtkTransform() + transformMatrix = vtk.vtkMatrix4x4() + for i in range(0, 4): + for j in range(0, 4): + if i == j and (i == 1 or i == 2 or i == 0): + transformMatrix.SetElement(i, j, float(dims_vector[i]) / 32.0) + elif j == 3 and i <= 2: + transformMatrix.SetElement(i, j, float(translate_vector[i]) - float(dims_vector[i]) / 2) + elif i == 3 and j == 3: + transformMatrix.SetElement(i, j, 1) + elif i == 3 and j <= 2: + transformMatrix.SetElement(i, j, 0) + trans.SetMatrix(transformMatrix) + self.part_list[ind].SetUserTransform(trans) + + print( translate_vector[0], translate_vector[1], translate_vector[2]) + + print( "part index: %r center: %r" % (ind, self.part_list[ind].GetCenter())) + print( "part index: %r position: %r" % (ind, self.part_list[ind].GetPosition())) + print( "part index: %r xRange: %r" % (ind, self.part_list[ind].GetXRange())) + print( "part index: %r length: %r" % (ind, self.part_list[ind].GetLength())) + print( "part index: %r translate_vector: %r" % (ind, translate_vector)) + print( "part index: %r dims_vector: %r" % (ind, dims_vector)) + + # self.glyph3D.Modified() + for i in range(len(self.glyph3D_list)): + self.glyph3D_list[i].Modified() + + if self.resetCamera: + self.renderer.ResetCamera() + + self.resetCamera = False + self.update() + QApplication.processEvents() + + for i in range(len(self.part_list)): + print( self.part_list[i].GetPosition()) + + + def save_image2(self): + file_path = QFileDialog.getSaveFileName(self, "saveFlle", str(self.engine.name) + ".png", + filter="png (*.png *.)") + current_file_path = file_path[0] + window_to_image_filter = vtk.vtkWindowToImageFilter() + # window_to_image_filter.SetInput(self.GetRenderWindow()) + window_to_image_filter.SetInput(self.GetRenderWindow()) + window_to_image_filter.Update() + writer = vtk.vtkPNGWriter() + # # writer.SetFileName(unicode(current_file_path)) + writer.SetFileName(str(current_file_path)) + writer.SetInputConnection(window_to_image_filter.GetOutputPort()) + writer.Write() + + def save_image1(self, file_path): + window_to_image_filter = vtk.vtkWindowToImageFilter() + # window_to_image_filter.SetInput(self.GetRenderWindow()) + window_to_image_filter.SetInput(self.GetRenderWindow()) + window_to_image_filter.Update() + writer = vtk.vtkPNGWriter() + # writer.SetFileName(unicode(file_path) + '/image_' + str(self.engine.index) + '.png') + writer.SetFileName(str(file_path) + '/image_' + str(self.engine.index) + '.png') + writer.SetInputConnection(window_to_image_filter.GetOutputPort()) + writer.Write() + + def set_camera(self, x, y, z): + camera = self.renderer.GetActiveCamera() + camera.SetViewUp(x, y, z) + self.renderer.SetActiveCamera(camera) \ No newline at end of file