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