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