Salome HOME
Merge tag 'V8_3_0a2' into ngr/python3_dev
[modules/smesh.git] / src / Tools / blocFissure / gmu / listOfExtraFunctions.py
1 # -*- coding: utf-8 -*-
2 """
3 Created on Mon Jun 23 14:49:36 2014
4
5 @author: I48174 (Olivier HOAREAU)
6 """
7
8 import logging
9 import SMESH
10 from .geomsmesh import smesh
11
12 def lookForCorner(maillageAScanner):
13     
14     """ Cette fonction permet de scanner la liste de noeuds qui composent le
15         maillage passé en paramètre. On recherche un ou plusieurs coins, ce
16         qui implique les caractéristiques suivantes:
17             - le noeud doit appartenir au moins à trois éléments distincts
18             - chaque élément doit appartenir à un ensemble distinct
19         La fonction renvoie une liste de coins par l'intermédiaire de l'IDs
20         chaque noeud. La liste contient en général au maximum deux coins.
21     """
22     
23     logging.info("start")
24     
25     allNodeIds = maillageAScanner.GetNodesId()  # On stocke tout les noeuds
26     listOfCorners = []
27     for ND in allNodeIds:
28         # On parcours la liste de noeuds
29         listOfElements = maillageAScanner.GetNodeInverseElements(ND)
30         if len(listOfElements) >=3:
31             # On teste le nombre d'éléments qui partagent le même noeud
32             # --- Filtre selon le critère 'coplanar' --- #
33             listOfCriterion = [smesh.GetCriterion(SMESH.FACE, SMESH.FT_CoplanarFaces, \
34                                SMESH.FT_Undefined, elem, SMESH.FT_Undefined, SMESH.FT_Undefined, 30) \
35                                for elem in listOfElements]
36             listOfFilters = [smesh.GetFilterFromCriteria([criteria]) for criteria in listOfCriterion]
37             listOfSets = [maillageAScanner.GetIdsFromFilter(filter) for filter in listOfFilters]
38             if listOfSets.count(listOfSets[0]) == len(listOfSets):
39                 # Si toutes les listes d'éléments sont similaires, on retourne
40                 # au début pour éviter de travailler sur des éléments inutiles.
41                 # Exemple : un noeud appartenant à 4 éléments sur la même face.
42                 continue
43             for s in listOfSets:
44                 while listOfSets.count(s) > 1:
45                     # On supprime tant que la liste d'éléments n'est pas unique.
46                     listOfSets.remove(s)
47             if len(listOfSets) >= 3:
48                 # Si on a au moins 3 listes d'élements différentes, on considère
49                 # qu'il y a présence d'un coin.
50                 listOfCorners.append(ND)
51     return listOfCorners
52
53 def createLinesFromMesh(maillageSupport):
54     
55     """ Cette fonction permet de générer une liste de lignes à partir du 
56         maillage support passé en paramètre. On démarre à partir d'un coin
57         simple et on parcourt tout les noeuds pour former une ligne. Soit la
58         figure ci-dessous :
59             
60             1_____4_____7    On part du coin N1, et on cherche les noeuds
61             |     |     |    successifs tels que [1, 2, 3]. Lorsqu'on arrive
62             |  1  |  3  |    arrive sur le noeud de fin de ligne N3, on repart
63             |     |     |    du noeud précédent du premier élément (E1), à
64             2_____5_____8    savoir le noeud N4. On suit les noeuds succesifs
65             |     |     |    [4, 5, 6] comme précédemment et ainsi de suite.
66             |  2  |  4  |    Lorsqu'on arrive sur le dernier noeud de la
67             |     |     |    dernière ligne, à savoir le noeud N9, on considère
68             3_____6_____9    que toutes les lignes sont créées.
69             
70         La fonction retourne une liste de lignes utilisées par la suite.
71     """
72     
73     logging.info("start")
74     
75     allNodeIds = maillageSupport.GetNodesId()
76     while len(allNodeIds):
77         nodeIds = allNodeIds
78         for idNode in nodeIds: # rechercher un coin
79           elems = maillageSupport.GetNodeInverseElements(idNode)
80           if len(elems) == 1:
81             # un coin: un noeud, un element quadrangle
82             elem = elems[0]
83             break;
84         idStart = idNode # le noeud de coin
85         elemStart = elem # l'élément quadrangle au coin
86         xyz = maillageSupport.GetNodeXYZ(idStart)
87         logging.debug("idStart %s, coords %s", idStart, str(xyz))
88     
89         nodelines =[] # on va constituer une liste de lignes de points
90         nextLine = True
91         ligneFinale = False
92         while nextLine:
93             logging.debug("--- une ligne")
94             idNode = idStart
95             elem = elemStart
96             if ligneFinale:
97                 agauche = False  # sens de parcours des 4 noeuds d'un quadrangle
98                 nextLine = False
99             else:
100                 agauche = True
101             ligneIncomplete = True  # on commence une ligne de points
102             debutLigne = True
103             nodeline = []
104             elemline = []
105             while ligneIncomplete:  # compléter la ligne de points
106                 nodeline.append(idNode)
107                 allNodeIds.remove(idNode)
108                 elemline.append(elem)
109                 nodes = maillageSupport.GetElemNodes(elem)
110                 i = nodes.index(idNode)  # repérer l'index du noeud courant (i) dans l'élément quadrangle (0 a 3)
111                 if agauche:              # déterminer le noeud suivant (j) et celui opposé (k) dans le quadrangle
112                     if i < 3:
113                         j = i+1
114                     else:
115                         j = 0
116                     if j < 3:
117                         k = j+1
118                     else:
119                         k = 0
120                 else:
121                     if i > 0:
122                         j = i -1
123                     else:
124                         j = 3
125                     if j > 0:
126                         k = j -1
127                     else:
128                         k = 3
129                 isuiv = nodes[j]   # noeud suivant
130                 iapres = nodes[k]  # noeud opposé
131                 if debutLigne:
132                     debutLigne = False
133                     # précédent a trouver, dernière ligne : précédent au lieu de suivant
134                     if agauche:
135                         if i > 0:
136                             iprec = nodes[i -1]
137                         else:
138                             iprec = nodes[3]
139                         idStart = iprec
140                         elems3 = maillageSupport.GetNodeInverseElements(iprec)
141                         if len(elems3) == 1: # autre coin
142                             ligneFinale = True
143                         else:
144                             for elem3 in elems3:
145                                 if elem3 != elem:
146                                     elemStart = elem3
147                                     break
148                 #print nodes, idNode, isuiv, iapres
149                 elems1 = maillageSupport.GetNodeInverseElements(isuiv)
150                 elems2 = maillageSupport.GetNodeInverseElements(iapres)
151                 ligneIncomplete = False
152                 for elem2 in elems2:
153                     if elems1.count(elem2) and elem2 != elem:
154                         ligneIncomplete = True
155                         idNode = isuiv
156                         elem = elem2
157                         break
158                 if not  ligneIncomplete:
159                     nodeline.append(isuiv)
160                     allNodeIds.remove(isuiv)
161             logging.debug("nodeline %s", nodeline)
162             logging.debug("elemline %s", elemline)
163             nodelines.append(nodeline)
164              
165         # on a constitué une liste de lignes de points connexes
166         logging.debug("dimensions [%s, %s]", len(nodelines),  len(nodeline))
167     
168     return nodelines
169
170 def createNewMeshesFromCorner(maillageSupport, listOfCorners):
171     
172     """ Cette fonction permet de générer un nouveau maillage plus facile à
173         utiliser. On démarre d'un coin et on récupère les trois éléments
174         auquel le noeud appartient. Grâce à un filtre 'coplanar' sur les trois
175         éléments, on peut générer des faces distinctes.
176     """
177     
178     logging.info("start")
179     
180     tmp = []
181     listOfNewMeshes = []
182     for corner in listOfCorners:
183         elems = maillageSupport.GetNodeInverseElements(corner)
184         for i, elem in enumerate(elems):
185             # --- Filtre selon le critère 'coplanar' --- #
186             critere = smesh.GetCriterion(SMESH.FACE, SMESH.FT_CoplanarFaces, \
187                                          SMESH.FT_Undefined, elem, SMESH.FT_Undefined, SMESH.FT_Undefined, 30)
188             filtre = smesh.GetFilterFromCriteria([critere])
189             grp = maillageSupport.GroupOnFilter(SMESH.FACE, 'grp', filtre)
190             # On copie le maillage en fonction du filtre
191             msh = smesh.CopyMesh(grp, 'new_{0}'.format(i + 1), False, True)
192             # On stocke l'ensemble des noeuds du maillage dans tmp
193             # On ajoute le maillage à la liste des nouveaux maillages
194             # seulement s'il n'y est pas déjà
195             tmp.append(msh.GetNodesId())
196             if tmp.count(msh.GetNodesId()) <= 1:
197                 listOfNewMeshes.append(msh)
198     return listOfNewMeshes