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