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, step=-1):
88 shapeDefaut = shapesFissure[0] # faces de fissure, débordant
89 fondFiss = shapesFissure[4] # groupe d'edges de fond de fissure
91 rayonPipe = shapeFissureParams['rayonPipe']
92 if 'lenSegPipe' in shapeFissureParams:
93 lenSegPipe = shapeFissureParams['lenSegPipe']
95 lenSegPipe = rayonPipe
97 nomRep = maillageFissureParams['nomRep']
98 nomFicSain = maillageFissureParams['nomFicSain']
99 nomFicFissure = maillageFissureParams['nomFicFissure']
101 nbsegRad = maillageFissureParams['nbsegRad'] # nombre de couches selon un rayon du pipe
102 nbsegCercle = maillageFissureParams['nbsegCercle'] # nombre de secteur dans un cercle du pipe
103 areteFaceFissure = maillageFissureParams['areteFaceFissure']
105 if 'aretesVives' in maillageFissureParams:
106 lgAretesVives = maillageFissureParams['aretesVives']
111 isPointInterne = False
112 if 'pointIn_x' in shapeFissureParams:
113 pointIn_x = shapeFissureParams['pointIn_x']
114 isPointInterne = True
115 if 'pointIn_y' in shapeFissureParams:
116 pointIn_y = shapeFissureParams['pointIn_y']
117 isPointInterne = True
118 if 'pointIn_z' in shapeFissureParams:
119 pointIn_z = shapeFissureParams['pointIn_z']
120 isPointInterne = True
122 pointInterne = geompy.MakeVertex(pointIn_x, pointIn_y, pointIn_z)
126 fichierMaillageFissure = os.path.join (nomRep , '{}.med'.format(nomFicFissure))
128 # fillings des faces en peau
129 facesDefaut = elementsDefaut[0]
130 #centresDefaut = elementsDefaut[1]
131 #normalsDefaut = elementsDefaut[2]
132 #extrusionsDefaut = elementsDefaut[3]
133 dmoyen = elementsDefaut[4]
134 bordsPartages = elementsDefaut[5]
135 #fillconts = elementsDefaut[6]
136 #idFilToCont = elementsDefaut[7]
137 maillageSain = elementsDefaut[8]
138 internalBoundary = elementsDefaut[9]
139 zoneDefaut = elementsDefaut[10]
140 zoneDefaut_skin = elementsDefaut[11]
141 zoneDefaut_internalFaces = elementsDefaut[12]
142 zoneDefaut_internalEdges = elementsDefaut[13]
143 #edgeFondExt = elementsDefaut[14]
144 centreFondFiss = elementsDefaut[15]
145 #tgtCentre = elementsDefaut[16]
146 if lgAretesVives == 0:
147 lgAretesVives = dmoyen
150 O, OX, OY, OZ = triedreBase()
152 # --- restriction de la face de fissure au domaine solide :
153 # partition face fissure étendue par fillings, on garde la face interne
155 facesPortFissure = restreintFaceFissure(shapeDefaut, facesDefaut, pointInterne)
157 # --- pipe de fond de fissure, prolongé, partition face fissure par pipe
158 # identification des edges communes pipe et face fissure
160 (fissPipe, edgesPipeFiss, edgesFondFiss, wirePipeFiss, wireFondFiss) = partitionneFissureParPipe(shapesFissure, elementsDefaut, rayonPipe)
161 edgesFondFiss, edgesIdByOrientation = orderEdgesFromWire(wireFondFiss)
163 for i,edge in enumerate(edgesFondFiss):
164 geomPublishInFather(initLog.debug, wireFondFiss, edge, "edgeFondFiss%d"%i)
166 # --- peau et face de fissure
168 # --- partition peau défaut - face de fissure prolongée - wire de fond de fissure prolongée
169 # il peut y avoir plusieurs faces externes, dont certaines sont découpées par la fissure
170 # liste de faces externes : facesDefaut
171 # liste de partitions face externe - fissure : partitionPeauFissFond (None quand pas d'intersection)
173 partitionsPeauFissFond = construitPartitionsPeauFissure(facesDefaut, fissPipe)
175 # --- arêtes vives détectées (dans quadranglesToShapeNoCorner
176 # et quadranglesToShapeWithCorner)
178 aretesVivesC = compoundFromList(bordsPartages, "areteVive")
179 aretesVivesCoupees = list() # ensembles des arêtes vives identifiées sur les faces de peau dans l'itération sur partitionsPeauFissFond
181 # --- inventaire des faces de peau coupées par la fissure
182 # pour chaque face de peau : 0, 1 ou 2 faces débouchante du fond de fissure
183 # 0, 1 ou plus edges de la face de fissure externe au pipe
185 nbFacesFilling = len(partitionsPeauFissFond)
186 texte = "nbFacesFilling : {} ".format(nbFacesFilling)
189 ptEdgeFond = [ list() for i in range(nbFacesFilling)] # pour chaque face [points edge fond de fissure aux débouchés du pipe]
190 fsPipePeau = [ list() for i in range(nbFacesFilling)] # pour chaque face [faces du pipe débouchantes]
191 edRadFPiPo = [ list() for i in range(nbFacesFilling)] # pour chaque face [edge radiale des faces du pipe débouchantes ]
192 fsFissuExt = [ list() for i in range(nbFacesFilling)] # pour chaque face [faces de fissure externes au pipe]
193 edFisExtPe = [ list() for i in range(nbFacesFilling)] # pour chaque face [edge en peau des faces de fissure externes (pas subshape facePeau)]
194 edFisExtPi = [ list() for i in range(nbFacesFilling)] # pour chaque face [edge commun au pipe des faces de fissure externes]
195 facesPeaux = [None for i in range(nbFacesFilling)] # pour chaque face : la face de peau finale a mailler (percée des faces débouchantes)
196 edCircPeau = [ list() for i in range(nbFacesFilling)] # pour chaque face de peau : [subshape edge circulaire aux débouchés du pipe]
197 ptCircPeau = [ list() for i in range(nbFacesFilling)] # pour chaque face de peau : [subshape point sur edge circulaire aux débouchés du pipe]
198 gpedgeBord = [None for i in range(nbFacesFilling)] # pour chaque face de peau : groupe subshape des edges aux bords liés à la partie saine
199 gpedgeVifs = [None for i in range(nbFacesFilling)] # pour chaque face de peau : groupes subshape des edges aux arêtes vives entre fillings
200 edFissPeau = [ list() for i in range(nbFacesFilling)] # pour chaque face de peau : [subshape edge en peau des faces de fissure externes]
201 ptFisExtPi = [ list() for i in range(nbFacesFilling)] # pour chaque face de peau : [point commun edFissPeau edCircPeau]
203 for ifil, partitionPeauFissFond in enumerate(partitionsPeauFissFond):
204 if partitionPeauFissFond is not None:
205 dataPPFF,aretesVivesCoupees = identifieElementsGeometriquesPeau(ifil, partitionPeauFissFond, edgesPipeFiss,
206 edgesFondFiss, wireFondFiss, aretesVivesC,
207 facesDefaut, centreFondFiss, rayonPipe,
209 ptEdgeFond[ifil] = dataPPFF['endsEdgeFond']
210 fsPipePeau[ifil] = dataPPFF['facesPipePeau']
211 edRadFPiPo[ifil] = dataPPFF['edgeRadFacePipePeau']
212 fsFissuExt[ifil] = dataPPFF['facesFissExt']
213 edFisExtPe[ifil] = dataPPFF['edgesFissExtPeau']
214 edFisExtPi[ifil] = dataPPFF['edgesFissExtPipe']
215 facesPeaux[ifil] = dataPPFF['facePeau']
216 edCircPeau[ifil] = dataPPFF['edgesCircPeau']
217 ptCircPeau[ifil] = dataPPFF['verticesCircPeau']
218 gpedgeBord[ifil] = dataPPFF['groupEdgesBordPeau']
219 gpedgeVifs[ifil] = dataPPFF['bordsVifs']
220 edFissPeau[ifil] = dataPPFF['edgesFissurePeau']
221 ptFisExtPi[ifil] = dataPPFF['verticesPipePeau']
223 facesPipePeau = list()
224 edgeRadFacePipePeau = list()
225 for ifil in range(nbFacesFilling):
226 facesPipePeau += fsPipePeau[ifil]
227 edgeRadFacePipePeau += edRadFPiPo[ifil]
229 for i, avc in enumerate(aretesVivesCoupees):
230 name = "areteViveCoupee%d"%i
231 geomPublish(initLog.debug, avc, name)
233 # --- identification des faces et edges de fissure externe pour maillage
235 (faceFissureExterne, edgesPipeFissureExterneC, wirePipeFissureExterne, edgesPeauFissureExterneC) = \
236 identifieFacesEdgesFissureExterne(fsFissuExt, edFisExtPe, edFisExtPi, edgesPipeFiss)
238 # --- preparation maillage du pipe :
239 # - détections des points a respecter : jonction des edges/faces constituant la face de fissure externe au pipe
240 # - points sur les edges de fond de fissure et edges pipe/face fissure,
241 # - vecteurs tangents au fond de fissure (normal au disque maillé)
243 (centres, gptsdisks, raydisks) = calculePointsAxiauxPipe(edgesFondFiss, edgesIdByOrientation, facesDefaut,
244 centreFondFiss, wireFondFiss, wirePipeFiss,
245 lenSegPipe, rayonPipe, nbsegCercle, nbsegRad)
247 # --- recherche des points en trop (externes au volume à remailler)
248 # - on associe chaque extrémité du pipe à une face filling
249 # - on part des disques aux extrémités du pipe
250 # - pour chaque disque, on prend les vertices de géométrie,
251 # on marque leur position relative à la face.
252 # - on s'arrete quand tous les noeuds sont dedans
254 (idFillingFromBout, idisklim, idiskout) = elimineExtremitesPipe(ptEdgeFond, facesDefaut, centres, gptsdisks, nbsegCercle)
256 # --- construction des listes d'edges radiales sur chaque extrémité débouchante
258 (listEdges, idFacesDebouchantes) = construitEdgesRadialesDebouchantes(idisklim, idiskout, gptsdisks, raydisks,
259 facesPipePeau, edgeRadFacePipePeau, nbsegCercle)
261 # --- création des points du maillage du pipe sur la face de peau
263 (gptsdisks, idisklim) = creePointsPipePeau(listEdges, idFacesDebouchantes, idFillingFromBout,
264 ptEdgeFond, ptFisExtPi, edCircPeau, gptsdisks, idisklim, nbsegRad)
266 # --- ajustement precis des points sur edgesPipeFissureExterneC
268 gptsdisks = ajustePointsEdgePipeFissure(edgesPipeFissureExterneC, wirePipeFissureExterne, gptsdisks, idisklim)
270 # --- maillage effectif du pipe
272 (meshPipe, meshPipeGroups, edgesCircPipeGroup) = construitMaillagePipe(gptsdisks, idisklim, nbsegCercle, nbsegRad)
274 # --- edges de bord, faces défaut à respecter
276 (internalBoundary, bordsLibres, grpAretesVives) = mailleAretesEtJonction(internalBoundary, aretesVivesCoupees, lgAretesVives)
278 # --- maillage faces de fissure
280 (meshFaceFiss, grpFaceFissureExterne,
281 grpEdgesPeauFissureExterne, grpEdgesPipeFissureExterne) = mailleFacesFissure(faceFissureExterne, edgesPipeFissureExterneC, edgesPeauFissureExterneC,
282 meshPipeGroups, areteFaceFissure, rayonPipe, nbsegRad)
284 # --- maillage faces de peau
286 meshesFacesPeau = mailleFacesPeau(partitionsPeauFissFond, idFillingFromBout, facesDefaut,
287 facesPeaux, edCircPeau, ptCircPeau, gpedgeBord, gpedgeVifs, edFissPeau,
288 bordsLibres, grpEdgesPeauFissureExterne, grpAretesVives,
289 edgesCircPipeGroup, dmoyen, rayonPipe, nbsegRad)
291 # --- regroupement des maillages du défaut
293 listMeshes = [internalBoundary.GetMesh(),
295 meshFaceFiss.GetMesh()]
296 for mp in meshesFacesPeau:
297 listMeshes.append(mp.GetMesh())
299 meshBoiteDefaut = smesh.Concatenate(listMeshes, 1, 1, 1e-05,False)
300 # pour aider l'algo hexa-tetra à ne pas mettre de pyramides à l'exterieur des volumes repliés sur eux-mêmes
301 # on désigne les faces de peau en quadrangles par le groupe "skinFaces"
302 group_faceFissOutPipe = None
303 group_faceFissInPipe = None
304 groups = meshBoiteDefaut.GetGroups()
306 if grp.GetType() == SMESH.FACE:
307 if grp.GetName() == "fisOutPi":
308 group_faceFissOutPipe = grp
309 elif grp.GetName() == "fisInPi":
310 group_faceFissInPipe = grp
312 # le maillage NETGEN ne passe pas toujours ==> utiliser GHS3D
315 algo3d = meshBoiteDefaut.Tetrahedron(algo=smeshBuilder.GHS3D)
317 algo3d = meshBoiteDefaut.Tetrahedron(algo=smeshBuilder.NETGEN)
318 hypo3d = algo3d.MaxElementVolume(1000.0)
319 putName(algo3d.GetSubMesh(), "boiteDefaut")
320 putName(algo3d, "algo3d_boiteDefaut")
321 putName(meshBoiteDefaut, "boiteDefaut")
323 is_done = meshBoiteDefaut.Compute()
324 text = "meshBoiteDefaut.Compute"
326 logging.info(text+" OK")
328 text = "Erreur au calcul du maillage.\n" + text
330 raise Exception(text)
332 faceFissure = meshBoiteDefaut.GetMesh().UnionListOfGroups( [ group_faceFissOutPipe, group_faceFissInPipe ], \
334 maillageSain = enleveDefaut(maillageSain, zoneDefaut, zoneDefaut_skin,
335 zoneDefaut_internalFaces, zoneDefaut_internalEdges)
336 putName(maillageSain, nomFicSain+"_coupe")
337 _, normfiss = shapeSurFissure(facesPortFissure)
338 maillageComplet = RegroupeSainEtDefaut(maillageSain, meshBoiteDefaut, \
339 None, None, 'COMPLET', normfiss)
341 logging.info("conversion quadratique")
342 maillageComplet.ConvertToQuadratic( 1 )
343 logging.info("groupes")
344 groups = maillageComplet.GetGroups()
345 grps = [ grp for grp in groups if grp.GetName() == 'FONDFISS']
346 fond = maillageComplet.GetMesh().CreateDimGroup( grps, SMESH.NODE, 'FONDFISS' )
348 logging.info("réorientation face de fissure FACE1")
349 grps = [ grp for grp in groups if grp.GetName() == 'FACE1']
350 nb = maillageComplet.Reorient2D( grps[0], normfiss, grps[0].GetID(1))
352 logging.info("réorientation face de fissure FACE2")
353 plansim = geompy.MakePlane(O, normfiss, 10000)
354 fissnorm = geompy.MakeMirrorByPlane(normfiss, plansim)
355 grps = [ grp for grp in groups if grp.GetName() == 'FACE2']
356 nb = maillageComplet.Reorient2D( grps[0], fissnorm, grps[0].GetID(1))
357 fond = maillageComplet.GetMesh().CreateDimGroup( grps, SMESH.NODE, 'FACE2' )
359 logging.info("export maillage fini")
360 maillageComplet.ExportMED(fichierMaillageFissure)
361 putName(maillageComplet, nomFicFissure)
362 logging.info("fichier maillage fissure %s", fichierMaillageFissure)
364 if salome.sg.hasDesktop():
365 salome.sg.updateObjBrowser()
367 logging.info("maillage fissure fini")
369 return maillageComplet