Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / applications / utilities / mesh / generation / cfMesh / python / Salome / extractFeatureEdges.py
blob558ff9c1373ff564b85d323f086e1694b4b06d13
1 #!python
2 # =============================================================================
3 # Salome GEOM script to extract the feature edges from a body and add them
4 # to the group named 'featureEdges'.
5 # Tested on Salome 7.4.0 and python 2.7 on 64-bit Windows
7 # Author: Ivor Clifford <ivor.clifford@psi.ch>
9 # =============================================================================
11 def extractFeatureEdges(body, minFeatureAngle = 5):
12 '''
13 Find all feature edges on the supplied body and return them as a list
14 of edge ids.
16 body - A Salome solid, compound, shell or face object to find all
17 feature edges on.
18 minFeatureAngle - the angle (in degrees) between adjacent surfaces
19 above which the edge will be considered a feature angle.
20 '''
21 import salome
22 salome.salome_init()
24 import GEOM
25 from salome.geom import geomBuilder
26 geompy = geomBuilder.New(salome.myStudy)
28 # Check the body type
29 if not (body.GetShapeType() in [GEOM.SHELL, GEOM.SOLID, GEOM.FACE, GEOM.COMPOUND]):
30 raise RuntimeError('Supplied object is not a solid, shell or face.')
32 print 'Extracting edges of %s with feature angle > %g.' % (body.GetName(), minFeatureAngle)
34 # Extract basic info
35 faces = geompy.SubShapeAll(body, geompy.ShapeType["FACE"])
36 curves = geompy.SubShapeAll(body, geompy.ShapeType["EDGE"])
37 points = geompy.SubShapeAll(body, geompy.ShapeType["VERTEX"])
39 faceIds = geompy.GetSubShapesIDs(body, faces)
40 curveIds = geompy.GetSubShapesIDs(body, curves)
41 nodeIds = geompy.GetSubShapesIDs(body, points)
43 maxFaceId = max(faceIds)
44 maxCurveId = max(curveIds)
45 maxNodeId = max(nodeIds)
47 # Reverse mapping from curve id to local curve arrays
48 faceMap = [-1 for i in xrange(maxFaceId+1)]
49 for localId, id in enumerate(faceIds):
50 faceMap[id] = localId
52 curveMap = [-1 for i in xrange(maxCurveId+1)]
53 for localId, id in enumerate(curveIds):
54 curveMap[id] = localId
56 nodeMap = [-1 for i in xrange(maxNodeId+1)]
57 for localId, id in enumerate(nodeIds):
58 nodeMap[id] = localId
61 # Get curves on each face
62 faceCurveIds = [[curveMap[id] for id in geompy.GetSubShapesIDs(
63 body,
64 geompy.SubShapeAll(face, geompy.ShapeType["EDGE"])
65 )] for face in faces]
67 # Get faces attached to each curve
68 curveFaceIds = [[] for id in curveIds]
70 for faceI, ids in enumerate(faceCurveIds):
71 for id in ids:
72 curveFaceIds[id].append(faceI)
74 # Now that we have the connectivity for curves and faces find the
75 # feature edges
76 featureEdgeIds = []
77 for curveId, curve, adjFaceIds in zip(curveIds, curves, curveFaceIds):
78 if len(adjFaceIds) == 2:
79 # Curve with 2 adjacent faces - Test feature angle
80 # Determine break angle at each curve
81 # If greater than the feature edge angle, add the curve to group featureEdges
82 face1 = faces[adjFaceIds[0]]
83 face2 = faces[adjFaceIds[1]]
84 point = geompy.GetFirstVertex(curve) # Test at the first vertex
85 n1 = geompy.GetNormal(face1, point)
86 n2 = geompy.GetNormal(face2, point)
87 angle = geompy.GetAngle(n1, n2)
88 if angle > minFeatureAngle:
89 featureEdgeIds.append(curveId)
91 elif len(adjFaceIds) == 1:
92 # Curve on standalone face - Add by default
93 featureEdgeIds.append(curveId)
95 elif len(adjFaceIds) == 0:
96 # Standalone curve - Ignore
97 None
99 else:
100 raise RuntimeError('Curve found sharing %d faces. This is unexpected for fully enclosed bodies.' % len(adjFaceIds))
102 # Done
103 print "%d feature edges found" % len(featureEdgeIds)
105 return featureEdgeIds
108 # If run as a standalone script, use the current Salome GUI selection
109 # and add the feature edges to group named 'featureEdges'
110 if __name__ == '__main__':
111 import salome
112 salome.salome_init()
114 import GEOM
115 from salome.geom import geomBuilder
116 geompy = geomBuilder.New(salome.myStudy)
118 # Get current GUI selection
119 selected = salome.sg.getAllSelected()
120 if len(selected) != 1:
121 raise RuntimeError('A single solid, shell or face object must be selected.')
123 body = salome.myStudy.FindObjectID(selected[0]).GetObject()
125 # Get feature edges and add to the group 'featureEdges'
126 featureEdges = geompy.CreateGroup(body, geompy.ShapeType["EDGE"])
127 geompy.UnionIDs(featureEdges, extractFeatureEdges(body))
128 geompy.addToStudyInFather(body, featureEdges, 'featureEdges')
130 if salome.sg.hasDesktop():
131 salome.sg.updateObjBrowser(1)