1 # Copyright (C) 2014-2020 CEA/DEN, EDF R&D
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License, or (at your option) any later version.
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 # Lesser General Public License for more details.
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 # Author : Maxim Glibin
21 from paraview.simple import *
22 from paraview.servermanager import *
24 paraview.simple._DisableFirstRenderCameraReset()
30 # Separator of family name
34 FAMILY_CELL = "FamilyIdCell"
35 FAMILY_NODE = "FamilyIdNode"
37 ## Extract information about groups, families and IDs of these families from active source proxy.
38 # @param smProxy The server manager proxy.
39 # @param mapFamilies The returned map of families and its IDs.
40 # @param mapGroups The returned map of groups and its families.
41 # @param mapRelations The returned map of relations between families and groups.
42 # @return True if all data are generated without errors, False is otherwise.
43 def ExctractSILInformation(smProxy, mapFamilies, mapGroups, mapRelations):
44 # Check access to arguments
45 if not isinstance(mapFamilies, dict) or not isinstance(mapGroups, dict) or not isinstance(mapRelations, dict):
46 raise TypeError("Returned arguments have inappropriate type.")
48 # Reset returned values
53 # Gather information about server manager proxy.
54 # Fills up 'silInfo' information with details about VTK object.
55 silInfo = vtkPVSILInformation()
56 smproxy.GatherInformation(silInfo)
58 # Get SIL graph (an editable directed graph) as vtkMutableDirectedGraph
59 graph = silInfo.GetSIL()
61 raise RuntimeError("No SIL graph found.")
63 # Get vertex data as vtkDataSetAttrbutes
64 vertexData = graph.GetVertexData()
65 if vertexData.GetNumberOfArrays() < 1:
66 raise RuntimeError("No data arrays found.")
68 # 'Names' array has 0 index
70 stringArray = graph.GetVertexData().GetAbstractArray(vertexData.GetArrayName(indexNames))
71 if stringArray == None:
72 raise RuntimeError("Abstract array with '%s' name is not found." % vertexData.GetArrayName(indexNames))
74 # Search index for families and groups
77 for index in range(stringArray.GetNumberOfValues()):
78 if stringArray.GetValue(index) == 'MeshesFamsGrps':
83 if not isFound or not idx:
84 raise RuntimeError("No 'MeshesFamsGrps' value in 'Names' array.")
86 # Initialize the adjacent vertex iterator to iterate over all outgoing vertices from vertex 'idx',
87 # i.e. the vertices which may be reached by traversing an out edge of the 'idx' vertex.
88 adjacentIterator = vtkAdjacentVertexIterator()
89 adjacentIterator.Initialize(graph, idx)
90 if adjacentIterator.GetVertex() != idx:
91 raise RuntimeError("Initialize the adjacent vertex iterator failed (main '%s')." % idx)
93 while (adjacentIterator.HasNext()):
94 vIdMesh = adjacentIterator.Next()
95 meshName = stringArray.GetValue(vIdMesh)
97 adjacentIt_Mesh = vtkAdjacentVertexIterator()
98 graph.GetAdjacentVertices(vIdMesh, adjacentIt_Mesh);
99 if adjacentIt_Mesh.GetVertex() != vIdMesh:
100 raise RuntimeError("Initialize the adjacent vertex iterator failed (mesh '%s')." % vIdMesh)
102 # Next edge in the graph associated with groups and its families
103 vId_Groups = adjacentIt_Mesh.Next() # 'zeGrps'
105 # Next edge in the graph associated with families and its IDs
106 vId_Families = adjacentIt_Mesh.Next() # 'zeFamIds'
108 adjacentIt_Families = vtkAdjacentVertexIterator()
109 graph.GetAdjacentVertices(vId_Families, adjacentIt_Families);
110 if adjacentIt_Families.GetVertex() != vId_Families:
111 raise RuntimeError("Initialize the adjacent vertex iterator failed (families '%s')." % vId_Families)
113 # Iterate over all families
114 while adjacentIt_Families.HasNext():
115 vIdFamily = adjacentIt_Families.Next()
116 rawFamilyName = stringArray.GetValue(vIdFamily)
118 # Get family name and its ID from raw string
119 splitFamily = rawFamilyName.split(ZE_SEP)
120 if len(splitFamily) != 2:
121 raise RuntimeError("No valid family name [%s]" % rawFamilyName)
123 familyName = splitFamily[0]
124 familyID = splitFamily[1]
125 if familyID.lstrip("+-").isdigit() == False:
126 raise RuntimeError("Family [%s] ID is not digit: %s" % (familyName, familyID))
128 # Save families and IDs in map
129 mapFamilies[familyName] = int(familyID)
131 adjacentIt_Groups = vtkAdjacentVertexIterator()
132 graph.GetAdjacentVertices(vId_Groups, adjacentIt_Groups);
133 if adjacentIt_Groups.GetVertex() != vId_Groups:
134 raise RuntimeError("Initialize the adjacent vertex iterator failed (groups '%s')." % vId_Groups)
136 # Iterate over all groups
137 while adjacentIt_Groups.HasNext():
138 vIdGroup = adjacentIt_Groups.Next()
139 groupName = stringArray.GetValue(vIdGroup)
141 adjacentIt_FamiliesOnGroups = vtkAdjacentVertexIterator()
142 graph.GetAdjacentVertices(vIdGroup, adjacentIt_FamiliesOnGroups);
143 if adjacentIt_FamiliesOnGroups.GetVertex() != vIdGroup:
144 raise RuntimeError("Initialize the adjacent vertex iterator failed (group '%s')." % vIdGroup)
146 familiesOnGroups = []
147 # Iterate over all families on group
148 while adjacentIt_FamiliesOnGroups.HasNext():
149 vIdFamilyOnGroup = adjacentIt_FamiliesOnGroups.Next()
150 familyNameOnGroup = stringArray.GetValue(vIdFamilyOnGroup)
151 familiesOnGroups.append(familyNameOnGroup)
153 # Save groups and its families in map
154 mapGroups[groupName] = familiesOnGroups
156 # Establish the relations between families and groups
157 for family_name, family_id in mapFamilies.items():
159 for group_name, family_name_on_group in mapGroups.items():
160 if family_name in family_name_on_group:
161 groupNames.append(group_name)
162 if len(groupNames) > 0:
163 mapRelations[family_name] = groupNames
169 source = GetActiveSource()
171 raise RuntimeError("No active source.")
173 # Get server manager proxy
174 smproxy = source.SMProxy
176 # Check MEDReader class
177 if smproxy.GetVTKClassName() != 'vtkMEDReader':
178 raise RuntimeError("VTK reader type is not supported (%s)." % smproxy.GetVTKClassName())
180 # Get render view in use or create new RenderView
181 renderView = GetActiveViewOrCreate('RenderView')
182 if renderView == None:
183 raise RuntimeError("No render view found.")
185 # Get representation of active source and view
186 representation = GetDisplayProperties(source, renderView)
187 if not representation:
188 raise RuntimeError("No representation found.")
190 # Visibility of source object
191 representation.Visibility = 1
193 # Get active or set default colour array name property
194 associationType = None
195 associationColorArray = representation.ColorArrayName.GetAssociation()
196 nameColorArray = representation.ColorArrayName.GetArrayName()
197 if not nameColorArray:
198 # Reset colour array name property
199 representation.ColorArrayName.SetElement(3, None)
200 representation.ColorArrayName.SetElement(4, None)
202 nameColorArray = FAMILY_CELL
203 associationType = GetAssociationFromString('CELLS')
205 if associationColorArray != None:
206 associationType = GetAssociationFromString(associationColorArray)
208 if nameColorArray not in [FAMILY_CELL, FAMILY_NODE]:
209 raise RuntimeError("Selected data array [%s] is not valid." % nameColorArray)
211 # Get data information
214 scalarBarlabel = None
215 activeRepresentation = 'Surface'
216 if data.GetDataObjectType() == vtkDataObjectTypes.GetTypeIdFromClassName("vtkMultiBlockDataSet"):
217 if data.GetNumberOfBlocks() < 1:
218 raise RuntimeError("No blocks.")
221 dataObject = data.GetBlock(blockID)
222 if not dataObject.IsA("vtkDataSet"):
223 raise RuntimeError("Data object has inappropriate type (%s)" % dataObject.GetDataObjectType())
225 if associationType == GetAssociationFromString("CELLS"):
226 cellData = dataObject.GetCellData()
227 if not cellData.HasArray(FAMILY_CELL):
228 raise RuntimeError("Cell data array has no '%s'." % FAMILY_CELL)
230 scalarBarlabel = "CELLS"
231 activeRepresentation = 'Surface'
233 dataArray = cellData.GetArray(FAMILY_CELL)
234 for tupleId in range(dataArray.GetNumberOfTuples()):
235 dataArrayValues.append(dataArray.GetValue(tupleId))
237 elif associationType == GetAssociationFromString("POINTS"):
238 pointData = dataObject.GetPointData()
239 if not pointData.HasArray(FAMILY_NODE):
240 raise RuntimeError("Point data array has no '%s'." % FAMILY_NODE)
242 scalarBarlabel = "POINTS"
244 # Check that PointSprite plugin is available
245 if hasattr(representation, "MaxPixelSize"):
246 activeRepresentation = 'Point Sprite'
247 if representation.MaxPixelSize == 64:
248 representation.MaxPixelSize = 8
250 activeRepresentation = 'Points'
252 dataArray = pointData.GetArray(FAMILY_NODE)
253 for tupleId in range(dataArray.GetNumberOfTuples()):
254 dataArrayValues.append(dataArray.GetValue(tupleId))
257 raise RuntimeError("Not implemented yet (%s)." % GetAssociationAsString(associationType))
261 mapRelations = dict()
263 if not ExctractSILInformation(smproxy, mapFamilies, mapGroups, mapRelations):
264 raise RuntimeError("Extraction SIL graph failed.")
266 # Sort families array by ID
267 sortedArray = sorted(list(mapFamilies.values()))
269 # Prepare 'Annotation' list for lookup-table
272 for idFamily in sortedArray:
273 if idFamily not in dataArrayValues:
276 if associationType == GetAssociationFromString("CELLS"):
279 elif associationType == GetAssociationFromString("POINTS"):
283 raise RuntimeError("Not implemented yet (%s)." % GetAssociationAsString(associationType))
285 annotationList.append(str(idFamily))
288 # Iterate over all families to get group(s) by family name
289 for famName, famID in mapFamilies.items():
290 if idFamily == famID:
291 if famName in mapRelations:
292 annotationList.append(str(', ').join(mapRelations.get(famName)))
294 annotationList.append(str('No group'))
296 # Generate indexed colour for array
298 # Generate HSV colour from red to blue
300 stepHue = int(240/(numberValues-1))
303 for i in range(numberValues):
304 indexedColor.extend(colorsys.hsv_to_rgb(float(i*stepHue)/360, 1, 1))
306 # Set scalar colouring
307 ColorBy(representation, (GetAssociationAsString(associationType), nameColorArray))
309 # Rescale colour and/or opacity maps used to include current data range
310 representation.RescaleTransferFunctionToDataRange(True)
312 # Show colour bar/colour legend
313 representation.SetScalarBarVisibility(renderView, True)
315 # Change representation type
316 representation.SetPropertyWithName("Representation", activeRepresentation)
318 # Get colour transfer function/colour map for 'FamilyIdCell' or 'FamilyIdNode'
319 lutFamily = GetLookupTableForArray(nameColorArray, 1)
320 lutFamily.SetPropertyWithName("ColorSpace", "RGB")
322 # Modify lookup table
323 lutFamily.InterpretValuesAsCategories = 1
324 lutFamily.Annotations = annotationList
325 lutFamily.IndexedColors = indexedColor
326 lutFamily.NumberOfTableValues = numberValues
328 # Modify scalar bar of view
329 lutScalarBar = GetScalarBar(lutFamily, renderView)
330 lutScalarBar.AddRangeAnnotations = 1
331 lutScalarBar.AddRangeLabels = 0
332 lutScalarBar.DrawAnnotations = 1
333 lutScalarBar.Title = 'Groups of %s' % scalarBarlabel