X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FTools%2FblocFissure%2Fgmu%2FlistOfExtraFunctions.py;h=f79c008f1c4db20d84ef79c1d839dbbbfc887edc;hp=803e37a6c422c9ed13dadfda58a281d717c607b2;hb=499f29d24922cec66e41b41a0039a954993bc6df;hpb=b7a7d49664daa32e1befb558280e13ed0bde37c9 diff --git a/src/Tools/blocFissure/gmu/listOfExtraFunctions.py b/src/Tools/blocFissure/gmu/listOfExtraFunctions.py index 803e37a6c..f79c008f1 100644 --- a/src/Tools/blocFissure/gmu/listOfExtraFunctions.py +++ b/src/Tools/blocFissure/gmu/listOfExtraFunctions.py @@ -1,198 +1,229 @@ # -*- coding: utf-8 -*- -""" -Created on Mon Jun 23 14:49:36 2014 +# Copyright (C) 2014-2022 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +"""Fonctions générrales sur les maillages +Created on Mon Jun 23 14:49:36 2014 @author: I48174 (Olivier HOAREAU) """ import logging + import SMESH from .geomsmesh import smesh +from .putName import putName + def lookForCorner(maillageAScanner): - - """ Cette fonction permet de scanner la liste de noeuds qui composent le - maillage passé en paramètre. On recherche un ou plusieurs coins, ce - qui implique les caractéristiques suivantes: - - le noeud doit appartenir au moins à trois éléments distincts - - chaque élément doit appartenir à un ensemble distinct - La fonction renvoie une liste de coins par l'intermédiaire de l'IDs - chaque noeud. La liste contient en général au maximum deux coins. - """ - - logging.info("start") - - allNodeIds = maillageAScanner.GetNodesId() # On stocke tout les noeuds - listOfCorners = [] - for ND in allNodeIds: - # On parcours la liste de noeuds - listOfElements = maillageAScanner.GetNodeInverseElements(ND) - if len(listOfElements) >=3: - # On teste le nombre d'éléments qui partagent le même noeud - # --- Filtre selon le critère 'coplanar' --- # - listOfCriterion = [smesh.GetCriterion(SMESH.FACE, SMESH.FT_CoplanarFaces, \ - SMESH.FT_Undefined, elem, SMESH.FT_Undefined, SMESH.FT_Undefined, 30) \ - for elem in listOfElements] - listOfFilters = [smesh.GetFilterFromCriteria([criteria]) for criteria in listOfCriterion] - listOfSets = [maillageAScanner.GetIdsFromFilter(filter) for filter in listOfFilters] - if listOfSets.count(listOfSets[0]) == len(listOfSets): - # Si toutes les listes d'éléments sont similaires, on retourne - # au début pour éviter de travailler sur des éléments inutiles. - # Exemple : un noeud appartenant à 4 éléments sur la même face. - continue - for s in listOfSets: - while listOfSets.count(s) > 1: - # On supprime tant que la liste d'éléments n'est pas unique. - listOfSets.remove(s) - if len(listOfSets) >= 3: - # Si on a au moins 3 listes d'élements différentes, on considère - # qu'il y a présence d'un coin. - listOfCorners.append(ND) - return listOfCorners + + """ Cette fonction permet de scanner la liste de noeuds qui composent le + maillage passé en paramètre. On recherche un ou plusieurs coins, ce + qui implique les caractéristiques suivantes: + - le noeud doit appartenir au moins à trois éléments distincts + - chaque élément doit appartenir à un ensemble distinct + La fonction renvoie une liste de coins par l'intermédiaire de l'IDs + chaque noeud. La liste contient en général au maximum deux coins. + """ + + logging.info("start") + + allNodeIds = maillageAScanner.GetNodesId() # On stocke tout les noeuds + listOfCorners = list() + for noeud in allNodeIds: + # On parcours la liste de noeuds + listOfElements = maillageAScanner.GetNodeInverseElements(noeud) + if len(listOfElements) >=3: + # On teste le nombre d'éléments qui partagent le même noeud + # --- Filtre selon le critère 'coplanar' --- # + listOfCriterion = [smesh.GetCriterion(SMESH.FACE, SMESH.FT_CoplanarFaces, \ + SMESH.FT_Undefined, elem, SMESH.FT_Undefined, SMESH.FT_Undefined, 30) \ + for elem in listOfElements] + listOfFilters = [smesh.GetFilterFromCriteria([criteria]) for criteria in listOfCriterion] + listOfSets = [maillageAScanner.GetIdsFromFilter(filtre) for filtre in listOfFilters] + if listOfSets.count(listOfSets[0]) == len(listOfSets): + # Si toutes les listes d'éléments sont similaires, on retourne + # au début pour éviter de travailler sur des éléments inutiles. + # Exemple : un noeud appartenant à 4 éléments sur la même face. + continue + for l_aux in listOfSets: + while listOfSets.count(l_aux) > 1: + # On supprime tant que la liste d'éléments n'est pas unique. + listOfSets.remove(l_aux) + if len(listOfSets) >= 3: + # Si on a au moins 3 listes d'élements différentes, on considère + # qu'il y a présence d'un coin. + listOfCorners.append(noeud) + + return listOfCorners def createLinesFromMesh(maillageSupport): - - """ Cette fonction permet de générer une liste de lignes à partir du - maillage support passé en paramètre. On démarre à partir d'un coin - simple et on parcourt tout les noeuds pour former une ligne. Soit la - figure ci-dessous : - - 1_____4_____7 On part du coin N1, et on cherche les noeuds - | | | successifs tels que [1, 2, 3]. Lorsqu'on arrive - | 1 | 3 | arrive sur le noeud de fin de ligne N3, on repart - | | | du noeud précédent du premier élément (E1), à - 2_____5_____8 savoir le noeud N4. On suit les noeuds succesifs - | | | [4, 5, 6] comme précédemment et ainsi de suite. - | 2 | 4 | Lorsqu'on arrive sur le dernier noeud de la - | | | dernière ligne, à savoir le noeud N9, on considère - 3_____6_____9 que toutes les lignes sont créées. - - La fonction retourne une liste de lignes utilisées par la suite. - """ - - logging.info("start") - - allNodeIds = maillageSupport.GetNodesId() - while len(allNodeIds): - nodeIds = allNodeIds - for idNode in nodeIds: # rechercher un coin - elems = maillageSupport.GetNodeInverseElements(idNode) - if len(elems) == 1: - # un coin: un noeud, un element quadrangle - elem = elems[0] - break; - idStart = idNode # le noeud de coin - elemStart = elem # l'élément quadrangle au coin - xyz = maillageSupport.GetNodeXYZ(idStart) - logging.debug("idStart %s, coords %s", idStart, str(xyz)) - - nodelines =[] # on va constituer une liste de lignes de points - nextLine = True - ligneFinale = False - while nextLine: - logging.debug("--- une ligne") - idNode = idStart - elem = elemStart - if ligneFinale: - agauche = False # sens de parcours des 4 noeuds d'un quadrangle - nextLine = False + + """ Cette fonction permet de générer une liste de lignes à partir du + maillage support passé en paramètre. On démarre à partir d'un coin + simple et on parcourt tout les noeuds pour former une ligne. Soit la + figure ci-dessous : + + 1_____4_____7 On part du coin N1, et on cherche les noeuds + | | | successifs tels que [1, 2, 3]. Lorsqu'on arrive + | 1 | 3 | arrive sur le noeud de fin de ligne N3, on repart + | | | du noeud précédent du premier élément (E1), à + 2_____5_____8 savoir le noeud N4. On suit les noeuds succesifs + | | | [4, 5, 6] comme précédemment et ainsi de suite. + | 2 | 4 | Lorsqu'on arrive sur le dernier noeud de la + | | | dernière ligne, à savoir le noeud N9, on considère + 3_____6_____9 que toutes les lignes sont créées. + + La fonction retourne une liste de lignes utilisées par la suite. + """ + + logging.info("start") + + allNodeIds = maillageSupport.GetNodesId() + while len(allNodeIds): + nodeIds = allNodeIds + for idNode in nodeIds: # rechercher un coin + elems = maillageSupport.GetNodeInverseElements(idNode) + if len(elems) == 1: + # un coin: un noeud, un element quadrangle + elem = elems[0] + idNode_c = idNode + break + idStart = idNode_c # le noeud de coin + elemStart = elem # l'élément quadrangle au coin + xyz = maillageSupport.GetNodeXYZ(idStart) + logging.debug("idStart %s, coords %s", idStart, str(xyz)) + + nodelines = list() # on va constituer une liste de lignes de points + nextLine = True + ligneFinale = False + while nextLine: + logging.debug("--- une ligne") + idNode = idStart + elem = elemStart + if ligneFinale: + agauche = False # sens de parcours des 4 noeuds d'un quadrangle + nextLine = False + else: + agauche = True + ligneIncomplete = True # on commence une ligne de points + debutLigne = True + nodeline = list() + elemline = list() + while ligneIncomplete: # compléter la ligne de points + nodeline.append(idNode) + allNodeIds.remove(idNode) + elemline.append(elem) + nodes = maillageSupport.GetElemNodes(elem) + i_aux = nodes.index(idNode) # repérer l'index du noeud courant (i_aux) dans l'élément quadrangle (0 a 3) + if agauche: # déterminer le noeud suivant (j_aux) et celui opposé (k_aux) dans le quadrangle + if i_aux < 3: + j_aux = i_aux+1 + else: + j_aux = 0 + if j_aux < 3: + k_aux = j_aux+1 + else: + k_aux = 0 + else: + if i_aux > 0: + j_aux = i_aux -1 + else: + j_aux = 3 + if j_aux > 0: + k_aux = j_aux -1 + else: + k_aux = 3 + isuiv = nodes[j_aux] # noeud suivant + iapres = nodes[k_aux] # noeud opposé + if debutLigne: + debutLigne = False + # précédent a trouver, dernière ligne : précédent au lieu de suivant + if agauche: + if i_aux > 0: + iprec = nodes[i_aux -1] else: - agauche = True - ligneIncomplete = True # on commence une ligne de points - debutLigne = True - nodeline = [] - elemline = [] - while ligneIncomplete: # compléter la ligne de points - nodeline.append(idNode) - allNodeIds.remove(idNode) - elemline.append(elem) - nodes = maillageSupport.GetElemNodes(elem) - i = nodes.index(idNode) # repérer l'index du noeud courant (i) dans l'élément quadrangle (0 a 3) - if agauche: # déterminer le noeud suivant (j) et celui opposé (k) dans le quadrangle - if i < 3: - j = i+1 - else: - j = 0 - if j < 3: - k = j+1 - else: - k = 0 - else: - if i > 0: - j = i -1 - else: - j = 3 - if j > 0: - k = j -1 - else: - k = 3 - isuiv = nodes[j] # noeud suivant - iapres = nodes[k] # noeud opposé - if debutLigne: - debutLigne = False - # précédent a trouver, dernière ligne : précédent au lieu de suivant - if agauche: - if i > 0: - iprec = nodes[i -1] - else: - iprec = nodes[3] - idStart = iprec - elems3 = maillageSupport.GetNodeInverseElements(iprec) - if len(elems3) == 1: # autre coin - ligneFinale = True - else: - for elem3 in elems3: - if elem3 != elem: - elemStart = elem3 - break - #print nodes, idNode, isuiv, iapres - elems1 = maillageSupport.GetNodeInverseElements(isuiv) - elems2 = maillageSupport.GetNodeInverseElements(iapres) - ligneIncomplete = False - for elem2 in elems2: - if elems1.count(elem2) and elem2 != elem: - ligneIncomplete = True - idNode = isuiv - elem = elem2 - break - if not ligneIncomplete: - nodeline.append(isuiv) - allNodeIds.remove(isuiv) - logging.debug("nodeline %s", nodeline) - logging.debug("elemline %s", elemline) - nodelines.append(nodeline) - - # on a constitué une liste de lignes de points connexes - logging.debug("dimensions [%s, %s]", len(nodelines), len(nodeline)) - - return nodelines - -def createNewMeshesFromCorner(maillageSupport, listOfCorners): - - """ Cette fonction permet de générer un nouveau maillage plus facile à - utiliser. On démarre d'un coin et on récupère les trois éléments - auquel le noeud appartient. Grâce à un filtre 'coplanar' sur les trois - éléments, on peut générer des faces distinctes. - """ - - logging.info("start") - - tmp = [] - listOfNewMeshes = [] - for corner in listOfCorners: - elems = maillageSupport.GetNodeInverseElements(corner) - for i, elem in enumerate(elems): - # --- Filtre selon le critère 'coplanar' --- # - critere = smesh.GetCriterion(SMESH.FACE, SMESH.FT_CoplanarFaces, \ - SMESH.FT_Undefined, elem, SMESH.FT_Undefined, SMESH.FT_Undefined, 30) - filtre = smesh.GetFilterFromCriteria([critere]) - grp = maillageSupport.GroupOnFilter(SMESH.FACE, 'grp', filtre) - # On copie le maillage en fonction du filtre - msh = smesh.CopyMesh(grp, 'new_{0}'.format(i + 1), False, True) - # On stocke l'ensemble des noeuds du maillage dans tmp - # On ajoute le maillage à la liste des nouveaux maillages - # seulement s'il n'y est pas déjà - tmp.append(msh.GetNodesId()) - if tmp.count(msh.GetNodesId()) <= 1: - listOfNewMeshes.append(msh) - return listOfNewMeshes \ No newline at end of file + iprec = nodes[3] + idStart = iprec + elems3 = maillageSupport.GetNodeInverseElements(iprec) + if len(elems3) == 1: # autre coin + ligneFinale = True + else: + for elem3 in elems3: + if elem3 != elem: + elemStart = elem3 + break + + #print nodes, idNode, isuiv, iapres + elems1 = maillageSupport.GetNodeInverseElements(isuiv) + elems2 = maillageSupport.GetNodeInverseElements(iapres) + ligneIncomplete = False + for elem2 in elems2: + if elems1.count(elem2) and elem2 != elem: + ligneIncomplete = True + idNode = isuiv + elem = elem2 + break + if not ligneIncomplete: + nodeline.append(isuiv) + allNodeIds.remove(isuiv) + logging.debug("nodeline %s", nodeline) + logging.debug("elemline %s", elemline) + nodelines.append(nodeline) + + # on a constitué une liste de lignes de points connexes + logging.debug("dimensions [%s, %s]", len(nodelines), len(nodeline)) + + return nodelines + +def createNewMeshesFromCorner(maillageSupport, listOfCorners, \ + nro_cas=None): + + """ Cette fonction permet de générer un nouveau maillage plus facile à + utiliser. On démarre d'un coin et on récupère les trois éléments + auquel le noeud appartient. Grâce à un filtre 'coplanar' sur les trois + éléments, on peut générer des faces distinctes. + """ + + logging.info("start") + + tmp = list() + listOfNewMeshes = list() + n_msh = -1 + for corner in listOfCorners: + elems = maillageSupport.GetNodeInverseElements(corner) + for elem in elems: + # --- Filtre selon le critère 'coplanar' --- # + critere = smesh.GetCriterion(SMESH.FACE, SMESH.FT_CoplanarFaces, \ + SMESH.FT_Undefined, elem, SMESH.FT_Undefined, SMESH.FT_Undefined, 30) + filtre = smesh.GetFilterFromCriteria([critere]) + n_msh += 1 + nom = "coin_{}".format(n_msh) + grp = maillageSupport.GroupOnFilter(SMESH.FACE, nom, filtre) + # On copie le maillage en fonction du filtre + msh = smesh.CopyMesh(grp, nom, False, True) + putName(msh, nom, i_pref=nro_cas) + # On stocke l'ensemble des noeuds du maillage dans tmp + # On ajoute le maillage à la liste des nouveaux maillages + # seulement s'il n'y est pas déjà + tmp.append(msh.GetNodesId()) + if ( tmp.count(msh.GetNodesId()) <= 1 ): + putName(msh, "Face", len(listOfNewMeshes), nro_cas) + listOfNewMeshes.append(msh) + + return listOfNewMeshes