Salome HOME
64aad5642de86896037dfc7e63450f2551dff7f6
[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
42 # -----------------------------------------------------------------------------
43 # --- procédure complète fissure générale
44
45 def construitFissureGenerale(maillagesSains,
46                              shapesFissure, shapeFissureParams,
47                              maillageFissureParams, elementsDefaut, step=-1):
48   """
49   TODO: a completer
50   """
51   logging.info('start')
52   
53   shapeDefaut       = shapesFissure[0] # faces de fissure, débordant
54   fondFiss          = shapesFissure[4] # groupe d'edges de fond de fissure
55
56   rayonPipe = shapeFissureParams['rayonPipe']
57   if shapeFissureParams.has_key('lenSegPipe'):
58     lenSegPipe = shapeFissureParams['lenSegPipe']
59   else:
60     lenSegPipe = rayonPipe
61
62   nomRep            = maillageFissureParams['nomRep']
63   nomFicSain        = maillageFissureParams['nomFicSain']
64   nomFicFissure     = maillageFissureParams['nomFicFissure']
65
66   nbsegRad          = maillageFissureParams['nbsegRad']      # nombre de couches selon un rayon du pipe
67   nbsegCercle       = maillageFissureParams['nbsegCercle']   # nombre de secteur dans un cercle du pipe
68   areteFaceFissure  = maillageFissureParams['areteFaceFissure']
69
70   pointIn_x = 0.0
71   pointIn_y = 0.0
72   pointIn_z = 0.0
73   isPointInterne = False
74   if shapeFissureParams.has_key('pointIn_x'):
75     pointIn_x = shapeFissureParams['pointIn_x']
76     isPointInterne = True
77   if shapeFissureParams.has_key('pointIn_y'):
78     pointIn_y = shapeFissureParams['pointIn_y']
79     isPointInterne = True
80   if shapeFissureParams.has_key('pointIn_z'):
81     pointIn_z = shapeFissureParams['pointIn_z']
82     isPointInterne = True
83   if isPointInterne:
84     pointInterne = geompy.MakeVertex(pointIn_x, pointIn_y, pointIn_z)
85   else:
86     pointInterne = None
87
88   #fichierMaillageSain = nomRep + '/' + nomFicSain + '.med'
89   fichierMaillageFissure = nomRep + '/' + nomFicFissure + '.med'
90
91   # fillings des faces en peau
92   facesDefaut = elementsDefaut[0]
93   #centresDefaut            = elementsDefaut[1]
94   #normalsDefaut            = elementsDefaut[2]
95   #extrusionsDefaut         = elementsDefaut[3]
96   dmoyen                   = elementsDefaut[4]
97   bordsPartages = elementsDefaut[5]
98   fillconts                = elementsDefaut[6]
99   idFilToCont              = elementsDefaut[7]
100   maillageSain             = elementsDefaut[8]
101   internalBoundary         = elementsDefaut[9]
102   zoneDefaut               = elementsDefaut[10]
103   zoneDefaut_skin          = elementsDefaut[11]
104   zoneDefaut_internalFaces = elementsDefaut[12]
105   zoneDefaut_internalEdges = elementsDefaut[13]
106   edgeFondExt              = elementsDefaut[14]
107   centreFondFiss           = elementsDefaut[15]
108   tgtCentre                = elementsDefaut[16]
109
110   O, OX, OY, OZ = triedreBase()
111
112   # --- restriction de la face de fissure au domaine solide :
113   #     partition face fissure étendue par fillings, on garde la face interne
114   
115   facesPortFissure = restreintFaceFissure(shapeDefaut, facesDefaut, pointInterne)
116  
117   # --- pipe de fond de fissure, prolongé, partition face fissure par pipe
118   #     identification des edges communes pipe et face fissure
119   
120   (fissPipe, edgesPipeFiss, edgesFondFiss, wirePipeFiss, wireFondFiss) = partitionneFissureParPipe(shapesFissure, elementsDefaut, rayonPipe)
121   edgesFondFiss, edgesIdByOrientation = orderEdgesFromWire(wireFondFiss)
122   for i,edge in enumerate(edgesFondFiss):
123     geompy.addToStudyInFather(wireFondFiss, edge, "edgeFondFiss%d"%i)
124   
125   # --- peau et face de fissure
126   #
127   # --- partition peau défaut - face de fissure prolongée - wire de fond de fissure prolongée
128   #     il peut y avoir plusieurs faces externes, dont certaines sont découpées par la fissure
129   #     liste de faces externes : facesDefaut
130   #     liste de partitions face externe - fissure : partitionPeauFissFond (None quand pas d'intersection)
131
132   partitionsPeauFissFond = construitPartitionsPeauFissure(facesDefaut, fissPipe)
133     
134   # --- arêtes vives détectées (dans quadranglesToShapeNoCorner
135   #                             et quadranglesToShapeWithCorner)
136     
137   aretesVivesCoupees = []  #= global
138   
139   aretesVivesC = compoundFromList(bordsPartages, "areteVive")
140  
141   # -------------------------------------------------------
142   # --- inventaire des faces de peau coupées par la fissure
143   #     pour chaque face de peau : 0, 1 ou 2 faces débouchante du fond de fissure
144   #                                0, 1 ou plus edges de la face de fissure externe au pipe
145   
146   nbFacesFilling = len(partitionsPeauFissFond)
147   
148   ptEdgeFond = [ []  for i in range(nbFacesFilling)] # pour chaque face [points edge fond de fissure aux débouchés du pipe]
149   fsPipePeau = [ []  for i in range(nbFacesFilling)] # pour chaque face [faces du pipe débouchantes]
150   edRadFPiPo = [ []  for i in range(nbFacesFilling)] # pour chaque face [edge radiale des faces du pipe débouchantes ]
151   fsFissuExt = [ []  for i in range(nbFacesFilling)] # pour chaque face [faces de fissure externes au pipe]
152   edFisExtPe = [ []  for i in range(nbFacesFilling)] # pour chaque face [edge en peau des faces de fissure externes (pas subshape facePeau)]
153   edFisExtPi = [ []  for i in range(nbFacesFilling)] # pour chaque face [edge commun au pipe des faces de fissure externes]
154   facesPeaux = [None for i in range(nbFacesFilling)] # pour chaque face : la face de peau finale a mailler (percée des faces débouchantes)
155   edCircPeau = [ []  for i in range(nbFacesFilling)] # pour chaque face de peau : [subshape edge circulaire aux débouchés du pipe]
156   ptCircPeau = [ []  for i in range(nbFacesFilling)] # pour chaque face de peau : [subshape point sur edge circulaire aux débouchés du pipe]
157   gpedgeBord = [None for i in range(nbFacesFilling)] # pour chaque face de peau : groupe subshape des edges aux bords liés à la partie saine
158   gpedgeVifs = [None for i in range(nbFacesFilling)] # pour chaque face de peau : groupes subshape des edges aux arêtes vives entre fillings
159   edFissPeau = [ []  for i in range(nbFacesFilling)] # pour chaque face de peau : [subshape edge en peau des faces de fissure externes]
160   ptFisExtPi = [ []  for i in range(nbFacesFilling)] # pour chaque face de peau : [point commun edFissPeau edCircPeau]
161   
162   for ifil, partitionPeauFissFond in enumerate(partitionsPeauFissFond):
163     if partitionPeauFissFond is not None:
164       dataPPFF,aretesVivesCoupees = identifieElementsGeometriquesPeau(ifil, partitionPeauFissFond, edgesPipeFiss,
165                                                                       edgesFondFiss, wireFondFiss, aretesVivesC,
166                                                                       facesDefaut, centreFondFiss, rayonPipe,
167                                                                       aretesVivesCoupees)
168       
169       ptEdgeFond[ifil] = dataPPFF['endsEdgeFond']
170       fsPipePeau[ifil] = dataPPFF['facesPipePeau']
171       edRadFPiPo[ifil] = dataPPFF['edgeRadFacePipePeau']
172       fsFissuExt[ifil] = dataPPFF['facesFissExt']
173       edFisExtPe[ifil] = dataPPFF['edgesFissExtPeau']
174       edFisExtPi[ifil] = dataPPFF['edgesFissExtPipe']
175       facesPeaux[ifil] = dataPPFF['facePeau']
176       edCircPeau[ifil] = dataPPFF['edgesCircPeau']
177       ptCircPeau[ifil] = dataPPFF['verticesCircPeau']
178       gpedgeBord[ifil] = dataPPFF['groupEdgesBordPeau']
179       gpedgeVifs[ifil] = dataPPFF['bordsVifs']
180       edFissPeau[ifil] = dataPPFF['edgesFissurePeau']
181       ptFisExtPi[ifil] = dataPPFF['verticesPipePeau']
182
183   # -----------------------------------------------------------------------
184   # fin de la boucle sur les faces de filling
185   # -----------------------------------------------------------------------
186   
187   for i, avc in enumerate(aretesVivesCoupees):
188     name = "areteViveCoupee%d"%i
189     geompy.addToStudy(avc, name)
190   
191   # --- identification des faces et edges de fissure externe pour maillage
192   
193   facesFissExt = []
194   edgesFissExtPeau = []
195   edgesFissExtPipe = []
196   for ifil in range(nbFacesFilling): # TODO: éliminer les doublons (comparer tous les vertices triés, avec mesure de distance ?)
197     facesFissExt += fsFissuExt[ifil]
198     edgesFissExtPeau += edFisExtPe[ifil]
199     edgesFissExtPipe += edFisExtPi[ifil]
200   logging.debug("---------------------------- identification faces de fissure externes au pipe :%s ", len(facesFissExt))
201   # regroupement des faces de fissure externes au pipe.
202   
203   if len(facesFissExt) > 1:
204     faceFissureExterne = geompy.MakePartition(facesFissExt, [], [], [], geompy.ShapeType["FACE"], 0, [], 0)
205     edgesPipeFissureExterneC = geompy.GetInPlace(faceFissureExterne, geompy.MakeCompound(edgesPipeFiss))    # edgesFissExtPipe peut ne pas couvrir toute la longueur
206     # edgesPeauFissureExterneC = geompy.GetInPlace(faceFissureExterne, geompy.MakeCompound(edgesFissExtPeau))
207     # il peut manquer des edges de faceFissureExterne en contact avec la peau dans edgesFissExtPeau
208     (isDone, closedFreeBoundaries, openFreeBoundaries) = geompy.GetFreeBoundary(faceFissureExterne)
209     edgesBordFFE = []
210     for bound in closedFreeBoundaries:
211       edgesBordFFE += geompy.ExtractShapes(bound, geompy.ShapeType["EDGE"], False)
212     edgesBordFFEid = [ (ed,geompy.GetSubShapeID(faceFissureExterne, ed)) for ed in edgesBordFFE]
213     logging.debug("edgesBordFFEid %s", edgesBordFFEid)
214     edgesPPE = geompy.ExtractShapes(edgesPipeFissureExterneC, geompy.ShapeType["EDGE"], False)
215     edgesPPEid = [ geompy.GetSubShapeID(faceFissureExterne, ed) for ed in edgesPPE]
216     logging.debug("edgesPPEid %s", edgesPPEid)
217     edgesPFE = [ edid[0] for edid in edgesBordFFEid if edid[1] not in edgesPPEid] # on garde toutes les edges de bord non en contact avec le pipe
218     logging.debug("edgesPFE %s", edgesPFE)
219     edgesPeauFissureExterneC = geompy.MakeCompound(edgesPFE)
220   else:
221     faceFissureExterne = facesFissExt[0]
222     edgesPeauFissureExterneC = geompy.MakeCompound(edgesFissExtPeau)
223     edgesPipeFissureExterneC = geompy.MakeCompound(edgesFissExtPipe)
224   wirePipeFissureExterne = geompy.MakeWire(geompy.ExtractShapes(edgesPipeFissureExterneC, geompy.ShapeType["EDGE"], False))
225   geompy.addToStudy(faceFissureExterne, "faceFissureExterne")
226   geompy.addToStudyInFather(faceFissureExterne, edgesPeauFissureExterneC, "edgesPeauFissureExterne")
227   geompy.addToStudyInFather(faceFissureExterne, edgesPipeFissureExterneC, "edgesPipeFissureExterne")
228   
229   logging.debug("---------------------------- Preparation Maillage du Pipe --------------")
230   # -----------------------------------------------------------------------
231   # --- preparation maillage du pipe :
232   #     - détections des points a respecter : jonction des edges/faces constituant
233   #       la face de fissure externe au pipe
234   #     - points sur les edges de fond de fissure et edges pipe/face fissure,
235   #     - vecteurs tangents au fond de fissure (normal au disque maillé)
236
237   # --- option de maillage selon le rayon de courbure du fond de fissure 
238   lenEdgeFondExt = 0
239   for edff in edgesFondFiss:
240     lenEdgeFondExt += geompy.BasicProperties(edff)[0]
241   
242   disfond = []
243   for filling in facesDefaut:
244     disfond.append(geompy.MinDistance(centreFondFiss, filling))
245   disfond.sort()
246   rcourb = disfond[0]
247   nbSegQuart = 5 # on veut 5 segments min sur un quart de cercle
248   alpha = math.pi/(4*nbSegQuart)
249   deflexion = rcourb*(1.0 -math.cos(alpha))
250   lgmin = lenSegPipe*0.25
251   lgmax = lenSegPipe*1.5               
252   logging.debug("rcourb: %s, lenFond:%s, deflexion: %s, lgmin: %s, lgmax: %s", rcourb, lenEdgeFondExt, deflexion, lgmin, lgmax)  
253
254   meshFondExt = smesh.Mesh(wireFondFiss)
255   algo1d = meshFondExt.Segment()
256   hypo1d = algo1d.Adaptive(lgmin, lgmax, deflexion) # a ajuster selon la profondeur de la fissure
257   isDone = meshFondExt.Compute()
258   
259   ptGSdic = {} # dictionnaire [paramètre sur la courbe] --> point géométrique
260   allNodeIds = meshFondExt.GetNodesId()
261   for nodeId in allNodeIds:
262     xyz = meshFondExt.GetNodeXYZ(nodeId)
263     #logging.debug("nodeId %s, coords %s", nodeId, str(xyz))
264     pt = geompy.MakeVertex(xyz[0], xyz[1], xyz[2])
265     u, PointOnEdge, EdgeInWireIndex = geompy.MakeProjectionOnWire(pt, wireFondFiss) # u compris entre 0 et 1
266     edgeOrder = edgesIdByOrientation[EdgeInWireIndex]
267     ptGSdic[(edgeOrder, EdgeInWireIndex, u)] = pt
268     #logging.debug("nodeId %s, u %s", nodeId, str(u))
269   usort = sorted(ptGSdic)  
270   logging.debug("nombre de points obtenus par deflexion %s",len(usort))
271      
272   centres = []
273   origins = []
274   normals = []      
275   for edu in usort:
276     ied = edu[1]
277     u = edu[2]
278     vertcx = ptGSdic[edu]
279     norm = geompy.MakeTangentOnCurve(edgesFondFiss[ied], u)
280     plan = geompy.MakePlane(vertcx, norm, 3*rayonPipe)
281     part = geompy.MakePartition([plan], [wirePipeFiss], [], [], geompy.ShapeType["VERTEX"], 0, [], 0)
282     liste = geompy.ExtractShapes(part, geompy.ShapeType["VERTEX"], True)
283     if len(liste) == 5: # 4 coins du plan plus intersection recherchée
284       for point in liste:
285         if geompy.MinDistance(point, vertcx) < 1.1*rayonPipe: # les quatre coins sont plus loin
286           vertpx = point
287           break
288       centres.append(vertcx)
289       origins.append(vertpx)
290       normals.append(norm)
291 #      name = "vertcx%d"%i
292 #      geompy.addToStudyInFather(wireFondFiss, vertcx, name)
293 #      name = "vertpx%d"%i
294 #      geompy.addToStudyInFather(wireFondFiss, vertpx, name)
295 #      name = "plan%d"%i
296 #      geompy.addToStudyInFather(wireFondFiss, plan, name)
297
298   # --- maillage du pipe étendu, sans tenir compte de l'intersection avec la face de peau
299       
300   logging.debug("nbsegCercle %s", nbsegCercle)
301   
302   # -----------------------------------------------------------------------
303   # --- points géométriques
304   
305   gptsdisks = [] # vertices géométrie de tous les disques
306   raydisks = [[] for i in range(nbsegCercle)]
307   for i in range(len(centres)): # boucle sur les disques
308     gptdsk = [] # vertices géométrie d'un disque
309     vertcx = centres[i]
310     vertpx = origins[i]
311     normal = normals[i]
312     vec1 = geompy.MakeVector(vertcx, vertpx)
313     
314     points = [vertcx] # les points du rayon de référence
315     for j in range(nbsegRad):
316       pt = geompy.MakeTranslationVectorDistance(vertcx, vec1, (j+1)*float(rayonPipe)/nbsegRad)
317       points.append(pt)
318     gptdsk.append(points)
319     pt = geompy.MakeTranslationVectorDistance(vertcx, vec1, 1.5*rayonPipe)
320     rayon = geompy.MakeLineTwoPnt(vertcx, pt)
321     raydisks[0].append(rayon)
322     
323     for k in range(nbsegCercle-1):
324       angle = (k+1)*2*math.pi/nbsegCercle
325       pts = [vertcx] # les points d'un rayon obtenu par rotation
326       for j in range(nbsegRad):
327         pt = geompy.MakeRotation(points[j+1], normal, angle)
328         pts.append(pt)
329       gptdsk.append(pts)
330       ray = geompy.MakeRotation(rayon, normal, angle)
331       raydisks[k+1].append(ray)
332       
333     gptsdisks.append(gptdsk) 
334  
335   # -----------------------------------------------------------------------
336   # --- recherche des points en trop (externes au volume à remailler)
337   #     - on associe chaque extrémité du pipe à une face filling 
338   #     - on part des disques aux extrémités du pipe
339   #     - pour chaque disque, on prend les vertices de géométrie,
340   #       on marque leur position relative à la face.
341   #     - on s'arrete quand tous les noeuds sont dedans
342   
343   logging.debug("---------------------------- recherche des points du pipe a éliminer --------------")
344
345   pt0 = centres[0]
346   pt1 = centres[-1]
347   idFillingFromBout = [None, None]                 # contiendra l'index du filling pour les extrémités 0 et 1
348   for ifil in range(nbFacesFilling):
349     for ipt, pt in enumerate(ptEdgeFond[ifil]): # il y a un ou deux points débouchant sur cette face
350       if geompy.MinDistance(pt,pt0) < geompy.MinDistance(pt,pt1): # TODO: trouver plus fiable pour les cas tordus...
351         idFillingFromBout[0] = ifil
352       else: 
353         idFillingFromBout[1] = ifil
354   logging.debug("association bouts du pipe - faces de filling: %s", idFillingFromBout)
355   
356   facesPipePeau = []
357   edgeRadFacePipePeau = []
358   for ifil in range(nbFacesFilling):
359     facesPipePeau += fsPipePeau[ifil]
360     edgeRadFacePipePeau += edRadFPiPo[ifil]
361     
362   logging.debug("recherche des disques de noeuds complètement internes")
363   idisklim = [] # indices des premier et dernier disques internes
364   idiskout = [] # indices des premier et dernier disques externes
365   for bout in range(2):
366     if bout == 0:
367       idisk = -1
368       inc = 1
369       numout = -1
370     else:
371       idisk = len(gptsdisks)
372       inc = -1
373       numout = len(gptsdisks)
374     inside = False
375     outside = True
376     while not inside:
377       idisk = idisk + inc
378       logging.debug("examen disque %s", idisk)
379       gptdsk = gptsdisks[idisk]
380       inside = True
381       for k in range(nbsegCercle):
382         points = gptdsk[k]
383         for j, pt in enumerate(points):
384           side = whichSideVertex(facesDefaut[idFillingFromBout[bout]], pt)
385           if side < 0:
386             if outside: # premier point detecté dedans
387               outside = False
388               numout = idisk -inc # le disque précédent était dehors
389           else:
390             inside = False # ce point est dehors              
391         if not inside and not outside:
392           break
393     idisklim.append(idisk)  # premier et dernier disques internes
394     idiskout.append(numout) # premier et dernier disques externes
395     
396   # --- listes de nappes radiales en filling à chaque extrémité débouchante
397   facesDebouchantes = [False, False]
398   idFacesDebouchantes = [-1, -1] # contiendra les indices des faces disque débouchantes (facesPipePeau)
399   listNappes =[]
400   for i, idisk in enumerate(idisklim):
401     numout = idiskout[i]
402     logging.debug("extremité %s, indices disques interne %s, externe %s",i, idisk, numout)
403     nappes = []
404     if  (idisk != 0) and (idisk != len(gptsdisks)-1): # si extrémité débouchante
405       for k in range(nbsegCercle):
406         if i == 0:
407           iddeb = max(0, numout)
408           idfin = max(iddeb+3,idisk+1) # il faut 3 rayons pour faire un filling qui suive le fond de fissure
409           #logging.debug("extremité %s, indices retenus interne %s, externe %s",i, idfin, iddeb)
410           comp = geompy.MakeCompound(raydisks[k][iddeb:idfin])
411           name='compoundRay%d'%k
412           geompy.addToStudy(comp, name)
413         else:
414           idfin = min(len(gptsdisks), numout+1)
415           iddeb = min(idfin-3, idisk) # il faut 3 rayons pour faire un filling qui suive le fond de fissure
416           #logging.debug("extremité %s, indices retenus interne %s, externe %s",i, idfin, iddeb)
417           comp = geompy.MakeCompound(raydisks[k][iddeb:idfin])
418           name='compoundRay%d'%k
419           geompy.addToStudy(comp, name)
420         nappe = geompy.MakeFilling(comp, 2, 5, 0.0001, 0.0001, 0, GEOM.FOM_Default)
421         nappes.append(nappe)
422         name='nappe%d'%k
423         geompy.addToStudy(nappe, name)
424         facesDebouchantes[i] = True
425     listNappes.append(nappes)
426       
427   # --- mise en correspondance avec les indices des faces disque débouchantes (facesPipePeau)
428   for i, nappes in enumerate(listNappes):
429     if facesDebouchantes[i]:
430       for k, face in enumerate(facesPipePeau):
431         edge = geompy.MakeSection(face, nappes[0])
432         if geompy.NbShapes(edge, geompy.ShapeType["EDGE"]) > 0:
433           idFacesDebouchantes[i] = k
434           break
435   logging.debug("idFacesDebouchantes: %s", idFacesDebouchantes)
436
437   # --- construction des listes d'edges radiales sur chaque extrémité débouchante
438   listEdges = []
439   for i, nappes in enumerate(listNappes):
440     id = idFacesDebouchantes[i] # indice de face débouchante (facesPipePeau)
441     if id < 0:
442       listEdges.append([])
443     else:
444       face = facesPipePeau[id]
445       edges = [edgeRadFacePipePeau[id]]
446       for k, nappe in enumerate(nappes):
447         if k > 0:
448           obj = geompy.MakeSection(face, nappes[k]) # normalement une edge, parfois un compound d'edges dont un tout petit
449           edge = obj
450           vs = geompy.ExtractShapes(obj, geompy.ShapeType["VERTEX"], False)
451           if len(vs) > 2:
452             eds = geompy.ExtractShapes(obj, geompy.ShapeType["EDGE"], False)
453             [edsorted, minl,maxl] = sortEdges(eds)
454             edge = edsorted[-1]
455           else:
456             maxl = geompy.BasicProperties(edge)[0]
457           if maxl < 0.01: # problème MakeSection
458             logging.debug("problème MakeSection recherche edge radiale %s, longueur trop faible: %s, utilisation partition", k, maxl)
459             partNappeFace = geompy.MakePartition([face, nappes[k]], [] , [], [], geompy.ShapeType["FACE"], 0, [], 0)
460             edps= geompy.ExtractShapes(partNappeFace, geompy.ShapeType["EDGE"], False)
461             ednouv = []
462             for ii, ed in enumerate(edps):
463               vxs = geompy.ExtractShapes(ed, geompy.ShapeType["VERTEX"], False)
464               distx = [geompy.MinDistance(vx, face) for vx in vxs]
465               distx += [geompy.MinDistance(vx, nappes[k]) for vx in vxs]
466               dmax = max(distx)
467               logging.debug("  dmax %s",dmax)
468               if dmax < 0.01:
469                 ednouv.append(ed)
470             logging.debug("  edges issues de la partition: %s", ednouv)
471             for ii, ed in enumerate(ednouv):
472               geompy.addToStudy(ed, "ednouv%d"%ii)
473             [edsorted, minl,maxl] = sortEdges(ednouv)
474             logging.debug("  longueur edge trouvée: %s", maxl) 
475             edge = edsorted[-1]
476           edges.append(edge)
477           name = 'edgeEndPipe%d'%k
478           geompy.addToStudy(edge, name)
479       listEdges.append(edges)
480
481   # --- création des points du maillage du pipe sur la face de peau
482   for i, edges in enumerate(listEdges):
483     id = idFacesDebouchantes[i] # indice de face débouchante (facesPipePeau)
484     if id >= 0:
485       gptdsk = []
486       if id > 0: # id vaut 0 ou 1
487         id = -1  # si id vaut 1, on prend le dernier élément de la liste (1 ou 2 extrémités débouchent sur la face)
488       centre = ptEdgeFond[idFillingFromBout[i]][id]
489       name = "centre%d"%id
490       geompy.addToStudy(centre, name)
491       vertPipePeau = ptFisExtPi[idFillingFromBout[i]][id]
492       geompy.addToStudyInFather(centre, vertPipePeau, "vertPipePeau")
493       grpsEdgesCirc = edCircPeau[idFillingFromBout[i]] # liste de groupes
494       edgesCirc = []
495       for grpEdgesCirc in grpsEdgesCirc:
496         edgesCirc += geompy.ExtractShapes(grpEdgesCirc, geompy.ShapeType["EDGE"], False)
497       for k, edge in enumerate(edges):
498         extrems = geompy.ExtractShapes(edge, geompy.ShapeType["VERTEX"], True)
499         if geompy.MinDistance(centre, extrems[0]) < geompy.MinDistance(centre, extrems[1]):
500           bout = extrems[1]
501         else:
502           bout = extrems[0]
503         # ajustement du point extrémité (bout) sur l'edge circulaire en face de peau
504         logging.debug("edgesCirc: %s", edgesCirc)
505         distEdgeCirc = [(geompy.MinDistance(bout, edgeCirc), k2, edgeCirc) for k2, edgeCirc in enumerate(edgesCirc)]
506         distEdgeCirc.sort()
507         logging.debug("distEdgeCirc: %s", distEdgeCirc)
508         u = projettePointSurCourbe(bout, distEdgeCirc[0][2])
509         if (abs(u) < 0.02) or (abs(1-u) < 0.02): # les points très proches d'une extrémité doivent y être mis précisément.
510           extrCircs = geompy.ExtractShapes(distEdgeCirc[0][2], geompy.ShapeType["VERTEX"], True)
511           if geompy.MinDistance(bout, extrCircs[0]) < geompy.MinDistance(bout, extrCircs[1]):
512             bout = extrCircs[0]
513           else:
514             bout = extrCircs[1]
515           pass
516         else:
517           bout = geompy.MakeVertexOnCurve(distEdgeCirc[0][2], u)
518         name ="bout%d"%k
519         geompy.addToStudyInFather(centre, bout, name)
520         # enregistrement des points dans la structure
521         points = []
522         for j in range(nbsegRad +1):
523           u = j/float(nbsegRad)
524           points.append(geompy.MakeVertexOnCurve(edge, u))
525         if geompy.MinDistance(bout, points[0]) < geompy.MinDistance(centre, points[0]):
526           points.reverse()
527         points[0] = centre
528         points[-1] = bout
529         gptdsk.append(points)
530       if i == 0:
531         gptsdisks[idisklim[0] -1] = gptdsk
532         idisklim[0] = idisklim[0] -1
533       else:
534         gptsdisks[idisklim[1] +1] = gptdsk
535         idisklim[1] = idisklim[1] +1
536
537   # --- ajustement precis des points sur edgesPipeFissureExterneC
538   
539   edgesPFE = geompy.ExtractShapes(edgesPipeFissureExterneC, geompy.ShapeType["EDGE"], False)
540   verticesPFE = findWireIntermediateVertices(wirePipeFissureExterne)  # vertices intermédiaires (des points en trop dans ptsInWireFissExtPipe)
541   idiskmin = idisklim[0] + 1 # on ne prend pas le disque sur la peau, déjà ajusté
542   idiskmax = idisklim[1]     # on ne prend pas le disque sur la peau, déjà ajusté
543   idiskint = []
544   for vtx in verticesPFE:
545     distPtVt = []
546     for idisk in range(idiskmin, idiskmax):
547       gptdsk = gptsdisks[idisk]
548       pt = gptdsk[0][-1]       # le point sur l'edge de la fissure externe au pipe
549       distPtVt.append((geompy.MinDistance(pt, vtx), idisk))
550     distPtVt.sort()
551     idiskint.append(distPtVt[0][1])
552     gptsdisks[idiskint[-1]][0][-1] = vtx
553     logging.debug("ajustement point sur edgePipeFissureExterne, vertex: %s %s", idiskint[-1], distPtVt[0][0])
554   for idisk in range(idiskmin, idiskmax):
555     if idisk in idiskint:
556       break
557     logging.debug("ajustement point sur edgePipeFissureExterne: %s", idisk)
558     gptdsk = gptsdisks[idisk]
559     pt = gptdsk[0][-1]       # le point sur l'edge de la fissure externe au pipe
560     distPtEd = [(geompy.MinDistance(pt, edgePFE), k, edgePFE) for k, edgePFE in enumerate(edgesPFE)]
561     distPtEd.sort()
562     edgePFE = distPtEd[0][2]
563     u = projettePointSurCourbe(pt, edgePFE)
564     ptproj = geompy.MakeVertexOnCurve(edgePFE, u)
565     gptsdisks[idisk][0][-1] = ptproj
566   
567   # -----------------------------------------------------------------------
568   # --- maillage effectif du pipe
569
570   logging.debug("---------------------------- maillage effectif du pipe --------------")
571   meshPipe = smesh.Mesh(None, "meshPipe")
572   fondFissGroup = meshPipe.CreateEmptyGroup(SMESH.EDGE, "FONDFISS")
573   nodesFondFissGroup = meshPipe.CreateEmptyGroup(SMESH.NODE, "nfondfis")
574   faceFissGroup = meshPipe.CreateEmptyGroup(SMESH.FACE, "fisInPi")
575   edgeFaceFissGroup = meshPipe.CreateEmptyGroup(SMESH.EDGE, "edgeFaceFiss")
576   edgeCircPipe0Group = meshPipe.CreateEmptyGroup(SMESH.EDGE, "edgeCircPipe0")
577   edgeCircPipe1Group = meshPipe.CreateEmptyGroup(SMESH.EDGE, "edgeCircPipe1")
578   faceCircPipe0Group = meshPipe.CreateEmptyGroup(SMESH.FACE, "faceCircPipe0")
579   faceCircPipe1Group = meshPipe.CreateEmptyGroup(SMESH.FACE, "faceCircPipe1")
580   mptsdisks = []  # vertices maillage de tous les disques
581   mEdges = []     # identifiants edges maillage fond de fissure
582   mEdgeFaces = [] # identifiants edges maillage edge face de fissure externe
583   mFaces = []     # identifiants faces maillage fissure
584   mVols  = []     # identifiants volumes maillage pipe
585
586   mptdsk = None
587   for idisk in range(idisklim[0], idisklim[1]+1): # boucle sur les disques internes
588     
589     # -----------------------------------------------------------------------
590     # --- points
591     
592     gptdsk = gptsdisks[idisk]
593     if idisk > idisklim[0]:
594       oldmpts = mptdsk
595     mptdsk = [] # vertices maillage d'un disque
596     for k in range(nbsegCercle):
597       points = gptdsk[k]
598       mptids = []
599       for j, pt in enumerate(points):
600         if j == 0 and k > 0:
601           id = mptdsk[0][0]
602         else:
603           coords = geompy.PointCoordinates(pt)
604           id = meshPipe.AddNode(coords[0], coords[1], coords[2])
605         mptids.append(id)
606       mptdsk.append(mptids)
607     mptsdisks.append(mptdsk)
608     
609     # -----------------------------------------------------------------------
610     # --- groupes edges cercles debouchants
611     
612     if idisk == idisklim[0]:
613       pts = []
614       for k in range(nbsegCercle):
615         pts.append(mptdsk[k][-1])
616       edges = []
617       for k in range(len(pts)):
618         k1 = (k+1)%len(pts)
619         idEdge = meshPipe.AddEdge([pts[k], pts[k1]])
620         edges.append(idEdge)
621       edgeCircPipe0Group.Add(edges)
622        
623     if idisk == idisklim[1]:
624       pts = []
625       for k in range(nbsegCercle):
626         pts.append(mptdsk[k][-1])
627       edges = []
628       for k in range(len(pts)):
629         k1 = (k+1)%len(pts)
630         idEdge = meshPipe.AddEdge([pts[k], pts[k1]])
631         edges.append(idEdge)
632       edgeCircPipe1Group.Add(edges)
633     
634     # -----------------------------------------------------------------------
635     # --- groupes faces  debouchantes
636     
637     if idisk == idisklim[0]:
638       faces = []
639       for j in range(nbsegRad):
640         for k in range(nbsegCercle):
641           k1 = k+1
642           if k ==  nbsegCercle-1:
643             k1 = 0
644           if j == 0:
645             idf = meshPipe.AddFace([mptdsk[k][0], mptdsk[k][1], mptdsk[k1][1]]) # triangle
646           else:
647             idf = meshPipe.AddFace([mptdsk[k][j], mptdsk[k][j+1], mptdsk[k1][j+1], mptdsk[k1][j]]) # quadrangle
648           faces.append(idf)
649       faceCircPipe0Group.Add(faces)
650
651     if idisk == idisklim[1]:
652       faces = []
653       for j in range(nbsegRad):
654         for k in range(nbsegCercle):
655           k1 = k+1
656           if k ==  nbsegCercle-1:
657             k1 = 0
658           if j == 0:
659             idf = meshPipe.AddFace([mptdsk[k][0], mptdsk[k][1], mptdsk[k1][1]]) # triangle
660           else:
661             idf = meshPipe.AddFace([mptdsk[k][j], mptdsk[k][j+1], mptdsk[k1][j+1], mptdsk[k1][j]]) # quadrangle
662           faces.append(idf)
663       faceCircPipe1Group.Add(faces)
664           
665     # -----------------------------------------------------------------------
666     # --- mailles volumiques, groupes noeuds et edges de fond de fissure, groupe de face de fissure
667     
668     if idisk == idisklim[0]:
669       mEdges.append(0)
670       mEdgeFaces.append(0)
671       mFaces.append([0])
672       mVols.append([[0]])
673       nodesFondFissGroup.Add([mptdsk[0][0]])
674     else:
675       ide = meshPipe.AddEdge([oldmpts[0][0], mptdsk[0][0]])
676       mEdges.append(ide)
677       fondFissGroup.Add([ide])
678       nodesFondFissGroup.Add([mptdsk[0][0]])
679       ide2 = meshPipe.AddEdge([oldmpts[0][-1], mptdsk[0][-1]])
680       mEdgeFaces.append(ide2)
681       edgeFaceFissGroup.Add([ide2])
682       idFaces = []
683       idVols = []
684       
685       for j in range(nbsegRad):
686         idf = meshPipe.AddFace([oldmpts[0][j], mptdsk[0][j], mptdsk[0][j+1], oldmpts[0][j+1]])
687         faceFissGroup.Add([idf])
688         idFaces.append(idf)
689         
690         idVolCercle = []
691         for k in range(nbsegCercle):
692           k1 = k+1
693           if k ==  nbsegCercle-1:
694             k1 = 0
695           if j == 0:
696             idv = meshPipe.AddVolume([mptdsk[k][j], mptdsk[k][j+1], mptdsk[k1][j+1],
697                                       oldmpts[k][j], oldmpts[k][j+1], oldmpts[k1][j+1]])
698           else:
699             idv = meshPipe.AddVolume([mptdsk[k][j], mptdsk[k][j+1], mptdsk[k1][j+1], mptdsk[k1][j],
700                                       oldmpts[k][j], oldmpts[k][j+1], oldmpts[k1][j+1], oldmpts[k1][j]])
701           idVolCercle.append(idv)
702         idVols.append(idVolCercle)  
703         
704       mFaces.append(idFaces)
705       mVols.append(idVols)
706
707   pipeFissGroup = meshPipe.CreateEmptyGroup( SMESH.VOLUME, 'PIPEFISS' )
708   nbAdd = pipeFissGroup.AddFrom( meshPipe.GetMesh() )
709
710   nb, new_mesh, new_group = meshPipe.MakeBoundaryElements(SMESH.BND_2DFROM3D, "pipeBoundaries")
711   edgesCircPipeGroup = [edgeCircPipe0Group, edgeCircPipe1Group]
712
713   # --- fin du maillage du pipe
714   # -----------------------------------------------------------------------
715   # --- edges de bord, faces défaut à respecter
716
717   aFilterManager = smesh.CreateFilterManager()
718   nbAdded, internalBoundary, _NoneGroup = internalBoundary.MakeBoundaryElements( SMESH.BND_1DFROM2D, '', '', 0, [  ])
719   criteres = []
720   unCritere = smesh.GetCriterion(SMESH.EDGE,SMESH.FT_FreeBorders,SMESH.FT_Undefined,0)
721   criteres.append(unCritere)
722   filtre = smesh.GetFilterFromCriteria(criteres)
723   bordsLibres = internalBoundary.MakeGroupByFilter( 'bords', filtre )
724   smesh.SetName(bordsLibres, 'bordsLibres')
725
726   # --- pour aider l'algo hexa-tetra à ne pas mettre de pyramides à l'exterieur des volumes repliés sur eux-mêmes
727   #     on désigne les faces de peau en quadrangles par le groupe "skinFaces"
728
729   skinFaces = internalBoundary.CreateEmptyGroup( SMESH.FACE, 'skinFaces' )
730   nbAdd = skinFaces.AddFrom( internalBoundary.GetMesh() )
731
732   # --- maillage des éventuelles arêtes vives entre faces reconstruites
733   
734   if len(aretesVivesCoupees) > 0:
735     aretesVivesC = geompy.MakeCompound(aretesVivesCoupees)
736     meshAretesVives = smesh.Mesh(aretesVivesC)
737     algo1d = meshAretesVives.Segment()
738     hypo1d = algo1d.LocalLength(dmoyen,[],1e-07)
739     putName(algo1d.GetSubMesh(), "aretesVives")
740     putName(algo1d, "algo1d_aretesVives")
741     putName(hypo1d, "hypo1d_aretesVives")
742     isDone = meshAretesVives.Compute()
743     logging.info("aretesVives fini")
744     grpAretesVives = meshAretesVives.CreateEmptyGroup( SMESH.EDGE, 'grpAretesVives' )
745     nbAdd = grpAretesVives.AddFrom( meshAretesVives.GetMesh() )
746
747   # -----------------------------------------------------------------------
748   # --- maillage faces de fissure
749   
750   logging.debug("---------------------------- maillage faces de fissure externes au pipe :%s --------------", len(facesFissExt))
751
752   meshFaceFiss = smesh.Mesh(faceFissureExterne)
753   algo2d = meshFaceFiss.Triangle(algo=smeshBuilder.NETGEN_1D2D)
754   hypo2d = algo2d.Parameters()
755   hypo2d.SetMaxSize( areteFaceFissure )
756   hypo2d.SetSecondOrder( 0 )
757   hypo2d.SetOptimize( 1 )
758   hypo2d.SetFineness( 2 )
759   hypo2d.SetMinSize( rayonPipe/float(nbsegRad) )
760   hypo2d.SetQuadAllowed( 0 )
761   putName(algo2d.GetSubMesh(), "faceFiss")
762   putName(algo2d, "algo2d_faceFiss")
763   putName(hypo2d, "hypo2d_faceFiss")
764   
765   algo1d = meshFaceFiss.UseExisting1DElements(geom=edgesPipeFissureExterneC)
766   hypo1d = algo1d.SourceEdges([ edgeFaceFissGroup ],0,0)
767   putName(algo1d.GetSubMesh(), "edgeFissPeau")
768   putName(algo1d, "algo1d_edgeFissPeau")
769   putName(hypo1d, "hypo1d_edgeFissPeau")
770   
771   isDone = meshFaceFiss.Compute()
772   logging.info("meshFaceFiss fini")
773
774   grpFaceFissureExterne = meshFaceFiss.GroupOnGeom(faceFissureExterne, "fisOutPi", SMESH.FACE)
775   grpEdgesPeauFissureExterne = meshFaceFiss.GroupOnGeom(edgesPeauFissureExterneC,'edgesPeauFissureExterne',SMESH.EDGE)
776   grpEdgesPipeFissureExterne = meshFaceFiss.GroupOnGeom(edgesPipeFissureExterneC,'edgesPipeFissureExterne',SMESH.EDGE)
777
778   # --- maillage faces de peau
779     
780   boutFromIfil = [None for i in range(nbFacesFilling)]
781   if idFillingFromBout[0] != idFillingFromBout[1]: # repérage des extremites du pipe quand elles débouchent sur des faces différentes
782     boutFromIfil[idFillingFromBout[0]] = 0
783     boutFromIfil[idFillingFromBout[1]] = 1
784   
785   logging.debug("---------------------------- maillage faces de peau --------------")
786   meshesFacesPeau = []
787   for ifil in range(nbFacesFilling):
788     meshFacePeau = None
789     if partitionsPeauFissFond[ifil] is None: # face de peau maillage sain intacte
790       
791       # --- edges de bord de la face de filling
792       filling = facesDefaut[ifil]
793       edgesFilling = geompy.ExtractShapes(filling, geompy.ShapeType["EDGE"], False)
794       groupEdgesBordPeau = geompy.CreateGroup(filling, geompy.ShapeType["EDGE"])
795       geompy.UnionList(groupEdgesBordPeau, edgesFilling)
796       geompy.addToStudyInFather(filling, groupEdgesBordPeau , "EdgesBords")
797       
798       meshFacePeau = smesh.Mesh(facesDefaut[ifil])
799       
800       algo1d = meshFacePeau.UseExisting1DElements(geom=groupEdgesBordPeau)
801       hypo1d = algo1d.SourceEdges([ bordsLibres ],0,0)
802       putName(algo1d.GetSubMesh(), "bordsLibres", ifil)
803       putName(algo1d, "algo1d_bordsLibres", ifil)
804       putName(hypo1d, "hypo1d_bordsLibres", ifil)
805       
806     else:
807       
808       facePeau           = facesPeaux[ifil] # pour chaque face : la face de peau finale a mailler (percée des faces débouchantes)
809       edgesCircPeau      = edCircPeau[ifil] # pour chaque face de peau : [subshape edge circulaire aux débouchés du pipe]
810       verticesCircPeau   = ptCircPeau[ifil] # pour chaque face de peau : [subshape point sur edge circulaire aux débouchés du pipe]
811       groupEdgesBordPeau = gpedgeBord[ifil] # pour chaque face de peau : groupe subshape des edges aux bords liés à la partie saine
812       bordsVifs          = gpedgeVifs[ifil] # pour chaque face de peau : groupe subshape des edges aux bords correspondant à des arêtes vives
813       edgesFissurePeau   = edFissPeau[ifil] # pour chaque face de peau : [subshape edge en peau des faces de fissure externes]
814
815       meshFacePeau = smesh.Mesh(facePeau)
816       
817       algo1d = meshFacePeau.UseExisting1DElements(geom=groupEdgesBordPeau)
818       hypo1d = algo1d.SourceEdges([ bordsLibres ],0,0)
819       putName(algo1d.GetSubMesh(), "bordsLibres", ifil)
820       putName(algo1d, "algo1d_bordsLibres", ifil)
821       putName(hypo1d, "hypo1d_bordsLibres", ifil)
822       
823       algo1d = meshFacePeau.UseExisting1DElements(geom=geompy.MakeCompound(edgesFissurePeau))
824       hypo1d = algo1d.SourceEdges([ grpEdgesPeauFissureExterne ],0,0)
825       putName(algo1d.GetSubMesh(), "edgePeauFiss", ifil)
826       putName(algo1d, "algo1d_edgePeauFiss", ifil)
827       putName(hypo1d, "hypo1d_edgePeauFiss", ifil)
828       
829       if bordsVifs is not None:
830         algo1d = meshFacePeau.UseExisting1DElements(geom=bordsVifs)
831         hypo1d = algo1d.SourceEdges([ grpAretesVives ],0,0)
832         putName(algo1d.GetSubMesh(), "bordsVifs", ifil)
833         putName(algo1d, "algo1d_bordsVifs", ifil)
834         putName(hypo1d, "hypo1d_bordsVifs", ifil)
835         
836       for i, edgeCirc in enumerate(edgesCircPeau):
837         if edgeCirc is not None:
838           algo1d = meshFacePeau.UseExisting1DElements(geom=edgeCirc)
839           if boutFromIfil[ifil] is None:
840             hypo1d = algo1d.SourceEdges([ edgesCircPipeGroup[i] ],0,0)
841           else:
842             hypo1d = algo1d.SourceEdges([ edgesCircPipeGroup[boutFromIfil[ifil]] ],0,0)
843           name = "cercle%d"%i
844           putName(algo1d.GetSubMesh(), name, ifil)
845           putName(algo1d, "algo1d_" + name, ifil)
846           putName(hypo1d, "hypo1d_" + name, ifil)
847    
848     algo2d = meshFacePeau.Triangle(algo=smeshBuilder.NETGEN_1D2D)
849     hypo2d = algo2d.Parameters()
850     hypo2d.SetMaxSize( dmoyen )
851     hypo2d.SetOptimize( 1 )
852     hypo2d.SetFineness( 2 )
853     hypo2d.SetMinSize( rayonPipe/float(nbsegRad) )
854     hypo2d.SetQuadAllowed( 0 )
855     putName(algo2d.GetSubMesh(), "facePeau", ifil)
856     putName(algo2d, "algo2d_facePeau", ifil)
857     putName(hypo2d, "hypo2d_facePeau", ifil)
858       
859     isDone = meshFacePeau.Compute()
860     logging.info("meshFacePeau %d fini", ifil)
861     GroupFaces = meshFacePeau.CreateEmptyGroup( SMESH.FACE, "facePeau%d"%ifil )
862     nbAdd = GroupFaces.AddFrom( meshFacePeau.GetMesh() )
863     meshesFacesPeau.append(meshFacePeau)
864
865   # --- regroupement des maillages du défaut
866
867   listMeshes = [internalBoundary.GetMesh(),
868                 meshPipe.GetMesh(),
869                 meshFaceFiss.GetMesh()]
870   for mp in meshesFacesPeau:
871     listMeshes.append(mp.GetMesh())
872
873   meshBoiteDefaut = smesh.Concatenate(listMeshes, 1, 1, 1e-05,False)
874   # pour aider l'algo hexa-tetra à ne pas mettre de pyramides à l'exterieur des volumes repliés sur eux-mêmes
875   # on désigne les faces de peau en quadrangles par le groupe "skinFaces"
876   group_faceFissOutPipe = None
877   group_faceFissInPipe = None
878   groups = meshBoiteDefaut.GetGroups()
879   for grp in groups:
880     if grp.GetType() == SMESH.FACE:
881       #if "internalBoundary" in grp.GetName():
882       #  grp.SetName("skinFaces")
883       if grp.GetName() == "fisOutPi":
884         group_faceFissOutPipe = grp
885       elif grp.GetName() == "fisInPi":
886         group_faceFissInPipe = grp
887
888   # le maillage NETGEN ne passe pas toujours ==> utiliser GHS3D
889   distene=True
890   if distene:
891     algo3d = meshBoiteDefaut.Tetrahedron(algo=smeshBuilder.GHS3D)
892   else:
893     algo3d = meshBoiteDefaut.Tetrahedron(algo=smeshBuilder.NETGEN)
894     hypo3d = algo3d.MaxElementVolume(1000.0)
895   putName(algo3d.GetSubMesh(), "boiteDefaut")
896   putName(algo3d, "algo3d_boiteDefaut")
897   isDone = meshBoiteDefaut.Compute()
898   putName(meshBoiteDefaut, "boiteDefaut")
899   logging.info("meshBoiteDefaut fini")
900   
901   faceFissure = meshBoiteDefaut.GetMesh().UnionListOfGroups( [ group_faceFissOutPipe, group_faceFissInPipe ], 'FACE1' )
902   maillageSain = enleveDefaut(maillageSain, zoneDefaut, zoneDefaut_skin,
903                               zoneDefaut_internalFaces, zoneDefaut_internalEdges)
904   putName(maillageSain, nomFicSain+"_coupe")
905   extrusionFaceFissure, normfiss = shapeSurFissure(facesPortFissure)
906   maillageComplet = RegroupeSainEtDefaut(maillageSain, meshBoiteDefaut,
907                                          None, None, 'COMPLET', normfiss)
908
909   logging.info("conversion quadratique")
910   maillageComplet.ConvertToQuadratic( 1 )
911   logging.info("groupes")
912   groups = maillageComplet.GetGroups()
913   grps = [ grp for grp in groups if grp.GetName() == 'FONDFISS']
914   fond = maillageComplet.GetMesh().CreateDimGroup( grps, SMESH.NODE, 'FONDFISS' )
915
916   logging.info("réorientation face de fissure FACE1")
917   grps = [ grp for grp in groups if grp.GetName() == 'FACE1']
918   nb = maillageComplet.Reorient2D( grps[0], normfiss, grps[0].GetID(1))
919
920   logging.info("réorientation face de fissure FACE2")
921   plansim = geompy.MakePlane(O, normfiss, 10000)
922   fissnorm = geompy.MakeMirrorByPlane(normfiss, plansim)
923   grps = [ grp for grp in groups if grp.GetName() == 'FACE2']
924   nb = maillageComplet.Reorient2D( grps[0], fissnorm, grps[0].GetID(1))
925   fond = maillageComplet.GetMesh().CreateDimGroup( grps, SMESH.NODE, 'FACE2' )
926
927   logging.info("export maillage fini")
928   maillageComplet.ExportMED( fichierMaillageFissure, 0, SMESH.MED_V2_2, 1 )
929   putName(maillageComplet, nomFicFissure)
930   logging.info("fichier maillage fissure %s", fichierMaillageFissure)
931
932   if salome.sg.hasDesktop():
933     salome.sg.updateObjBrowser(1)
934
935   logging.info("maillage fissure fini")
936   
937   return maillageComplet