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
23 from .geomsmesh import geompy
24 from .geomsmesh import geomPublish
25 from .geomsmesh import geomPublishInFather
28 from .geomsmesh import smesh
29 from salome.smesh import smeshBuilder
35 # from extractionOrientee import extractionOrientee
36 # from extractionOrienteeMulti import extractionOrienteeMulti
37 # from sortFaces import sortFaces
38 #from sortEdges import sortEdges
39 # from eliminateDoubles import eliminateDoubles
40 # from substractSubShapes import substractSubShapes
41 # from produitMixte import produitMixte
42 # from findWireEndVertices import findWireEndVertices
43 #from findWireIntermediateVertices import findWireIntermediateVertices
44 from .orderEdgesFromWire import orderEdgesFromWire
45 # from getSubshapeIds import getSubshapeIds
46 from .putName import putName
47 # from distance2 import distance2
48 from .enleveDefaut import enleveDefaut
49 from .shapeSurFissure import shapeSurFissure
50 from .regroupeSainEtDefaut import RegroupeSainEtDefaut
51 from .triedreBase import triedreBase
52 # from checkDecoupePartition import checkDecoupePartition
53 # from whichSide import whichSide
54 # from whichSideMulti import whichSideMulti
55 #from whichSideVertex import whichSideVertex
56 #from projettePointSurCourbe import projettePointSurCourbe
57 # from prolongeWire import prolongeWire
58 from .restreintFaceFissure import restreintFaceFissure
59 from .partitionneFissureParPipe import partitionneFissureParPipe
60 from .construitPartitionsPeauFissure import construitPartitionsPeauFissure
61 from .compoundFromList import compoundFromList
62 from .identifieElementsGeometriquesPeau import identifieElementsGeometriquesPeau
63 from .identifieFacesEdgesFissureExterne import identifieFacesEdgesFissureExterne
64 from .calculePointsAxiauxPipe import calculePointsAxiauxPipe
65 from .elimineExtremitesPipe import elimineExtremitesPipe
66 from .construitEdgesRadialesDebouchantes import construitEdgesRadialesDebouchantes
67 from .creePointsPipePeau import creePointsPipePeau
68 from .ajustePointsEdgePipeFissure import ajustePointsEdgePipeFissure
69 from .construitMaillagePipe import construitMaillagePipe
70 from .mailleAretesEtJonction import mailleAretesEtJonction
71 from .mailleFacesFissure import mailleFacesFissure
72 from .mailleFacesPeau import mailleFacesPeau
73 from .fissError import fissError
75 # -----------------------------------------------------------------------------
76 # --- procédure complète fissure générale
78 def construitFissureGenerale(maillagesSains,
79 shapesFissure, shapeFissureParams,
80 maillageFissureParams, elementsDefaut, step=-1):
86 shapeDefaut = shapesFissure[0] # faces de fissure, débordant
87 fondFiss = shapesFissure[4] # groupe d'edges de fond de fissure
89 rayonPipe = shapeFissureParams['rayonPipe']
90 if 'lenSegPipe' in shapeFissureParams:
91 lenSegPipe = shapeFissureParams['lenSegPipe']
93 lenSegPipe = rayonPipe
95 nomRep = maillageFissureParams['nomRep']
96 nomFicSain = maillageFissureParams['nomFicSain']
97 nomFicFissure = maillageFissureParams['nomFicFissure']
99 nbsegRad = maillageFissureParams['nbsegRad'] # nombre de couches selon un rayon du pipe
100 nbsegCercle = maillageFissureParams['nbsegCercle'] # nombre de secteur dans un cercle du pipe
101 areteFaceFissure = maillageFissureParams['areteFaceFissure']
103 if 'aretesVives' in maillageFissureParams:
104 lgAretesVives = maillageFissureParams['aretesVives']
109 isPointInterne = False
110 if 'pointIn_x' in shapeFissureParams:
111 pointIn_x = shapeFissureParams['pointIn_x']
112 isPointInterne = True
113 if 'pointIn_y' in shapeFissureParams:
114 pointIn_y = shapeFissureParams['pointIn_y']
115 isPointInterne = True
116 if 'pointIn_z' in shapeFissureParams:
117 pointIn_z = shapeFissureParams['pointIn_z']
118 isPointInterne = True
120 pointInterne = geompy.MakeVertex(pointIn_x, pointIn_y, pointIn_z)
124 #fichierMaillageSain = nomRep + '/' + nomFicSain + '.med'
125 fichierMaillageFissure = nomRep + '/' + nomFicFissure + '.med'
127 # fillings des faces en peau
128 facesDefaut = elementsDefaut[0]
129 #centresDefaut = elementsDefaut[1]
130 #normalsDefaut = elementsDefaut[2]
131 #extrusionsDefaut = elementsDefaut[3]
132 dmoyen = elementsDefaut[4]
133 bordsPartages = elementsDefaut[5]
134 #fillconts = elementsDefaut[6]
135 #idFilToCont = elementsDefaut[7]
136 maillageSain = elementsDefaut[8]
137 internalBoundary = elementsDefaut[9]
138 zoneDefaut = elementsDefaut[10]
139 zoneDefaut_skin = elementsDefaut[11]
140 zoneDefaut_internalFaces = elementsDefaut[12]
141 zoneDefaut_internalEdges = elementsDefaut[13]
142 #edgeFondExt = elementsDefaut[14]
143 centreFondFiss = elementsDefaut[15]
144 #tgtCentre = elementsDefaut[16]
145 if lgAretesVives == 0:
146 lgAretesVives = dmoyen
149 O, OX, OY, OZ = triedreBase()
151 # --- restriction de la face de fissure au domaine solide :
152 # partition face fissure étendue par fillings, on garde la face interne
154 facesPortFissure = restreintFaceFissure(shapeDefaut, facesDefaut, pointInterne)
156 # --- pipe de fond de fissure, prolongé, partition face fissure par pipe
157 # identification des edges communes pipe et face fissure
159 (fissPipe, edgesPipeFiss, edgesFondFiss, wirePipeFiss, wireFondFiss) = partitionneFissureParPipe(shapesFissure, elementsDefaut, rayonPipe)
160 edgesFondFiss, edgesIdByOrientation = orderEdgesFromWire(wireFondFiss)
161 for i,edge in enumerate(edgesFondFiss):
162 geomPublishInFather(initLog.debug, wireFondFiss, edge, "edgeFondFiss%d"%i)
164 # --- peau et face de fissure
166 # --- partition peau défaut - face de fissure prolongée - wire de fond de fissure prolongée
167 # il peut y avoir plusieurs faces externes, dont certaines sont découpées par la fissure
168 # liste de faces externes : facesDefaut
169 # liste de partitions face externe - fissure : partitionPeauFissFond (None quand pas d'intersection)
171 partitionsPeauFissFond = construitPartitionsPeauFissure(facesDefaut, fissPipe)
173 # --- arêtes vives détectées (dans quadranglesToShapeNoCorner
174 # et quadranglesToShapeWithCorner)
176 aretesVivesC = compoundFromList(bordsPartages, "areteVive")
177 aretesVivesCoupees = [] # ensembles des arêtes vives identifiées sur les faces de peau dans l'itération sur partitionsPeauFissFond
179 # --- inventaire des faces de peau coupées par la fissure
180 # pour chaque face de peau : 0, 1 ou 2 faces débouchante du fond de fissure
181 # 0, 1 ou plus edges de la face de fissure externe au pipe
183 nbFacesFilling = len(partitionsPeauFissFond)
185 ptEdgeFond = [ [] for i in range(nbFacesFilling)] # pour chaque face [points edge fond de fissure aux débouchés du pipe]
186 fsPipePeau = [ [] for i in range(nbFacesFilling)] # pour chaque face [faces du pipe débouchantes]
187 edRadFPiPo = [ [] for i in range(nbFacesFilling)] # pour chaque face [edge radiale des faces du pipe débouchantes ]
188 fsFissuExt = [ [] for i in range(nbFacesFilling)] # pour chaque face [faces de fissure externes au pipe]
189 edFisExtPe = [ [] for i in range(nbFacesFilling)] # pour chaque face [edge en peau des faces de fissure externes (pas subshape facePeau)]
190 edFisExtPi = [ [] for i in range(nbFacesFilling)] # pour chaque face [edge commun au pipe des faces de fissure externes]
191 facesPeaux = [None for i in range(nbFacesFilling)] # pour chaque face : la face de peau finale a mailler (percée des faces débouchantes)
192 edCircPeau = [ [] for i in range(nbFacesFilling)] # pour chaque face de peau : [subshape edge circulaire aux débouchés du pipe]
193 ptCircPeau = [ [] for i in range(nbFacesFilling)] # pour chaque face de peau : [subshape point sur edge circulaire aux débouchés du pipe]
194 gpedgeBord = [None for i in range(nbFacesFilling)] # pour chaque face de peau : groupe subshape des edges aux bords liés à la partie saine
195 gpedgeVifs = [None for i in range(nbFacesFilling)] # pour chaque face de peau : groupes subshape des edges aux arêtes vives entre fillings
196 edFissPeau = [ [] for i in range(nbFacesFilling)] # pour chaque face de peau : [subshape edge en peau des faces de fissure externes]
197 ptFisExtPi = [ [] for i in range(nbFacesFilling)] # pour chaque face de peau : [point commun edFissPeau edCircPeau]
199 for ifil, partitionPeauFissFond in enumerate(partitionsPeauFissFond):
200 if partitionPeauFissFond is not None:
201 dataPPFF,aretesVivesCoupees = identifieElementsGeometriquesPeau(ifil, partitionPeauFissFond, edgesPipeFiss,
202 edgesFondFiss, wireFondFiss, aretesVivesC,
203 facesDefaut, centreFondFiss, rayonPipe,
205 ptEdgeFond[ifil] = dataPPFF['endsEdgeFond']
206 fsPipePeau[ifil] = dataPPFF['facesPipePeau']
207 edRadFPiPo[ifil] = dataPPFF['edgeRadFacePipePeau']
208 fsFissuExt[ifil] = dataPPFF['facesFissExt']
209 edFisExtPe[ifil] = dataPPFF['edgesFissExtPeau']
210 edFisExtPi[ifil] = dataPPFF['edgesFissExtPipe']
211 facesPeaux[ifil] = dataPPFF['facePeau']
212 edCircPeau[ifil] = dataPPFF['edgesCircPeau']
213 ptCircPeau[ifil] = dataPPFF['verticesCircPeau']
214 gpedgeBord[ifil] = dataPPFF['groupEdgesBordPeau']
215 gpedgeVifs[ifil] = dataPPFF['bordsVifs']
216 edFissPeau[ifil] = dataPPFF['edgesFissurePeau']
217 ptFisExtPi[ifil] = dataPPFF['verticesPipePeau']
220 edgeRadFacePipePeau = []
221 for ifil in range(nbFacesFilling):
222 facesPipePeau += fsPipePeau[ifil]
223 edgeRadFacePipePeau += edRadFPiPo[ifil]
225 for i, avc in enumerate(aretesVivesCoupees):
226 name = "areteViveCoupee%d"%i
227 geomPublish(initLog.debug, avc, name)
229 # --- identification des faces et edges de fissure externe pour maillage
231 (faceFissureExterne, edgesPipeFissureExterneC,
232 wirePipeFissureExterne, edgesPeauFissureExterneC) = identifieFacesEdgesFissureExterne(fsFissuExt, edFisExtPe,
233 edFisExtPi, edgesPipeFiss)
235 # --- preparation maillage du pipe :
236 # - détections des points a respecter : jonction des edges/faces constituant la face de fissure externe au pipe
237 # - points sur les edges de fond de fissure et edges pipe/face fissure,
238 # - vecteurs tangents au fond de fissure (normal au disque maillé)
240 (centres, gptsdisks, raydisks) = calculePointsAxiauxPipe(edgesFondFiss, edgesIdByOrientation, facesDefaut,
241 centreFondFiss, wireFondFiss, wirePipeFiss,
242 lenSegPipe, rayonPipe, nbsegCercle, nbsegRad)
244 # --- recherche des points en trop (externes au volume à remailler)
245 # - on associe chaque extrémité du pipe à une face filling
246 # - on part des disques aux extrémités du pipe
247 # - pour chaque disque, on prend les vertices de géométrie,
248 # on marque leur position relative à la face.
249 # - on s'arrete quand tous les noeuds sont dedans
251 (idFillingFromBout, idisklim, idiskout) = elimineExtremitesPipe(ptEdgeFond, facesDefaut, centres, gptsdisks, nbsegCercle)
253 # --- construction des listes d'edges radiales sur chaque extrémité débouchante
255 (listEdges, idFacesDebouchantes) = construitEdgesRadialesDebouchantes(idisklim, idiskout, gptsdisks, raydisks,
256 facesPipePeau, edgeRadFacePipePeau, nbsegCercle)
258 # --- création des points du maillage du pipe sur la face de peau
260 (gptsdisks, idisklim) = creePointsPipePeau(listEdges, idFacesDebouchantes, idFillingFromBout,
261 ptEdgeFond, ptFisExtPi, edCircPeau, gptsdisks, idisklim, nbsegRad)
263 # --- ajustement precis des points sur edgesPipeFissureExterneC
265 gptsdisks = ajustePointsEdgePipeFissure(edgesPipeFissureExterneC, wirePipeFissureExterne, gptsdisks, idisklim)
267 # --- maillage effectif du pipe
269 (meshPipe, meshPipeGroups, edgesCircPipeGroup) = construitMaillagePipe(gptsdisks, idisklim, nbsegCercle, nbsegRad)
271 # --- edges de bord, faces défaut à respecter
273 (internalBoundary, bordsLibres, grpAretesVives) = mailleAretesEtJonction(internalBoundary, aretesVivesCoupees, lgAretesVives)
275 # --- maillage faces de fissure
277 (meshFaceFiss, grpFaceFissureExterne,
278 grpEdgesPeauFissureExterne, grpEdgesPipeFissureExterne) = mailleFacesFissure(faceFissureExterne, edgesPipeFissureExterneC, edgesPeauFissureExterneC,
279 meshPipeGroups, areteFaceFissure, rayonPipe, nbsegRad)
281 # --- maillage faces de peau
283 meshesFacesPeau = mailleFacesPeau(partitionsPeauFissFond, idFillingFromBout, facesDefaut,
284 facesPeaux, edCircPeau, ptCircPeau, gpedgeBord, gpedgeVifs, edFissPeau,
285 bordsLibres, grpEdgesPeauFissureExterne, grpAretesVives,
286 edgesCircPipeGroup, dmoyen, rayonPipe, nbsegRad)
288 # --- regroupement des maillages du défaut
290 listMeshes = [internalBoundary.GetMesh(),
292 meshFaceFiss.GetMesh()]
293 for mp in meshesFacesPeau:
294 listMeshes.append(mp.GetMesh())
296 meshBoiteDefaut = smesh.Concatenate(listMeshes, 1, 1, 1e-05,False)
297 # pour aider l'algo hexa-tetra à ne pas mettre de pyramides à l'exterieur des volumes repliés sur eux-mêmes
298 # on désigne les faces de peau en quadrangles par le groupe "skinFaces"
299 group_faceFissOutPipe = None
300 group_faceFissInPipe = None
301 groups = meshBoiteDefaut.GetGroups()
303 if grp.GetType() == SMESH.FACE:
304 if grp.GetName() == "fisOutPi":
305 group_faceFissOutPipe = grp
306 elif grp.GetName() == "fisInPi":
307 group_faceFissInPipe = grp
309 # le maillage NETGEN ne passe pas toujours ==> utiliser GHS3D
312 algo3d = meshBoiteDefaut.Tetrahedron(algo=smeshBuilder.GHS3D)
314 algo3d = meshBoiteDefaut.Tetrahedron(algo=smeshBuilder.NETGEN)
315 hypo3d = algo3d.MaxElementVolume(1000.0)
316 putName(algo3d.GetSubMesh(), "boiteDefaut")
317 putName(algo3d, "algo3d_boiteDefaut")
318 isDone = meshBoiteDefaut.Compute()
319 putName(meshBoiteDefaut, "boiteDefaut")
320 logging.info("meshBoiteDefaut fini")
322 faceFissure = meshBoiteDefaut.GetMesh().UnionListOfGroups( [ group_faceFissOutPipe, group_faceFissInPipe ], 'FACE1' )
323 maillageSain = enleveDefaut(maillageSain, zoneDefaut, zoneDefaut_skin,
324 zoneDefaut_internalFaces, zoneDefaut_internalEdges)
325 putName(maillageSain, nomFicSain+"_coupe")
326 extrusionFaceFissure, normfiss = shapeSurFissure(facesPortFissure)
327 maillageComplet = RegroupeSainEtDefaut(maillageSain, meshBoiteDefaut,
328 None, None, 'COMPLET', normfiss)
330 logging.info("conversion quadratique")
331 maillageComplet.ConvertToQuadratic( 1 )
332 logging.info("groupes")
333 groups = maillageComplet.GetGroups()
334 grps = [ grp for grp in groups if grp.GetName() == 'FONDFISS']
335 fond = maillageComplet.GetMesh().CreateDimGroup( grps, SMESH.NODE, 'FONDFISS' )
337 logging.info("réorientation face de fissure FACE1")
338 grps = [ grp for grp in groups if grp.GetName() == 'FACE1']
339 nb = maillageComplet.Reorient2D( grps[0], normfiss, grps[0].GetID(1))
341 logging.info("réorientation face de fissure FACE2")
342 plansim = geompy.MakePlane(O, normfiss, 10000)
343 fissnorm = geompy.MakeMirrorByPlane(normfiss, plansim)
344 grps = [ grp for grp in groups if grp.GetName() == 'FACE2']
345 nb = maillageComplet.Reorient2D( grps[0], fissnorm, grps[0].GetID(1))
346 fond = maillageComplet.GetMesh().CreateDimGroup( grps, SMESH.NODE, 'FACE2' )
348 logging.info("export maillage fini")
349 maillageComplet.ExportMED(fichierMaillageFissure)
350 putName(maillageComplet, nomFicFissure)
351 logging.info("fichier maillage fissure %s", fichierMaillageFissure)
353 if salome.sg.hasDesktop():
354 salome.sg.updateObjBrowser()
356 logging.info("maillage fissure fini")
358 return maillageComplet