1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2014-2020 EDF R&D
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.
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.
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
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
25 from .geomsmesh import geompy
26 from .geomsmesh import geomPublish
27 from .geomsmesh import geomPublishInFather
30 from .geomsmesh import smesh
31 from salome.smesh import smeshBuilder
37 # from extractionOrientee import extractionOrientee
38 # from extractionOrienteeMulti import extractionOrienteeMulti
39 # from sortFaces import sortFaces
40 #from sortEdges import sortEdges
41 # from eliminateDoubles import eliminateDoubles
42 # from substractSubShapes import substractSubShapes
43 # from produitMixte import produitMixte
44 # from findWireEndVertices import findWireEndVertices
45 #from findWireIntermediateVertices import findWireIntermediateVertices
46 from .orderEdgesFromWire import orderEdgesFromWire
47 # from getSubshapeIds import getSubshapeIds
48 from .putName import putName
49 # from distance2 import distance2
50 from .enleveDefaut import enleveDefaut
51 from .shapeSurFissure import shapeSurFissure
52 from .regroupeSainEtDefaut import RegroupeSainEtDefaut
53 from .triedreBase import triedreBase
54 # from checkDecoupePartition import checkDecoupePartition
55 # from whichSide import whichSide
56 # from whichSideMulti import whichSideMulti
57 #from whichSideVertex import whichSideVertex
58 #from projettePointSurCourbe import projettePointSurCourbe
59 # from prolongeWire import prolongeWire
60 from .restreintFaceFissure import restreintFaceFissure
61 from .partitionneFissureParPipe import partitionneFissureParPipe
62 from .construitPartitionsPeauFissure import construitPartitionsPeauFissure
63 from .compoundFromList import compoundFromList
64 from .identifieElementsGeometriquesPeau import identifieElementsGeometriquesPeau
65 from .identifieFacesEdgesFissureExterne import identifieFacesEdgesFissureExterne
66 from .calculePointsAxiauxPipe import calculePointsAxiauxPipe
67 from .elimineExtremitesPipe import elimineExtremitesPipe
68 from .construitEdgesRadialesDebouchantes import construitEdgesRadialesDebouchantes
69 from .creePointsPipePeau import creePointsPipePeau
70 from .ajustePointsEdgePipeFissure import ajustePointsEdgePipeFissure
71 from .construitMaillagePipe import construitMaillagePipe
72 from .mailleAretesEtJonction import mailleAretesEtJonction
73 from .mailleFacesFissure import mailleFacesFissure
74 from .mailleFacesPeau import mailleFacesPeau
75 from .fissError import fissError
77 # -----------------------------------------------------------------------------
78 # --- procédure complète fissure générale
80 def construitFissureGenerale(maillagesSains, \
81 shapesFissure, shapeFissureParams, \
82 maillageFissureParams, elementsDefaut, \
83 step=-1, mailleur="MeshGems"):
88 logging.info(mailleur)
90 shapeDefaut = shapesFissure[0] # faces de fissure, débordant
91 fondFiss = shapesFissure[4] # groupe d'edges de fond de fissure
93 rayonPipe = shapeFissureParams['rayonPipe']
94 if 'lenSegPipe' in shapeFissureParams:
95 lenSegPipe = shapeFissureParams['lenSegPipe']
97 lenSegPipe = rayonPipe
99 nomRep = maillageFissureParams['nomRep']
100 nomFicSain = maillageFissureParams['nomFicSain']
101 nomFicFissure = maillageFissureParams['nomFicFissure']
103 nbsegRad = maillageFissureParams['nbsegRad'] # nombre de couches selon un rayon du pipe
104 nbsegCercle = maillageFissureParams['nbsegCercle'] # nombre de secteur dans un cercle du pipe
105 areteFaceFissure = maillageFissureParams['areteFaceFissure']
107 if 'aretesVives' in maillageFissureParams:
108 lgAretesVives = maillageFissureParams['aretesVives']
113 isPointInterne = False
114 if 'pointIn_x' in shapeFissureParams:
115 pointIn_x = shapeFissureParams['pointIn_x']
116 isPointInterne = True
117 if 'pointIn_y' in shapeFissureParams:
118 pointIn_y = shapeFissureParams['pointIn_y']
119 isPointInterne = True
120 if 'pointIn_z' in shapeFissureParams:
121 pointIn_z = shapeFissureParams['pointIn_z']
122 isPointInterne = True
124 pointInterne = geompy.MakeVertex(pointIn_x, pointIn_y, pointIn_z)
128 fichierMaillageFissure = os.path.join (nomRep , '{}.med'.format(nomFicFissure))
130 # fillings des faces en peau
131 facesDefaut = elementsDefaut[0]
132 #centresDefaut = elementsDefaut[1]
133 #normalsDefaut = elementsDefaut[2]
134 #extrusionsDefaut = elementsDefaut[3]
135 dmoyen = elementsDefaut[4]
136 bordsPartages = elementsDefaut[5]
137 #fillconts = elementsDefaut[6]
138 #idFilToCont = elementsDefaut[7]
139 maillageSain = elementsDefaut[8]
140 internalBoundary = elementsDefaut[9]
141 zoneDefaut = elementsDefaut[10]
142 zoneDefaut_skin = elementsDefaut[11]
143 zoneDefaut_internalFaces = elementsDefaut[12]
144 zoneDefaut_internalEdges = elementsDefaut[13]
145 #edgeFondExt = elementsDefaut[14]
146 centreFondFiss = elementsDefaut[15]
147 #tgtCentre = elementsDefaut[16]
148 if lgAretesVives == 0:
149 lgAretesVives = dmoyen
152 O, OX, OY, OZ = triedreBase()
154 # --- restriction de la face de fissure au domaine solide :
155 # partition face fissure étendue par fillings, on garde la face interne
157 facesPortFissure = restreintFaceFissure(shapeDefaut, facesDefaut, pointInterne)
159 # --- pipe de fond de fissure, prolongé, partition face fissure par pipe
160 # identification des edges communes pipe et face fissure
162 (fissPipe, edgesPipeFiss, edgesFondFiss, wirePipeFiss, wireFondFiss) = partitionneFissureParPipe(shapesFissure, elementsDefaut, rayonPipe)
163 edgesFondFiss, edgesIdByOrientation = orderEdgesFromWire(wireFondFiss)
165 for i,edge in enumerate(edgesFondFiss):
166 geomPublishInFather(initLog.debug, wireFondFiss, edge, "edgeFondFiss%d"%i)
168 # --- peau et face de fissure
170 # --- partition peau défaut - face de fissure prolongée - wire de fond de fissure prolongée
171 # il peut y avoir plusieurs faces externes, dont certaines sont découpées par la fissure
172 # liste de faces externes : facesDefaut
173 # liste de partitions face externe - fissure : partitionPeauFissFond (None quand pas d'intersection)
175 partitionsPeauFissFond = construitPartitionsPeauFissure(facesDefaut, fissPipe)
177 # --- arêtes vives détectées (dans quadranglesToShapeNoCorner
178 # et quadranglesToShapeWithCorner)
180 aretesVivesC = compoundFromList(bordsPartages, "areteVive")
181 aretesVivesCoupees = list() # ensembles des arêtes vives identifiées sur les faces de peau dans l'itération sur partitionsPeauFissFond
183 # --- inventaire des faces de peau coupées par la fissure
184 # pour chaque face de peau : 0, 1 ou 2 faces débouchante du fond de fissure
185 # 0, 1 ou plus edges de la face de fissure externe au pipe
187 nbFacesFilling = len(partitionsPeauFissFond)
188 texte = "nbFacesFilling : {} ".format(nbFacesFilling)
191 ptEdgeFond = [ list() for i in range(nbFacesFilling)] # pour chaque face [points edge fond de fissure aux débouchés du pipe]
192 fsPipePeau = [ list() for i in range(nbFacesFilling)] # pour chaque face [faces du pipe débouchantes]
193 edRadFPiPo = [ list() for i in range(nbFacesFilling)] # pour chaque face [edge radiale des faces du pipe débouchantes ]
194 fsFissuExt = [ list() for i in range(nbFacesFilling)] # pour chaque face [faces de fissure externes au pipe]
195 edFisExtPe = [ list() for i in range(nbFacesFilling)] # pour chaque face [edge en peau des faces de fissure externes (pas subshape facePeau)]
196 edFisExtPi = [ list() for i in range(nbFacesFilling)] # pour chaque face [edge commun au pipe des faces de fissure externes]
197 facesPeaux = [None for i in range(nbFacesFilling)] # pour chaque face : la face de peau finale a mailler (percée des faces débouchantes)
198 edCircPeau = [ list() for i in range(nbFacesFilling)] # pour chaque face de peau : [subshape edge circulaire aux débouchés du pipe]
199 ptCircPeau = [ list() for i in range(nbFacesFilling)] # pour chaque face de peau : [subshape point sur edge circulaire aux débouchés du pipe]
200 gpedgeBord = [None for i in range(nbFacesFilling)] # pour chaque face de peau : groupe subshape des edges aux bords liés à la partie saine
201 gpedgeVifs = [None for i in range(nbFacesFilling)] # pour chaque face de peau : groupes subshape des edges aux arêtes vives entre fillings
202 edFissPeau = [ list() for i in range(nbFacesFilling)] # pour chaque face de peau : [subshape edge en peau des faces de fissure externes]
203 ptFisExtPi = [ list() for i in range(nbFacesFilling)] # pour chaque face de peau : [point commun edFissPeau edCircPeau]
205 for ifil, partitionPeauFissFond in enumerate(partitionsPeauFissFond):
206 if partitionPeauFissFond is not None:
207 dataPPFF,aretesVivesCoupees = identifieElementsGeometriquesPeau(ifil, partitionPeauFissFond, edgesPipeFiss,
208 edgesFondFiss, wireFondFiss, aretesVivesC,
209 facesDefaut, centreFondFiss, rayonPipe,
211 ptEdgeFond[ifil] = dataPPFF['endsEdgeFond']
212 fsPipePeau[ifil] = dataPPFF['facesPipePeau']
213 edRadFPiPo[ifil] = dataPPFF['edgeRadFacePipePeau']
214 fsFissuExt[ifil] = dataPPFF['facesFissExt']
215 edFisExtPe[ifil] = dataPPFF['edgesFissExtPeau']
216 edFisExtPi[ifil] = dataPPFF['edgesFissExtPipe']
217 facesPeaux[ifil] = dataPPFF['facePeau']
218 edCircPeau[ifil] = dataPPFF['edgesCircPeau']
219 ptCircPeau[ifil] = dataPPFF['verticesCircPeau']
220 gpedgeBord[ifil] = dataPPFF['groupEdgesBordPeau']
221 gpedgeVifs[ifil] = dataPPFF['bordsVifs']
222 edFissPeau[ifil] = dataPPFF['edgesFissurePeau']
223 ptFisExtPi[ifil] = dataPPFF['verticesPipePeau']
225 facesPipePeau = list()
226 edgeRadFacePipePeau = list()
227 for ifil in range(nbFacesFilling):
228 facesPipePeau += fsPipePeau[ifil]
229 edgeRadFacePipePeau += edRadFPiPo[ifil]
231 for i, avc in enumerate(aretesVivesCoupees):
232 name = "areteViveCoupee%d"%i
233 geomPublish(initLog.debug, avc, name)
235 # --- identification des faces et edges de fissure externe pour maillage
237 (faceFissureExterne, edgesPipeFissureExterneC, wirePipeFissureExterne, edgesPeauFissureExterneC) = \
238 identifieFacesEdgesFissureExterne(fsFissuExt, edFisExtPe, edFisExtPi, edgesPipeFiss)
240 # --- preparation maillage du pipe :
241 # - détections des points a respecter : jonction des edges/faces constituant la face de fissure externe au pipe
242 # - points sur les edges de fond de fissure et edges pipe/face fissure,
243 # - vecteurs tangents au fond de fissure (normal au disque maillé)
245 (centres, gptsdisks, raydisks) = calculePointsAxiauxPipe(edgesFondFiss, edgesIdByOrientation, facesDefaut,
246 centreFondFiss, wireFondFiss, wirePipeFiss,
247 lenSegPipe, rayonPipe, nbsegCercle, nbsegRad)
249 # --- recherche des points en trop (externes au volume à remailler)
250 # - on associe chaque extrémité du pipe à une face filling
251 # - on part des disques aux extrémités du pipe
252 # - pour chaque disque, on prend les vertices de géométrie,
253 # on marque leur position relative à la face.
254 # - on s'arrete quand tous les noeuds sont dedans
256 (idFillingFromBout, idisklim, idiskout) = elimineExtremitesPipe(ptEdgeFond, facesDefaut, centres, gptsdisks, nbsegCercle)
258 # --- construction des listes d'edges radiales sur chaque extrémité débouchante
260 (listEdges, idFacesDebouchantes) = construitEdgesRadialesDebouchantes(idisklim, idiskout, gptsdisks, raydisks,
261 facesPipePeau, edgeRadFacePipePeau, nbsegCercle)
263 # --- création des points du maillage du pipe sur la face de peau
265 (gptsdisks, idisklim) = creePointsPipePeau(listEdges, idFacesDebouchantes, idFillingFromBout,
266 ptEdgeFond, ptFisExtPi, edCircPeau, gptsdisks, idisklim, nbsegRad)
268 # --- ajustement precis des points sur edgesPipeFissureExterneC
270 gptsdisks = ajustePointsEdgePipeFissure(edgesPipeFissureExterneC, wirePipeFissureExterne, gptsdisks, idisklim)
272 # --- maillage effectif du pipe
274 (meshPipe, meshPipeGroups, edgesCircPipeGroup) = construitMaillagePipe(gptsdisks, idisklim, nbsegCercle, nbsegRad)
276 # --- edges de bord, faces défaut à respecter
278 (internalBoundary, bordsLibres, grpAretesVives) = mailleAretesEtJonction(internalBoundary, aretesVivesCoupees, lgAretesVives)
280 # --- maillage faces de fissure
282 (meshFaceFiss, grpFaceFissureExterne, grpEdgesPeauFissureExterne, grpEdgesPipeFissureExterne) = \
283 mailleFacesFissure(faceFissureExterne, \
284 edgesPipeFissureExterneC, edgesPeauFissureExterneC, \
285 meshPipeGroups, areteFaceFissure, rayonPipe, nbsegRad, \
288 # --- maillage faces de peau
290 meshesFacesPeau = mailleFacesPeau(partitionsPeauFissFond, idFillingFromBout, facesDefaut, \
291 facesPeaux, edCircPeau, ptCircPeau, gpedgeBord, gpedgeVifs, edFissPeau, \
292 bordsLibres, grpEdgesPeauFissureExterne, grpAretesVives, \
293 edgesCircPipeGroup, dmoyen, rayonPipe, nbsegRad, \
296 # --- regroupement des maillages du défaut
298 listMeshes = [internalBoundary.GetMesh(),
300 meshFaceFiss.GetMesh()]
301 for mp in meshesFacesPeau:
302 listMeshes.append(mp.GetMesh())
304 meshBoiteDefaut = smesh.Concatenate(listMeshes, 1, 1, 1e-05,False)
305 # pour aider l'algo hexa-tetra à ne pas mettre de pyramides à l'exterieur des volumes repliés sur eux-mêmes
306 # on désigne les faces de peau en quadrangles par le groupe "skinFaces"
307 group_faceFissOutPipe = None
308 group_faceFissInPipe = None
309 groups = meshBoiteDefaut.GetGroups()
311 if grp.GetType() == SMESH.FACE:
312 if grp.GetName() == "fisOutPi":
313 group_faceFissOutPipe = grp
314 elif grp.GetName() == "fisInPi":
315 group_faceFissInPipe = grp
317 # le maillage NETGEN ne passe pas toujours ==> on force l'usage de MG_Tetra
318 mailleur = "MeshGems"
319 logging.info("Maillage avec %s", mailleur)
320 if ( mailleur == "MeshGems"):
321 algo3d = meshBoiteDefaut.Tetrahedron(algo=smeshBuilder.MG_Tetra)
323 algo3d = meshBoiteDefaut.Tetrahedron(algo=smeshBuilder.NETGEN)
324 hypo3d = algo3d.MaxElementVolume(1000.0)
325 hypo3d.SetVerboseLevel( 0 )
326 hypo3d.SetStandardOutputLog( 0 )
327 hypo3d.SetRemoveLogOnSuccess( 1 )
328 putName(algo3d.GetSubMesh(), "boiteDefaut")
329 putName(algo3d, "algo3d_boiteDefaut")
330 putName(meshBoiteDefaut, "boiteDefaut")
332 is_done = meshBoiteDefaut.Compute()
333 text = "meshBoiteDefaut.Compute"
335 logging.info(text+" OK")
337 text = "Erreur au calcul du maillage.\n" + text
339 raise Exception(text)
341 faceFissure = meshBoiteDefaut.GetMesh().UnionListOfGroups( [ group_faceFissOutPipe, group_faceFissInPipe ], \
343 maillageSain = enleveDefaut(maillageSain, zoneDefaut, zoneDefaut_skin,
344 zoneDefaut_internalFaces, zoneDefaut_internalEdges)
345 putName(maillageSain, nomFicSain+"_coupe")
346 _, normfiss = shapeSurFissure(facesPortFissure)
347 maillageComplet = RegroupeSainEtDefaut(maillageSain, meshBoiteDefaut, \
348 None, None, 'COMPLET', normfiss)
350 logging.info("conversion quadratique")
351 maillageComplet.ConvertToQuadratic( 1 )
352 logging.info("groupes")
353 groups = maillageComplet.GetGroups()
354 grps = [ grp for grp in groups if grp.GetName() == 'FONDFISS']
355 fond = maillageComplet.GetMesh().CreateDimGroup( grps, SMESH.NODE, 'FONDFISS' )
357 logging.info("réorientation face de fissure FACE1")
358 grps = [ grp for grp in groups if grp.GetName() == 'FACE1']
359 nb = maillageComplet.Reorient2D( grps[0], normfiss, grps[0].GetID(1))
361 logging.info("réorientation face de fissure FACE2")
362 plansim = geompy.MakePlane(O, normfiss, 10000)
363 fissnorm = geompy.MakeMirrorByPlane(normfiss, plansim)
364 grps = [ grp for grp in groups if grp.GetName() == 'FACE2']
365 nb = maillageComplet.Reorient2D( grps[0], fissnorm, grps[0].GetID(1))
366 fond = maillageComplet.GetMesh().CreateDimGroup( grps, SMESH.NODE, 'FACE2' )
368 logging.info("export maillage fini")
369 maillageComplet.ExportMED(fichierMaillageFissure)
370 putName(maillageComplet, nomFicFissure)
371 logging.info("fichier maillage fissure %s", fichierMaillageFissure)
373 if salome.sg.hasDesktop():
374 salome.sg.updateObjBrowser()
376 logging.info("maillage fissure fini")
378 return maillageComplet