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