def __init__(self): self.nvalues = 9 self.groups = set([]) self._group_elements = {} self._group_coords = {} self._group_shown = {} self._names_storage = NamesStorage() self.dim_max = 1.0 self.vtk_version = [int(i) for i in vtk.VTK_VERSION.split('.')[:1]] print('vtk_version = %s' % (self.vtk_version))
class GuiCommon(object): def __init__(self): self._is_displaced = False self._xyz_nominal = None self.nvalues = 9 self.groups = set([]) self._group_elements = {} self._group_coords = {} self._group_shown = {} self._names_storage = NamesStorage() self.dim_max = 1.0 self.vtk_version = [int(i) for i in vtk.VTK_VERSION.split('.')[:1]] print('vtk_version = %s' % (self.vtk_version)) #def nCells(self): #try: #cell_data = self.grid.GetCellData() #return cell_data.GetNumberOfCells() #except AttributeError: #return 0 #def nPoints(self): #try: #point_data = self.grid.GetPointData() #return point_data.GetNumberOfPoints() #except AttributeError: #return 0 def update_axes_length(self, dim_max): """ scale coordinate system based on model length """ self.dim_max = dim_max dim_max *= 0.10 if hasattr(self, 'axes'): for cid, axes in iteritems(self.axes): axes.SetTotalLength(dim_max, dim_max, dim_max) @property def displacement_scale_factor(self): """ # dim_max = max_val * scale # scale = dim_max / max_val # 0.25 added just cause scale = self.displacement_scale_factor / tnorm_abs_max """ #scale = self.dim_max / tnorm_abs_max * 0.25 scale = self.dim_max * 0.25 return scale def update_text_actors(self, subcase_id, subtitle, min_value, max_value, label): self.text_actors[0].SetInput('Max: %g' % max_value) # max self.text_actors[1].SetInput('Min: %g' % min_value) # min self.text_actors[2].SetInput('Subcase: %s Subtitle: %s' % (subcase_id, subtitle)) # info if label: self.text_actors[3].SetInput('Label: %s' % label) # info self.text_actors[3].VisibilityOn() else: self.text_actors[3].VisibilityOff() def cycleResults(self, result_name=None): if self.nCases <= 1: self.log.warning('cycleResults(result_name=%r); nCases=%i' % (result_name, self.nCases)) if self.nCases == 0: self.scalarBar.SetVisibility(False) return result_type = self.cycleResults_explicit(result_name, explicit=False) self.log_command('cycleResults(result_name=%r)' % result_type) def get_subtitle_label(self, subcase_id): try: subtitle, label = self.iSubcaseNameMap[subcase_id] except KeyError: subtitle = 'case=NA' label = 'label=NA' return subtitle, label def cycleResults_explicit(self, result_name=None, explicit=True): #if explicit: #self.log_command('cycleResults(result_name=%r)' % result_name) found_cases = self.incrementCycle(result_name) if found_cases: result_type = self._set_case(result_name, self.iCase, explicit=explicit, cycle=True) else: result_type = None #else: #self.log_command(""didn't find case...") return result_type def _set_case(self, result_name, icase, explicit=False, cycle=False, skip_click_check=False): if not skip_click_check: if not cycle and icase == self.iCase: # don't click the button twice # cycle=True means we're cycling # cycle=False skips that check return try: key = self.caseKeys[icase] except: print('icase=%s caseKeys=%s' % (icase, str(self.caseKeys))) raise self.iCase = icase case = self.resultCases[key] label2 = '' if isinstance(key, (int, int32)): (obj, (i, name)) = self.resultCases[key] subcase_id = obj.subcase_id case = obj.get_result(i, name) result_type = obj.get_title(i, name) vector_size = obj.get_vector_size(i, name) location = obj.get_location(i, name) data_format = obj.get_data_format(i, name) scale = obj.get_scale(i, name) elif len(key) == 5: (subcase_id, result_type, vector_size, location, data_format) = key scale = 0.0 elif len(key) == 6: (subcase_id, j, result_type, vector_size, location, data_format) = key scale = 0.0 else: (subcase_id, j, result_type, vector_size, location, data_format, label2) = key scale = 0.0 subtitle, label = self.get_subtitle_label(subcase_id) label += label2 print("subcase_id=%s result_type=%r subtitle=%r label=%r" % (subcase_id, result_type, subtitle, label)) #================================================ if isinstance(case, ndarray): max_value = case.max() min_value = case.min() else: raise RuntimeError('list-based results have been removed; use numpy.array') # flips sign to make colors go from blue -> red norm_value = float(max_value - min_value) vector_size = 1 name = (vector_size, subcase_id, result_type, label, min_value, max_value, scale) if self._names_storage.has_exact_name(name): grid_result = None else: grid_result = self.set_grid_values(name, case, vector_size, min_value, max_value, norm_value) vector_size = 3 name_vector = (vector_size, subcase_id, result_type, label, min_value, max_value, scale) if self._names_storage.has_exact_name(name_vector): grid_result_vector = None else: grid_result_vector = self.set_grid_values(name_vector, case, vector_size, min_value, max_value, norm_value) self.update_text_actors(subcase_id, subtitle, min_value, max_value, label) # TODO: results can only go from centroid->node and not back to centroid self.final_grid_update(name, grid_result, name_vector, grid_result_vector, key, subtitle, label) is_blue_to_red = True self.update_scalar_bar(result_type, min_value, max_value, norm_value, data_format, is_blue_to_red=is_blue_to_red, is_horizontal=self.is_horizontal_scalar_bar) self.update_legend(result_type, min_value, max_value, data_format, is_blue_to_red, self.is_horizontal_scalar_bar, scale) location = self.get_case_location(key) self.res_widget.update_method(location) if explicit: self.log_command('cycleResults(result_name=%r)' % result_type) return result_type def set_grid_values(self, name, case, vector_size, min_value, max_value, norm_value, is_blue_to_red=True): """ https://pyscience.wordpress.com/2014/09/06/numpy-to-vtk-converting-your-numpy-arrays-to-vtk-arrays-and-files/ """ if self._names_storage.has_exact_name(name): return if issubdtype(case.dtype, numpy.integer): data_type = vtk.VTK_INT self.aQuadMapper.InterpolateScalarsBeforeMappingOn() elif issubdtype(case.dtype, numpy.float): data_type = vtk.VTK_FLOAT self.aQuadMapper.InterpolateScalarsBeforeMappingOff() else: raise NotImplementedError(case.dtype.type) if 0: # nan testing if case.dtype.name == 'float32': case[50] = float32(1) / float32(0) else: case[50] = int32(1) / int32(0) if vector_size == 1: if is_blue_to_red: if norm_value == 0: #for i, value in enumerate(case): #grid_result.InsertNextValue(1 - min_value) nvalues = len(case) case2 = full((nvalues), 1.0 - min_value, dtype='float32') #case2 = 1 - ones(nvalues) * min_value else: #for i, value in enumerate(case): #grid_result.InsertNextValue(1.0 - (value - min_value) / norm_value) case2 = 1.0 - (case - min_value) / norm_value else: if norm_value == 0: # how do you even get a constant nodal result on a surface? # nodal normals on a constant surface, but that's a bit of an edge case #for i, value in enumerate(case): #grid_result.InsertNextValue(min_value) case2 = full((nvalues), min_value, dtype='float32') #case2 = case else: #for i, value in enumerate(case): #grid_result.InsertNextValue((value - min_value) / norm_value) case2 = (case - min_value) / norm_value #scalar_range = self.grid.GetScalarRange() #print(scalar_range) #self.aQuadMapper.SetScalarRange(scalar_range) if case.flags.contiguous: case2 = case else: case2 = deepcopy(case) grid_result = numpy_to_vtk( num_array=case2, deep=True, array_type=data_type ) #print('grid_result = %s' % grid_result) #print('max2 =', grid_result.GetRange()) else: # vector_size=3 #for value in case: #grid_result.InsertNextTuple3(*value) # x, y, z if case.flags.contiguous: case2 = case else: case2 = deepcopy(case) grid_result = numpy_to_vtk( num_array=case2, deep=True, array_type=data_type ) return grid_result def final_grid_update(self, name, grid_result, name_vector, grid_result_vector, key, subtitle, label): obj = None if isinstance(key, int): (obj, (i, res_name)) = self.resultCases[key] subcase_id = obj.subcase_id #case = obj.get_result(i, name) result_type = obj.get_title(i, res_name) vector_size = obj.get_vector_size(i, res_name) #print('res_name=%s vector_size=%s' % (res_name, vector_size)) location = obj.get_location(i, res_name) data_format = obj.get_data_format(i, res_name) elif len(key) == 5: (subcase_id, result_type, vector_size, location, data_format) = key elif len(key) == 6: (subcase_id, j, result_type, vector_size, location, data_format) = key else: (subcase_id, j, result_type, vector_size, location, data_format, label2) = key self._final_grid_update(name, grid_result, None, None, None, 1, subcase_id, result_type, location, subtitle, label, revert_displaced=True) if obj is None: return if vector_size == 3: self._final_grid_update(name_vector, grid_result_vector, obj, i, res_name, vector_size, subcase_id, result_type, location, subtitle, label, revert_displaced=False) #xyz_nominal, vector_data = obj.get_vector_result(i, res_name) #self._update_grid(vector_data) def _final_grid_update(self, name, grid_result, obj, i, res_name, vector_size, subcase_id, result_type, location, subtitle, label, revert_displaced=True): if name is None: return name_str = self._names_storage.get_name_string(name) if not self._names_storage.has_exact_name(name): grid_result.SetName(name_str) self._names_storage.add(name) if self._is_displaced and revert_displaced: self._is_displaced = False self._update_grid(self._xyz_nominal) if location == 'centroid': cell_data = self.grid.GetCellData() if self._names_storage.has_close_name(name): cell_data.RemoveArray(name_str) self._names_storage.remove(name) cell_data.AddArray(grid_result) self.log_info("centroidal plotting vector=%s - subcase_id=%s result_type=%s subtitle=%s label=%s" % (vector_size, subcase_id, result_type, subtitle, label)) elif location == 'node': point_data = self.grid.GetPointData() if self._names_storage.has_close_name(name): point_data.RemoveArray(name_str) self._names_storage.remove(name) if vector_size == 1: self.log_info("node plotting vector=%s - subcase_id=%s result_type=%s subtitle=%s label=%s" % (vector_size, subcase_id, result_type, subtitle, label)) point_data.AddArray(grid_result) elif vector_size == 3: #print('vector_size3; get, update') xyz_nominal, vector_data = obj.get_vector_result(i, res_name) #grid_result1 = self.set_grid_values(name, case, 1, #min_value, max_value, norm_value) #point_data.AddArray(grid_result1) self._is_displaced = True self._xyz_nominal = xyz_nominal self._update_grid(vector_data) self.log_info("node plotting vector=%s - subcase_id=%s result_type=%s subtitle=%s label=%s" % (vector_size, subcase_id, result_type, subtitle, label)) #point_data.AddVector(grid_result) # old #point_data.AddArray(grid_result) else: raise RuntimeError(vector_size) else: raise RuntimeError(location) if location == 'centroid': cell_data = self.grid.GetCellData() cell_data.SetActiveScalars(name_str) point_data = self.grid.GetPointData() point_data.SetActiveScalars(None) elif location == 'node': cell_data = self.grid.GetCellData() cell_data.SetActiveScalars(None) point_data = self.grid.GetPointData() if vector_size == 1: point_data.SetActiveScalars(name_str) elif vector_size == 3: point_data.SetActiveVectors(name_str) else: raise RuntimeError(vector_size) else: raise RuntimeError(location) self.grid.Modified() self.vtk_interactor.Render() self.hide_labels(show_msg=False) self.show_labels(result_names=[result_type], show_msg=False) def _update_grid(self, vector_data): nnodes = vector_data.shape[0] points = self.grid.GetPoints() for j in range(nnodes): points.SetPoint(j, *vector_data[j, :]) self.grid.Modified() def _get_icase(self, result_name): found_case = False print(self.resultCases.keys()) i = 0 for icase, cases in sorted(iteritems(self.resultCases)): if result_name == icase[1]: found_case = True iCase = i break i += 1 assert found_case == True, 'result_name=%r' % result_name return iCase def incrementCycle(self, result_name=False): found_case = False if result_name is not False and result_name is not None: for icase, cases in sorted(iteritems(self.resultCases)): if result_name == cases[1]: found_case = True self.iCase = icase # no idea why this works...if it does... if not found_case: if self.iCase is not self.nCases: self.iCase += 1 else: self.iCase = 0 if self.iCase == len(self.caseKeys): self.iCase = 0 if len(self.caseKeys) > 0: try: key = self.caseKeys[self.iCase] except IndexError: found_cases = False return found_cases location = self.get_case_location(key) print("key = %s" % str(key)) #if key[2] == 3: # vector size=3 -> vector, skipping ??? #self.incrementCycle() found_cases = True else: # key = self.caseKeys[self.iCase] # location = self.get_case_location(key) location = 'N/A' #result_type = 'centroidal' if location == 'centroid' else 'nodal' result_type = '???' self.log_error("No Results found. Many results are not supported in the GUI.\nTry using %s results." % result_type) self.scalarBar.SetVisibility(False) found_cases = False #print("next iCase=%s key=%s" % (self.iCase, key)) return found_cases def get_result_name(self, key): if isinstance(key, int): (obj, (i, name)) = self.resultCases[key] return name elif len(key) == 5: (subcase_id, result_type, vector_size, location, data_format) = key elif len(key) == 6: (subcase_id, i, result_type, vector_size, location, data_format) = key else: (subcase_id, i, result_type, vector_size, location, data_format, label2) = key return result_type def get_case_location(self, key): if isinstance(key, int): (obj, (i, name)) = self.resultCases[key] return obj.get_location(i, name) elif len(key) == 5: (subcase_id, result_type, vector_size, location, data_format) = key elif len(key) == 6: (subcase_id, i, result_type, vector_size, location, data_format) = key else: (subcase_id, i, result_type, vector_size, location, data_format, label2) = key return location