Salome HOME
merge manuel developpements Olivier Hoareau
[modules/smesh.git] / src / Tools / blocFissure / gmu / insereFissureGenerale.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 getCentreFondFiss import getCentreFondFiss
37
38 # -----------------------------------------------------------------------------
39 # --- procédure complète fissure générale
40
41 def insereFissureGenerale(maillagesSains,
42                           shapesFissure, shapeFissureParams,
43                           maillageFissureParams, elementsDefaut, step=-1):
44   """
45   TODO: a completer
46   """
47   logging.info('start')
48   
49   shapeDefaut       = shapesFissure[0] # faces de fissure, débordant
50   fondFiss          = shapesFissure[4] # groupe d'edges de fond de fissure
51
52   rayonPipe = shapeFissureParams['rayonPipe']
53   if shapeFissureParams.has_key('lenSegPipe'):
54     lenSegPipe = shapeFissureParams['lenSegPipe']
55   else:
56     lenSegPipe = rayonPipe
57
58   nomRep            = maillageFissureParams['nomRep']
59   nomFicSain        = maillageFissureParams['nomFicSain']
60   nomFicFissure     = maillageFissureParams['nomFicFissure']
61
62   nbsegRad          = maillageFissureParams['nbsegRad']      # nombre de couches selon un rayon du pipe
63   nbsegCercle       = maillageFissureParams['nbsegCercle']   # nombre de secteur dans un cercle du pipe
64   areteFaceFissure  = maillageFissureParams['areteFaceFissure']
65
66   pointIn_x = 0.0
67   pointIn_y = 0.0
68   pointIn_z = 0.0
69   isPointInterne = False
70   if shapeFissureParams.has_key('pointIn_x'):
71     pointIn_x = shapeFissureParams['pointIn_x']
72     isPointInterne = True
73   if shapeFissureParams.has_key('pointIn_y'):
74     pointIn_y = shapeFissureParams['pointIn_y']
75     isPointInterne = True
76   if shapeFissureParams.has_key('pointIn_z'):
77     pointIn_z = shapeFissureParams['pointIn_z']
78     isPointInterne = True
79   if isPointInterne:
80     pointInterne = geompy.MakeVertex(pointIn_x, pointIn_y, pointIn_z)
81
82   #fichierMaillageSain = nomRep + '/' + nomFicSain + '.med'
83   fichierMaillageFissure = nomRep + '/' + nomFicFissure + '.med'
84
85   # fillings des faces en peau
86   facesDefaut = elementsDefaut[0]
87   #centresDefaut            = elementsDefaut[1]
88   #normalsDefaut            = elementsDefaut[2]
89   #extrusionsDefaut         = elementsDefaut[3]
90   dmoyen                   = elementsDefaut[4]
91   bordsPartages = elementsDefaut[5]
92   fillconts                = elementsDefaut[6]
93   idFilToCont              = elementsDefaut[7]
94   maillageSain             = elementsDefaut[8]
95   internalBoundary         = elementsDefaut[9]
96   zoneDefaut               = elementsDefaut[10]
97   zoneDefaut_skin          = elementsDefaut[11]
98   zoneDefaut_internalFaces = elementsDefaut[12]
99   zoneDefaut_internalEdges = elementsDefaut[13]
100   edgeFondExt              = elementsDefaut[14]
101   centreFondFiss           = elementsDefaut[15]
102   tgtCentre                = elementsDefaut[16]
103
104   # --- restriction de la face de fissure au domaine solide :
105   #     partition face fissure étendue par fillings, on garde la plus grande face
106
107   partShapeDefaut = geompy.MakePartition([shapeDefaut], facesDefaut, [], [], geompy.ShapeType["FACE"], 0, [], 0)
108   geompy.addToStudy(partShapeDefaut, 'partShapeDefaut')
109   facesPartShapeDefaut = geompy.ExtractShapes(partShapeDefaut, geompy.ShapeType["FACE"], False)
110   if isPointInterne:
111     distfaces = [(geompy.MinDistance(face,pointInterne), i, face) for i, face in enumerate(facesPartShapeDefaut)]
112     distfaces.sort()
113     logging.debug("selection de la face la plus proche du point interne, distance=%s",distfaces[0][0])
114     facesPortFissure = distfaces[0][2]
115   else:
116     facesPartShapeDefautSorted, minSurf, maxSurf = sortFaces(facesPartShapeDefaut) # la face de fissure dans le volume doit être la plus grande
117     logging.debug("surfaces faces fissure étendue, min %s, max %s", minSurf, maxSurf)
118     facesPortFissure = facesPartShapeDefautSorted[-1]
119   
120   geompy.addToStudy(facesPortFissure, "facesPortFissure")
121
122   O, OX, OY, OZ = triedreBase()
123   
124   # -----------------------------------------------------------------------------
125   # --- pipe de fond de fissure, prolongé, partition face fissure par pipe
126   #     identification des edges communes pipe et face fissure
127   
128   if geompy.NumberOfFaces(shapeDefaut) == 1:
129     plan = geompy.MakePlane(centreFondFiss, tgtCentre, 10000)
130     shapeDefaut = geompy.MakePartition([shapeDefaut], [plan], [], [], geompy.ShapeType["FACE"], 0, [], 0)
131     fondFissCoupe = geompy.GetInPlaceByHistory(shapeDefaut, fondFiss)
132     geompy.addToStudy(shapeDefaut, 'shapeDefaut_coupe')
133     geompy.addToStudyInFather(shapeDefaut, fondFissCoupe, 'fondFiss_coupe')
134   
135   extrem, norms = findWireEndVertices(fondFiss, True)
136   logging.debug("extrem: %s, norm: %s",extrem, norms)
137   cercle = geompy.MakeCircle(extrem[0], norms[0], rayonPipe)
138   cercle = geompy.MakeRotation(cercle, norms[0], math.pi/3.0 ) # éviter d'avoir l'arête de couture du pipe presque confondue avec la face fissure
139   geompy.addToStudy(cercle, 'cercle')
140   fondFissProlonge = prolongeWire(fondFiss, extrem, norms, 2*rayonPipe)
141   pipeFiss = geompy.MakePipe(cercle, fondFissProlonge)
142   geompy.addToStudy(pipeFiss, 'pipeFiss')
143   partFissPipe = geompy.MakePartition([shapeDefaut, pipeFiss], [], [], [], geompy.ShapeType["FACE"], 0, [], 1)
144   geompy.addToStudy(partFissPipe, 'partFissPipe')
145   fissPipe = geompy.GetInPlaceByHistory(partFissPipe, shapeDefaut)
146   geompy.addToStudy(fissPipe, 'fissPipe')
147   partPipe = geompy.GetInPlaceByHistory(partFissPipe, pipeFiss)
148   geompy.addToStudy(partPipe, 'partPipe')
149   
150   edgesPipeFiss = geompy.GetSharedShapesMulti([fissPipe, partPipe], geompy.ShapeType["EDGE"])
151   for i, edge in enumerate(edgesPipeFiss):
152     name = "edgePipe%d"%i
153     geompy.addToStudyInFather(fissPipe, edge, name)
154   try:
155     wirePipeFiss = geompy.MakeWire(edgesPipeFiss)
156   except:
157     wirePipeFiss = geompy.MakeCompound(edgesPipeFiss)
158     logging.debug("wirePipeFiss construit sous forme de compound")
159   geompy.addToStudy(wirePipeFiss, "wirePipeFiss")
160   
161   wireFondFiss = geompy.GetInPlace(partFissPipe,fondFiss)
162   edgesFondFiss = geompy.GetSharedShapesMulti([fissPipe, wireFondFiss], geompy.ShapeType["EDGE"])
163   for i, edge in enumerate(edgesFondFiss):
164     name = "edgeFondFiss%d"%i
165     geompy.addToStudyInFather(fissPipe, edge, name)
166   wireFondFiss = geompy.MakeWire(edgesFondFiss)
167   geompy.addToStudy(wireFondFiss,"wireFondFiss")  
168
169   # -----------------------------------------------------------------------------
170   # --- peau et face de fissure
171   #
172   # --- partition peau défaut - face de fissure prolongée - wire de fond de fissure prolongée
173   #     il peut y avoir plusieurs faces externes, dont certaines sont découpées par la fissure
174   #     liste de faces externes : facesDefaut
175   #     liste de partitions face externe - fissure : partitionPeauFissFond (None quand pas d'intersection)
176
177   partitionsPeauFissFond = []
178   ipart = 0
179   for filling in facesDefaut: 
180     part = geompy.MakePartition([fissPipe, filling], [], [], [], geompy.ShapeType["FACE"], 0, [], 0)
181     isPart = checkDecoupePartition([fissPipe, filling], part)
182     if isPart: # on recrée la partition avec toutes les faces filling en outil pour avoir une face de fissure correcte
183       otherFD = [fd for fd in facesDefaut if fd != filling]
184       if len(otherFD) > 0:
185         fissPipePart = geompy.MakePartition([fissPipe], otherFD, [], [], geompy.ShapeType["FACE"], 0, [], 0)
186       else:
187         fissPipePart = fissPipe
188       part = geompy.MakePartition([fissPipePart, filling], [], [], [], geompy.ShapeType["FACE"], 0, [], 0)
189       partitionsPeauFissFond.append(part)
190       geompy.addToStudy( part, 'partitionPeauFissFond%d'%ipart )
191     else:
192       partitionsPeauFissFond.append(None)
193     ipart = ipart +1
194  
195   
196   # --- arêtes vives détectées (dans quadranglesToShapeNoCorner
197   #                             et quadranglesToShapeWithCorner)
198   
199   aretesVives = []
200   aretesVivesCoupees = []
201   ia = 0
202   for a in bordsPartages:
203     if not isinstance(a, list):
204         aretesVives.append(a)
205         name = "areteVive%d"%ia
206         geompy.addToStudy(a, name)
207         ia += 1
208     else:
209         if a[0] is not None:
210             aretesVives.append(a[0])
211             name = "areteVive%d"%ia
212             geompy.addToStudy(a[0], name)
213             ia += 1
214
215   aretesVivesC = None
216   if len(aretesVives) > 0:
217     aretesVivesC =geompy.MakeCompound(aretesVives)
218     
219   # -------------------------------------------------------
220   # --- inventaire des faces de peau coupées par la fissure
221   #     pour chaque face de peau : 0, 1 ou 2 faces débouchante du fond de fissure
222   #                                0, 1 ou plus edges de la face de fissure externe au pipe
223   
224   nbFacesFilling = len(partitionsPeauFissFond)
225   ptEdgeFond = [ []  for i in range(nbFacesFilling)] # pour chaque face [points edge fond de fissure aux débouchés du pipe]
226   fsPipePeau = [ []  for i in range(nbFacesFilling)] # pour chaque face [faces du pipe débouchantes]
227   edRadFPiPo = [ []  for i in range(nbFacesFilling)] # pour chaque face [edge radiale des faces du pipe débouchantes ]
228   fsFissuExt = [ []  for i in range(nbFacesFilling)] # pour chaque face [faces de fissure externes au pipe]
229   edFisExtPe = [ []  for i in range(nbFacesFilling)] # pour chaque face [edge en peau des faces de fissure externes (pas subshape facePeau)]
230   edFisExtPi = [ []  for i in range(nbFacesFilling)] # pour chaque face [edge commun au pipe des faces de fissure externes]
231   facesPeaux = [None for i in range(nbFacesFilling)] # pour chaque face : la face de peau finale a mailler (percée des faces débouchantes)
232   edCircPeau = [ []  for i in range(nbFacesFilling)] # pour chaque face de peau : [subshape edge circulaire aux débouchés du pipe]
233   ptCircPeau = [ []  for i in range(nbFacesFilling)] # pour chaque face de peau : [subshape point sur edge circulaire aux débouchés du pipe]
234   gpedgeBord = [None for i in range(nbFacesFilling)] # pour chaque face de peau : groupe subshape des edges aux bords liés à la partie saine
235   gpedgeVifs = [None for i in range(nbFacesFilling)] # pour chaque face de peau : groupes subshape des edges aux arêtes vives entre fillings
236   edFissPeau = [ []  for i in range(nbFacesFilling)] # pour chaque face de peau : [subshape edge en peau des faces de fissure externes]
237   ptFisExtPi = [ []  for i in range(nbFacesFilling)] # pour chaque face de peau : [point commun edFissPeau edCircPeau]
238   
239   for ifil, partitionPeauFissFond in enumerate(partitionsPeauFissFond):
240     fillingFaceExterne = facesDefaut[ifil]
241     #fillingSansDecoupe = fillconts[idFilToCont[ifil]]
242     if partitionPeauFissFond is not None:
243       logging.debug("traitement partitionPeauFissFond %s", ifil)
244       # -----------------------------------------------------------------------
245       # --- identification edges fond de fissure, edges pipe sur la face de fissure,
246       #     edges prolongées
247       
248       edgesPipeC = geompy.GetInPlace(partitionPeauFissFond, geompy.MakeCompound(edgesPipeFiss))
249       geompy.addToStudyInFather(partitionPeauFissFond, edgesPipeC, "edgesPipeFiss")
250       edgesFondC = geompy.GetInPlace(partitionPeauFissFond, geompy.MakeCompound(edgesFondFiss))
251       geompy.addToStudyInFather(partitionPeauFissFond, edgesFondC, "edgesFondFiss")
252       
253       if aretesVivesC is None:
254         [edgesInside, edgesOutside, edgesOnside] = extractionOrientee(fillingFaceExterne, partitionPeauFissFond, centreFondFiss, "EDGE", 1.e-3)
255         [facesInside, facesOutside, facesOnside] = extractionOrientee(fillingFaceExterne, partitionPeauFissFond, centreFondFiss, "FACE", 1.e-3)
256       else:
257         [edgesInside, edgesOutside, edgesOnside] = extractionOrienteeMulti(facesDefaut, ifil, partitionPeauFissFond, centreFondFiss, "EDGE", 1.e-3)
258         [facesInside, facesOutside, facesOnside] = extractionOrienteeMulti(facesDefaut, ifil, partitionPeauFissFond, centreFondFiss, "FACE", 1.e-3)
259         
260       edgesPipeIn = geompy.GetSharedShapesMulti([edgesPipeC, geompy.MakeCompound(edgesInside)], geompy.ShapeType["EDGE"])
261       verticesPipePeau = []
262
263       for i, edge in enumerate(edgesPipeIn):
264         try:
265           vertices = geompy.GetSharedShapesMulti([edge, geompy.MakeCompound(facesOnside)], geompy.ShapeType["VERTEX"])
266           verticesPipePeau.append(vertices[0])
267           name = "edgePipeIn%d"%i
268           geompy.addToStudyInFather(partitionPeauFissFond, edge, name)
269           name = "verticePipePeau%d"%i
270           geompy.addToStudyInFather(partitionPeauFissFond, vertices[0], name)
271           logging.debug("edgePipeIn%s coupe les faces OnSide", i)
272         except:
273           logging.debug("edgePipeIn%s ne coupe pas les faces OnSide", i)
274       edgesFondOut = []
275       edgesFondIn =[]
276       if len(verticesPipePeau) > 0: # au moins une extrémité du pipe sur cette face de peau  
277         tmp = geompy.GetSharedShapesMulti([edgesFondC, geompy.MakeCompound(edgesOutside)], geompy.ShapeType["EDGE"])
278         edgesFondOut = [ ed for ed in tmp if geompy.MinDistance(ed, geompy.MakeCompound(facesOnside)) < 1.e-3]
279         tmp = geompy.GetSharedShapesMulti([edgesFondC, geompy.MakeCompound(edgesInside)], geompy.ShapeType["EDGE"])
280         edgesFondIn = [ ed for ed in tmp if geompy.MinDistance(ed, geompy.MakeCompound(facesOnside)) < 1.e-3]
281       verticesEdgesFondIn = [] # les points du fond de fissure au débouché du pipe sur la peau (indice de edgesFondIn)
282       pipexts = []             # les segments de pipe associés au points de fond de fissure débouchants (même indice)
283       cercles = []             # les cercles de generation des pipes débouchant (même indice)
284       facesFissExt = []        # les faces de la fissure externe associés au points de fond de fissure débouchants (même indice)
285       edgesFissExtPeau = []    # edges des faces de fissure externe sur la peau (même indice)
286       edgesFissExtPipe = []    # edges des faces de fissure externe sur le pipe (même indice)
287       #logging.debug("edgesFondIn %s", edgesFondIn)
288
289       edgesFondFiss, edgesIdByOrientation = orderEdgesFromWire(wireFondFiss)
290       for i,edge in enumerate(edgesFondFiss):
291         geompy.addToStudyInFather(wireFondFiss, edge, "edgeFondFiss%d"%i)
292
293       for iedf, edge in enumerate(edgesFondIn):
294         name = "edgeFondIn%d"%iedf
295         geompy.addToStudyInFather(partitionPeauFissFond, edge, name)
296         dist = [ geompy.MinDistance(pt, edge) for pt in verticesPipePeau]
297         ptPeau = verticesPipePeau[dist.index(min(dist))] # le point de verticesPipePeau a distance minimale de l'edge
298         [u, PointOnEdge, EdgeInWireIndex]  = geompy.MakeProjectionOnWire(ptPeau, wireFondFiss)
299         logging.debug("u:%s, EdgeInWireIndex: %s, len(edgesFondFiss): %s", u, EdgeInWireIndex, len(edgesFondFiss))
300         localEdgeInFondFiss = edgesFondFiss[EdgeInWireIndex]
301         centre = PointOnEdge
302         centre2 = geompy.MakeVertexOnCurve(localEdgeInFondFiss, u)
303         geompy.addToStudyInFather(partitionPeauFissFond, centre2, "centre2_%d"%iedf)
304         verticesEdgesFondIn.append(centre)
305         name = "verticeEdgesFondIn%d"%iedf
306         geompy.addToStudyInFather(partitionPeauFissFond, centre, name)
307         norm = geompy.MakeTangentOnCurve(localEdgeInFondFiss, u)
308         geompy.addToStudyInFather(partitionPeauFissFond, centre, "norm%d"%iedf)
309         cercle = geompy.MakeCircle(centre, norm, rayonPipe)
310         geompy.addToStudyInFather(partitionPeauFissFond, cercle, "cerclorig%d"%iedf)
311         [vertex] = geompy.ExtractShapes(cercle, geompy.ShapeType["VERTEX"], False)
312         vec1 = geompy.MakeVector(centre, vertex)
313         vec2 = geompy.MakeVector(centre, ptPeau)
314         angle = geompy.GetAngleRadians(vec1, vec2)
315         # cas général : on reconstitue une portion de pipe, avec l'arête de couture qui coincide
316         #   avec la face de fissure, au niveau du débouché sur la face externe
317         # cas dégénéré : le pipe débouche perpendiculairement à une surface plane à l'origine.
318         #   La partition filling / pipe reconstruit échoue.
319         #   - Si on partitionne le filling avec un simple pipe obtenu par extrusion droite du cercle,
320         #     cela donne un point en trop sur le cercle.
321         #   - Si on prend une vraie surface plane (pas un filling), on peut faire la partition avec 
322         #     les pipes reconstruits              
323         logging.debug("angle=%s", angle)
324         #if abs(angle) > 1.e-7:
325         sommetAxe = geompy.MakeTranslationVector(centre, norm)
326         pm = produitMixte(centre, vertex, ptPeau, sommetAxe)
327         if pm > 0:  # ajout de pi a (-)angle pour éviter des points confondus (partition échoue) dans les cas dégénérés
328           cercle = geompy.MakeRotation(cercle, norm, angle + math.pi)
329         else:
330           cercle = geompy.MakeRotation(cercle, norm, -angle + math.pi)
331         name = "cercle%d"%iedf
332         geompy.addToStudyInFather(partitionPeauFissFond, cercle, name)
333         cercles.append(cercle)
334
335         # --- estimation de la longueur du pipe necessaire de part et d'autre du point de sortie
336         if aretesVivesC is None:
337           faceTestPeau = fillingFaceExterne
338         else:
339           faceTestPeau = facesDefaut[ifil]
340         sideCentre = whichSide(faceTestPeau, centre)
341         locPt0 = geompy.MakeVertexOnCurve(localEdgeInFondFiss, 0.0)
342         locPt1 = geompy.MakeVertexOnCurve(localEdgeInFondFiss, 1.0)
343         sidePt0 = whichSide(faceTestPeau, locPt0)
344         sidePt1 = whichSide(faceTestPeau, locPt1)
345         logging.debug("position centre cercle: %s, extremité edge u0: %s, u1: %s", sideCentre, sidePt0, sidePt1) 
346         normFace = geompy.GetNormal(faceTestPeau, ptPeau)
347         inclPipe = abs(geompy.GetAngleRadians(norm, normFace))
348         lgp = max(rayonPipe/2., abs(3*rayonPipe*math.tan(inclPipe)))
349         logging.debug("angle inclinaison Pipe en sortie: %s degres, lgp: %s", inclPipe*180/math.pi, lgp)
350         
351         # --- position des points extremite du pipe sur l'edge debouchante
352         #     il faut la distance curviligne ofp du point central par rapport à une extrémité de l'edge débouchante
353         locEdgePart = geompy.MakePartition([localEdgeInFondFiss],[centre], [], [], geompy.ShapeType["EDGE"], 0, [], 0)
354         edgesLoc = geompy.ExtractShapes(locEdgePart, geompy.ShapeType["EDGE"], False)
355         edgesLocSorted =[(geompy.MinDistance(edge, locPt0), kk, edge) for kk, edge in enumerate(edgesLoc)]
356         edgesLocSorted.sort()
357         ofp = geompy.BasicProperties(edgesLocSorted[0][2])[0] # distance curviligne centre locPt0
358         logging.debug("distance curviligne centre extremite0: %s", ofp)
359         p1 = geompy.MakeVertexOnCurveByLength(localEdgeInFondFiss, ofp +lgp, locPt0)
360         p2 = geompy.MakeVertexOnCurveByLength(localEdgeInFondFiss, ofp -lgp, locPt0)
361         geompy.addToStudyInFather(wireFondFiss, p1, "p1_%d"%iedf)
362         geompy.addToStudyInFather(wireFondFiss, p2, "p2_%d"%iedf)
363
364         edgePart = geompy.MakePartition([localEdgeInFondFiss], [p1,p2], [], [], geompy.ShapeType["EDGE"], 0, [], 0)
365         edps = geompy.ExtractShapes(edgePart, geompy.ShapeType["EDGE"], True)
366         for edp in edps:
367           if geompy.MinDistance(centre, edp) < 1.e-3:
368             pipext = geompy.MakePipe(cercle, edp)
369             name = "pipeExt%d"%iedf
370             geompy.addToStudyInFather(partitionPeauFissFond, pipext, name)
371             pipexts.append(pipext)
372
373         for face in facesInside:
374           logging.debug("recherche edges communes entre une face inside et (faces onside, edges pipe et fond débouchante)")
375           edgesPeauFis = []
376           edgesPipeFis = []
377           edgesPipeFnd = []
378           try:
379             edgesPeauFis = geompy.GetSharedShapesMulti([geompy.MakeCompound(facesOnside), face], geompy.ShapeType["EDGE"])
380             logging.debug("    faces onside %s",edgesPeauFis)
381             edgesPipeFis = geompy.GetSharedShapesMulti([geompy.MakeCompound(edgesPipeIn), face], geompy.ShapeType["EDGE"])
382             logging.debug("    edgesPipeIn %s", edgesPipeFis)
383             edgesPipeFnd = geompy.GetSharedShapesMulti([geompy.MakeCompound(edgesFondIn), face], geompy.ShapeType["EDGE"])
384             logging.debug("    edgesFondIn %s ", edgesPipeFnd)
385           except:
386             logging.debug("  pb edges communes %s %s %s",edgesPeauFis, edgesPipeFis, edgesPipeFnd)
387             pass
388           if (len(edgesPeauFis) > 0) and (len(edgesPipeFis) > 0) and (len(edgesPipeFnd) == 0):
389             dist = geompy.MinDistance(geompy.MakeCompound(edgesPeauFis), ptPeau)
390             logging.debug("    test distance extrémité reference %s", dist)
391             if dist < 1.e-3: # c'est la face de fissure externe associée
392               logging.debug("    face %s inside ajoutée", i)
393               facesFissExt.append(face)
394               name="faceFissExt%d"%iedf
395               geompy.addToStudyInFather(partitionPeauFissFond, face, name)
396               dist = 1.
397               for ipe, edpe in enumerate(edgesPeauFis):
398                 for ipi, edpi in enumerate(edgesPipeFis):
399                   dist = geompy.MinDistance(edpe, edpi)
400                   if dist < 1.e-3:
401                     edgesFissExtPeau.append(edpe)
402                     name="edgesFissExtPeau%d"%iedf
403                     geompy.addToStudyInFather(partitionPeauFissFond, edpe, name)
404                     edgesFissExtPipe.append(edpi)
405                     name="edgesFissExtPipe%d"%iedf
406                     geompy.addToStudyInFather(partitionPeauFissFond, edpi, name)
407                     break
408                 if dist < 1.e-3:
409                   break
410
411       if len(verticesPipePeau) == 0: # aucune extrémité du pipe sur cette face de peau
412                                      # il faut recenser les edges de fissure sur la face de peau
413         j = 0
414         for face in facesInside:
415           edgesPeauFis = []
416           edgesPipeFis = []
417           edgesPipeFnd = []
418           try:
419             edgesPeauFis = geompy.GetSharedShapesMulti([geompy.MakeCompound(facesOnside), face], geompy.ShapeType["EDGE"])
420             edgesPipeFis = geompy.GetSharedShapesMulti([geompy.MakeCompound(edgesPipeIn), face], geompy.ShapeType["EDGE"])
421             edgesPipeFnd = geompy.GetSharedShapesMulti([geompy.MakeCompound(edgesFondIn), face], geompy.ShapeType["EDGE"])
422           except:
423             pass
424           if (len(edgesPeauFis) > 0) and (len(edgesPipeFis) > 0) and (len(edgesPipeFnd) == 0):
425             edgesFissExtPeau.append(edgesPeauFis[0])
426             name="edgesFissExtPeau%d"%j
427             geompy.addToStudyInFather(partitionPeauFissFond, edgesPeauFis[0], name)
428             j += 1
429      
430       # -----------------------------------------------------------------------
431       # --- identification faces de peau : face de peau percée du pipe, extrémités du pipe
432       #     La partition avec le pipe peut créer un vertex (et un edge) de trop sur le cercle projeté,
433       #     quand le cercle est très proche de la face.
434       #     dans ce cas, la projection du cercle sur la face suivie d'une partition permet
435       #     d'éviter le point en trop
436       
437       facesAndFond = facesOnside
438       facesAndFond.append(wireFondFiss)
439       try:
440         partitionPeauByPipe = geompy.MakePartition(facesAndFond, pipexts, [], [], geompy.ShapeType["FACE"], 0, [], 1)
441       except:
442         logging.debug("probleme partition face pipe, contournement avec MakeSection")
443         sections = []
444         for pipext in pipexts:
445           sections.append(geompy.MakeSection(facesOnside[0], pipext))
446         partitionPeauByPipe = geompy.MakePartition(facesAndFond, sections, [], [], geompy.ShapeType["FACE"], 0, [], 1)
447         
448       # contrôle edge en trop sur edges circulaires
449       if len(verticesPipePeau) > 0: # --- au moins une extrémité du pipe sur cette face de peau
450         edgeEnTrop = []
451         outilPart = pipexts
452         facesPeau = geompy.ExtractShapes(partitionPeauByPipe, geompy.ShapeType["FACE"], False)
453         facesPeauSorted, minsur, maxsurf = sortFaces(facesPeau)
454         for i, face in enumerate(facesPeauSorted[:-1]): # on ne teste que la ou les petites faces "circulaires"
455           nbv = geompy.NumberOfEdges(face)
456           logging.debug("nombre d'edges sur face circulaire: %s", nbv)
457           if nbv > 3:
458             edgeEnTrop.append(True) # TODO : distinguer les cas avec deux faces circulaires dont l'une est correcte
459           else:
460             edgeEnTrop.append(False)
461         refaire = sum(edgeEnTrop)
462         if refaire > 0:
463           dc = [(geompy.MinDistance(verticesEdgesFondIn[0], fac), i)  for i, fac in enumerate(facesPeauSorted[:-1])]
464           dc.sort()
465           logging.debug("dc sorted: %s", dc)
466           i0 = dc[0][1] # indice de facesPeauSorted qui correspond à verticesEdgesFondIn[0], donc 0 pour cercles
467           direct = (i0 == 0)
468           for i, bad in enumerate(edgeEnTrop):
469             if direct:
470               j = i
471             else:
472               j = 1-i
473             if bad:
474               outilPart[j] = geompy.MakeProjection(cercles[j],facesOnside[0])
475             pass
476           partitionPeauByPipe = geompy.MakePartition(facesAndFond, outilPart, [], [], geompy.ShapeType["FACE"], 0, [], 1)
477           pass
478           
479       name="partitionPeauByPipe%d"%ifil
480       geompy.addToStudy(partitionPeauByPipe, name)
481       [edgesPeauFondIn, edgesPeauFondOut, edgesPeauFondOn] = extractionOrientee(fillingFaceExterne, partitionPeauByPipe, centreFondFiss, "EDGE", 1.e-3)
482       [facesPeauFondIn, facesPeauFondOut, facesPeauFondOn] = extractionOrientee(fillingFaceExterne, partitionPeauByPipe, centreFondFiss, "FACE", 1.e-3)
483         
484       if len(verticesPipePeau) > 0: # --- au moins une extrémité du pipe sur cette face de peau
485         facesPeauSorted, minsur, maxsurf = sortFaces(facesPeauFondOn)
486         facePeau = facesPeauSorted[-1] # la plus grande face
487       else:
488         facePeau =geompy.MakePartition(facesPeauFondOn, [], [], [], geompy.ShapeType["FACE"], 0, [], 1)
489       name="facePeau%d"%ifil
490       geompy.addToStudy(facePeau, name)
491       
492       facesPipePeau = [None for i in range(len(edgesFissExtPipe))]
493       endsEdgeFond = [None for i in range(len(edgesFissExtPipe))]
494       edgeRadFacePipePeau = [None for i in range(len(edgesFissExtPipe))]
495       
496       edgesListees = []
497       edgesCircPeau = []
498       verticesCircPeau = []
499       if len(verticesPipePeau) > 0: # --- au moins une extrémité du pipe sur cette face de peau
500         
501         for face in facesPeauSorted[:-1]: # la ou les faces débouchantes, pas la grande face de peau
502           logging.debug("examen face debouchante circulaire")
503           for i,efep in enumerate(edgesFissExtPipe):
504             dist = geompy.MinDistance(face, efep)
505             logging.debug("  distance face circulaire edge %s", dist)
506             if dist < 1e-3:
507               for ik, edpfi in enumerate(edgesPeauFondIn):
508                 if geompy.MinDistance(face, edpfi) < 1e-3:
509                   break
510               sharedVertices = geompy.GetSharedShapesMulti([face, edgesPeauFondIn[ik]], geompy.ShapeType["VERTEX"])
511               nameFace = "facePipePeau%d"%i
512               nameVert = "endEdgeFond%d"%i
513               nameEdge = "edgeRadFacePipePeau%d"%i
514               facesPipePeau[i] = face
515               endsEdgeFond[i] = sharedVertices[0]
516               geompy.addToStudy(face, nameFace)
517               geompy.addToStudy(sharedVertices[0], nameVert)
518               edgesFace = geompy.ExtractShapes(face, geompy.ShapeType["EDGE"], True)
519               for edge in edgesFace:
520                 if geompy.MinDistance(edge, sharedVertices[0]) < 1e-3:
521                   edgeRadFacePipePeau[i] = edge
522                   geompy.addToStudy(edge, nameEdge)
523                   break
524                 pass
525               pass
526             pass
527           pass
528         
529         # --- edges circulaires de la face de peau et points de jonction de la face externe de fissure
530         logging.debug("facesPipePeau: %s", facesPipePeau)
531         edgesCircPeau = [None for i in range(len(facesPipePeau))]
532         verticesCircPeau = [None for i in range(len(facesPipePeau))]        
533         for i,fcirc in enumerate(facesPipePeau):
534           edges = geompy.GetSharedShapesMulti([facePeau, fcirc], geompy.ShapeType["EDGE"])
535           grpEdgesCirc = geompy.CreateGroup(facePeau, geompy.ShapeType["EDGE"])
536           geompy.UnionList(grpEdgesCirc, edges)
537           edgesCircPeau[i] = grpEdgesCirc
538           name = "edgeCirc%d"%i
539           geompy.addToStudyInFather(facePeau, grpEdgesCirc, name)
540           edgesListees = edgesListees + edges
541           vertices = geompy.GetSharedShapesMulti([facePeau, fcirc], geompy.ShapeType["VERTEX"])
542           grpVertCircPeau = geompy.CreateGroup(facePeau, geompy.ShapeType["VERTEX"])
543           geompy.UnionList(grpVertCircPeau, vertices)
544           verticesCircPeau[i] = grpVertCircPeau
545           name = "pointEdgeCirc%d"%i
546           geompy.addToStudyInFather(facePeau, grpVertCircPeau, name)
547           pass
548         pass # --- au moins une extrémité du pipe sur cette face de peau
549
550       # --- edges de bord de la face de peau
551
552       edgesFilling = geompy.ExtractShapes(fillingFaceExterne, geompy.ShapeType["EDGE"], False)
553       edgesBords = []
554       for i, edge in enumerate(edgesFilling):
555         edgepeau = geompy.GetInPlace(facePeau, edge)
556         name = "edgepeau%d"%i
557         geompy.addToStudyInFather(facePeau,edgepeau, name)
558         logging.debug("edgepeau %s", geompy.ShapeInfo(edgepeau))
559         if geompy.ShapeInfo(edgepeau)['EDGE'] > 1:
560           logging.debug("  EDGES multiples")
561           edgs = geompy.ExtractShapes(edgepeau, geompy.ShapeType["EDGE"], False)
562           edgesBords += edgs
563           edgesListees += edgs
564         else:
565           logging.debug("  EDGE")
566           edgesBords.append(edgepeau)
567           edgesListees.append(edgepeau)
568       groupEdgesBordPeau = geompy.CreateGroup(facePeau, geompy.ShapeType["EDGE"])
569       geompy.UnionList(groupEdgesBordPeau, edgesBords)
570       bordsVifs = None
571       if aretesVivesC is not None:
572         bordsVifs = geompy.GetInPlace(facePeau, aretesVivesC)
573       if bordsVifs is not None:
574         geompy.addToStudyInFather(facePeau, bordsVifs, "bordsVifs")
575         groupEdgesBordPeau = geompy.CutGroups(groupEdgesBordPeau, bordsVifs)
576         grptmp = None
577         if len(aretesVivesCoupees) > 0:
578           grpC = geompy.MakeCompound(aretesVivesCoupees)
579           grptmp = geompy.GetInPlace(facePeau, grpC)
580         if grptmp is not None:
581           grpnew = geompy.CutGroups(bordsVifs, grptmp) # ce qui est nouveau dans bordsVifs
582         else:
583           grpnew = bordsVifs
584         if grpnew is not None:
585           edv = geompy.ExtractShapes(grpnew, geompy.ShapeType["EDGE"], False)
586           aretesVivesCoupees += edv
587       logging.debug("aretesVivesCoupees %s",aretesVivesCoupees)
588       geompy.addToStudyInFather(facePeau, groupEdgesBordPeau , "EdgesBords")
589         
590       # ---  edges de la face de peau partagées avec la face de fissure
591       
592       edgesPeau = geompy.ExtractShapes(facePeau, geompy.ShapeType["EDGE"], False)
593       edges = substractSubShapes(facePeau, edgesPeau, edgesListees)
594       edgesFissurePeau = []
595       if len(verticesPipePeau) > 0: # --- au moins une extrémité du pipe sur cette face de peau
596         edgesFissurePeau = [None for i in range(len(verticesCircPeau))] # edges associés aux extrémités du pipe, en premier
597         for edge in edges:
598           for i, grpVert in enumerate(verticesCircPeau):
599             if (geompy.MinDistance(grpVert, edge) < 1.e-3) and (edge not in edgesFissurePeau):
600               edgesFissurePeau[i] = edge
601               name = "edgeFissurePeau%d"%i
602               geompy.addToStudyInFather(facePeau,  edge, name)
603         for edge in edges: # on ajoute après les edges manquantes
604           if edge not in edgesFissurePeau:
605             edgesFissurePeau.append(edge)
606       else:
607         for i, edge in enumerate(edges):
608           edgesFissurePeau.append(edge)
609           name = "edgeFissurePeau%d"%i
610           geompy.addToStudyInFather(facePeau,  edge, name)
611         
612
613       ptEdgeFond[ifil] = endsEdgeFond        # pour chaque face [points edge fond de fissure aux débouchés du pipe]
614       fsPipePeau[ifil] = facesPipePeau       # pour chaque face [faces du pipe débouchantes]
615       edRadFPiPo[ifil] = edgeRadFacePipePeau # pour chaque face [edge radiale des faces du pipe débouchantes ]
616       fsFissuExt[ifil] = facesFissExt        # pour chaque face [faces de fissure externes au pipe]
617       edFisExtPe[ifil] = edgesFissExtPeau    # pour chaque face [edge en peau des faces de fissure externes (pas subshape facePeau)]
618       edFisExtPi[ifil] = edgesFissExtPipe    # pour chaque face [edge commun au pipe des faces de fissure externes]
619       facesPeaux[ifil] = facePeau            # pour chaque face : la face de peau finale a mailler (percee des faces débouchantes)
620       edCircPeau[ifil] = edgesCircPeau       # pour chaque face de peau : [groupe subshapes edges circulaires aux débouchés du pipe]
621       ptCircPeau[ifil] = verticesCircPeau    # pour chaque face de peau : [groupe subshapes points sur edges circulaires aux débouchés du pipe]
622       gpedgeBord[ifil] = groupEdgesBordPeau  # pour chaque face de peau : groupe subshape des edges aux bords liés à la partie saine
623       gpedgeVifs[ifil] = bordsVifs           # pour chaque face de peau : groupe subshape des edges aux bords correspondant à des arêtes vives
624       edFissPeau[ifil] = edgesFissurePeau    # pour chaque face de peau : [subshape edge en peau des faces de fissure externes]
625       ptFisExtPi[ifil] = verticesPipePeau    # pour chaque face de peau : [point commun edFissPeau edCircPeau]
626
627   # -----------------------------------------------------------------------
628   # fin de la boucle sur les faces de filling
629   # -----------------------------------------------------------------------
630   
631   for i, avc in enumerate(aretesVivesCoupees):
632     name = "areteViveCoupee%d"%i
633     geompy.addToStudy(avc, name)
634   
635   # --- identification des faces et edges de fissure externe pour maillage
636   
637   facesFissExt = []
638   edgesFissExtPeau = []
639   edgesFissExtPipe = []
640   for ifil in range(nbFacesFilling): # TODO: éliminer les doublons (comparer tous les vertices triés, avec mesure de distance ?)
641     facesFissExt += fsFissuExt[ifil]
642     edgesFissExtPeau += edFisExtPe[ifil]
643     edgesFissExtPipe += edFisExtPi[ifil]
644   logging.debug("---------------------------- identification faces de fissure externes au pipe :%s ", len(facesFissExt))
645   # regroupement des faces de fissure externes au pipe.
646   
647   if len(facesFissExt) > 1:
648     faceFissureExterne = geompy.MakePartition(facesFissExt, [], [], [], geompy.ShapeType["FACE"], 0, [], 0)
649     edgesPipeFissureExterneC = geompy.GetInPlace(faceFissureExterne, geompy.MakeCompound(edgesPipeFiss))    # edgesFissExtPipe peut ne pas couvrir toute la longueur
650     # edgesPeauFissureExterneC = geompy.GetInPlace(faceFissureExterne, geompy.MakeCompound(edgesFissExtPeau))
651     # il peut manquer des edges de faceFissureExterne en contact avec la peau dans edgesFissExtPeau
652     (isDone, closedFreeBoundaries, openFreeBoundaries) = geompy.GetFreeBoundary(faceFissureExterne)
653     edgesBordFFE = []
654     for bound in closedFreeBoundaries:
655       edgesBordFFE += geompy.ExtractShapes(bound, geompy.ShapeType["EDGE"], False)
656     edgesBordFFEid = [ (ed,geompy.GetSubShapeID(faceFissureExterne, ed)) for ed in edgesBordFFE]
657     logging.debug("edgesBordFFEid %s", edgesBordFFEid)
658     edgesPPE = geompy.ExtractShapes(edgesPipeFissureExterneC, geompy.ShapeType["EDGE"], False)
659     edgesPPEid = [ geompy.GetSubShapeID(faceFissureExterne, ed) for ed in edgesPPE]
660     logging.debug("edgesPPEid %s", edgesPPEid)
661     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
662     logging.debug("edgesPFE %s", edgesPFE)
663     edgesPeauFissureExterneC = geompy.MakeCompound(edgesPFE)
664   else:
665     faceFissureExterne = facesFissExt[0]
666     edgesPeauFissureExterneC = geompy.MakeCompound(edgesFissExtPeau)
667     edgesPipeFissureExterneC = geompy.MakeCompound(edgesFissExtPipe)
668   wirePipeFissureExterne = geompy.MakeWire(geompy.ExtractShapes(edgesPipeFissureExterneC, geompy.ShapeType["EDGE"], False))
669   geompy.addToStudy(faceFissureExterne, "faceFissureExterne")
670   geompy.addToStudyInFather(faceFissureExterne, edgesPeauFissureExterneC, "edgesPeauFissureExterne")
671   geompy.addToStudyInFather(faceFissureExterne, edgesPipeFissureExterneC, "edgesPipeFissureExterne")
672   
673   logging.debug("---------------------------- Preparation Maillage du Pipe --------------")
674   # -----------------------------------------------------------------------
675   # --- preparation maillage du pipe :
676   #     - détections des points a respecter : jonction des edges/faces constituant
677   #       la face de fissure externe au pipe
678   #     - points sur les edges de fond de fissure et edges pipe/face fissure,
679   #     - vecteurs tangents au fond de fissure (normal au disque maillé)
680
681   # --- option de maillage selon le rayon de courbure du fond de fissure 
682   lenEdgeFondExt = 0
683   for edff in edgesFondFiss:
684     lenEdgeFondExt += geompy.BasicProperties(edff)[0]
685   
686   disfond = []
687   for filling in facesDefaut:
688     disfond.append(geompy.MinDistance(centreFondFiss, filling))
689   disfond.sort()
690   rcourb = disfond[0]
691   nbSegQuart = 5 # on veut 5 segments min sur un quart de cercle
692   alpha = math.pi/(4*nbSegQuart)
693   deflexion = rcourb*(1.0 -math.cos(alpha))
694   lgmin = lenSegPipe*0.25
695   lgmax = lenSegPipe*1.5               
696   logging.debug("rcourb: %s, lenFond:%s, deflexion: %s, lgmin: %s, lgmax: %s", rcourb, lenEdgeFondExt, deflexion, lgmin, lgmax)  
697
698   meshFondExt = smesh.Mesh(wireFondFiss)
699   algo1d = meshFondExt.Segment()
700   hypo1d = algo1d.Adaptive(lgmin, lgmax, deflexion) # a ajuster selon la profondeur de la fissure
701   isDone = meshFondExt.Compute()
702   
703   ptGSdic = {} # dictionnaire [paramètre sur la courbe] --> point géométrique
704   allNodeIds = meshFondExt.GetNodesId()
705   for nodeId in allNodeIds:
706     xyz = meshFondExt.GetNodeXYZ(nodeId)
707     #logging.debug("nodeId %s, coords %s", nodeId, str(xyz))
708     pt = geompy.MakeVertex(xyz[0], xyz[1], xyz[2])
709     u, PointOnEdge, EdgeInWireIndex = geompy.MakeProjectionOnWire(pt, wireFondFiss) # u compris entre 0 et 1
710     edgeOrder = edgesIdByOrientation[EdgeInWireIndex]
711     ptGSdic[(edgeOrder, EdgeInWireIndex, u)] = pt
712     #logging.debug("nodeId %s, u %s", nodeId, str(u))
713   usort = sorted(ptGSdic)  
714   logging.debug("nombre de points obtenus par deflexion %s",len(usort))
715      
716   centres = []
717   origins = []
718   normals = []      
719   for edu in usort:
720     ied = edu[1]
721     u = edu[2]
722     vertcx = ptGSdic[edu]
723     norm = geompy.MakeTangentOnCurve(edgesFondFiss[ied], u)
724     plan = geompy.MakePlane(vertcx, norm, 3*rayonPipe)
725     part = geompy.MakePartition([plan], [wirePipeFiss], [], [], geompy.ShapeType["VERTEX"], 0, [], 0)
726     liste = geompy.ExtractShapes(part, geompy.ShapeType["VERTEX"], True)
727     if len(liste) == 5: # 4 coins du plan plus intersection recherchée
728       for point in liste:
729         if geompy.MinDistance(point, vertcx) < 1.1*rayonPipe: # les quatre coins sont plus loin
730           vertpx = point
731           break
732       centres.append(vertcx)
733       origins.append(vertpx)
734       normals.append(norm)
735 #      name = "vertcx%d"%i
736 #      geompy.addToStudyInFather(wireFondFiss, vertcx, name)
737 #      name = "vertpx%d"%i
738 #      geompy.addToStudyInFather(wireFondFiss, vertpx, name)
739 #      name = "plan%d"%i
740 #      geompy.addToStudyInFather(wireFondFiss, plan, name)
741
742   # --- maillage du pipe étendu, sans tenir compte de l'intersection avec la face de peau
743       
744   logging.debug("nbsegCercle %s", nbsegCercle)
745   
746   # -----------------------------------------------------------------------
747   # --- points géométriques
748   
749   gptsdisks = [] # vertices géométrie de tous les disques
750   raydisks = [[] for i in range(nbsegCercle)]
751   for i in range(len(centres)): # boucle sur les disques
752     gptdsk = [] # vertices géométrie d'un disque
753     vertcx = centres[i]
754     vertpx = origins[i]
755     normal = normals[i]
756     vec1 = geompy.MakeVector(vertcx, vertpx)
757     
758     points = [vertcx] # les points du rayon de référence
759     for j in range(nbsegRad):
760       pt = geompy.MakeTranslationVectorDistance(vertcx, vec1, (j+1)*float(rayonPipe)/nbsegRad)
761       points.append(pt)
762     gptdsk.append(points)
763     pt = geompy.MakeTranslationVectorDistance(vertcx, vec1, 1.5*rayonPipe)
764     rayon = geompy.MakeLineTwoPnt(vertcx, pt)
765     raydisks[0].append(rayon)
766     
767     for k in range(nbsegCercle-1):
768       angle = (k+1)*2*math.pi/nbsegCercle
769       pts = [vertcx] # les points d'un rayon obtenu par rotation
770       for j in range(nbsegRad):
771         pt = geompy.MakeRotation(points[j+1], normal, angle)
772         pts.append(pt)
773       gptdsk.append(pts)
774       ray = geompy.MakeRotation(rayon, normal, angle)
775       raydisks[k+1].append(ray)
776       
777     gptsdisks.append(gptdsk) 
778  
779   # -----------------------------------------------------------------------
780   # --- recherche des points en trop (externes au volume à remailler)
781   #     - on associe chaque extrémité du pipe à une face filling 
782   #     - on part des disques aux extrémités du pipe
783   #     - pour chaque disque, on prend les vertices de géométrie,
784   #       on marque leur position relative à la face.
785   #     - on s'arrete quand tous les noeuds sont dedans
786   
787   logging.debug("---------------------------- recherche des points du pipe a éliminer --------------")
788
789   pt0 = centres[0]
790   pt1 = centres[-1]
791   idFillingFromBout = [None, None]                 # contiendra l'index du filling pour les extrémités 0 et 1
792   for ifil in range(nbFacesFilling):
793     for ipt, pt in enumerate(ptEdgeFond[ifil]): # il y a un ou deux points débouchant sur cette face
794       if geompy.MinDistance(pt,pt0) < geompy.MinDistance(pt,pt1): # TODO: trouver plus fiable pour les cas tordus...
795         idFillingFromBout[0] = ifil
796       else: 
797         idFillingFromBout[1] = ifil
798   logging.debug("association bouts du pipe - faces de filling: %s", idFillingFromBout)
799   
800   facesPipePeau = []
801   edgeRadFacePipePeau = []
802   for ifil in range(nbFacesFilling):
803     facesPipePeau += fsPipePeau[ifil]
804     edgeRadFacePipePeau += edRadFPiPo[ifil]
805     
806   logging.debug("recherche des disques de noeuds complètement internes")
807   idisklim = [] # indices des premier et dernier disques internes
808   idiskout = [] # indices des premier et dernier disques externes
809   for bout in range(2):
810     if bout == 0:
811       idisk = -1
812       inc = 1
813       numout = -1
814     else:
815       idisk = len(gptsdisks)
816       inc = -1
817       numout = len(gptsdisks)
818     inside = False
819     outside = True
820     while not inside:
821       idisk = idisk + inc
822       logging.debug("examen disque %s", idisk)
823       gptdsk = gptsdisks[idisk]
824       inside = True
825       for k in range(nbsegCercle):
826         points = gptdsk[k]
827         for j, pt in enumerate(points):
828           side = whichSideVertex(facesDefaut[idFillingFromBout[bout]], pt)
829           if side < 0:
830             if outside: # premier point detecté dedans
831               outside = False
832               numout = idisk -inc # le disque précédent était dehors
833           else:
834             inside = False # ce point est dehors              
835         if not inside and not outside:
836           break
837     idisklim.append(idisk)  # premier et dernier disques internes
838     idiskout.append(numout) # premier et dernier disques externes
839     
840   # --- listes de nappes radiales en filling à chaque extrémité débouchante
841   facesDebouchantes = [False, False]
842   idFacesDebouchantes = [-1, -1] # contiendra les indices des faces disque débouchantes (facesPipePeau)
843   listNappes =[]
844   for i, idisk in enumerate(idisklim):
845     numout = idiskout[i]
846     logging.debug("extremité %s, indices disques interne %s, externe %s",i, idisk, numout)
847     nappes = []
848     if  (idisk != 0) and (idisk != len(gptsdisks)-1): # si extrémité débouchante
849       for k in range(nbsegCercle):
850         if i == 0:
851           iddeb = max(0, numout)
852           idfin = max(iddeb+3,idisk+1) # il faut 3 rayons pour faire un filling qui suive le fond de fissure
853           #logging.debug("extremité %s, indices retenus interne %s, externe %s",i, idfin, iddeb)
854           comp = geompy.MakeCompound(raydisks[k][iddeb:idfin])
855           name='compoundRay%d'%k
856           geompy.addToStudy(comp, name)
857         else:
858           idfin = min(len(gptsdisks), numout+1)
859           iddeb = min(idfin-3, idisk) # il faut 3 rayons pour faire un filling qui suive le fond de fissure
860           #logging.debug("extremité %s, indices retenus interne %s, externe %s",i, idfin, iddeb)
861           comp = geompy.MakeCompound(raydisks[k][iddeb:idfin])
862           name='compoundRay%d'%k
863           geompy.addToStudy(comp, name)
864         nappe = geompy.MakeFilling(comp, 2, 5, 0.0001, 0.0001, 0, GEOM.FOM_Default)
865         nappes.append(nappe)
866         name='nappe%d'%k
867         geompy.addToStudy(nappe, name)
868         facesDebouchantes[i] = True
869     listNappes.append(nappes)
870       
871   # --- mise en correspondance avec les indices des faces disque débouchantes (facesPipePeau)
872   for i, nappes in enumerate(listNappes):
873     if facesDebouchantes[i]:
874       for k, face in enumerate(facesPipePeau):
875         edge = geompy.MakeSection(face, nappes[0])
876         if geompy.NbShapes(edge, geompy.ShapeType["EDGE"]) > 0:
877           idFacesDebouchantes[i] = k
878           break
879   logging.debug("idFacesDebouchantes: %s", idFacesDebouchantes)
880
881   # --- construction des listes d'edges radiales sur chaque extrémité débouchante
882   listEdges = []
883   for i, nappes in enumerate(listNappes):
884     id = idFacesDebouchantes[i] # indice de face débouchante (facesPipePeau)
885     if id < 0:
886       listEdges.append([])
887     else:
888       face = facesPipePeau[id]
889       edges = [edgeRadFacePipePeau[id]]
890       for k, nappe in enumerate(nappes):
891         if k > 0:
892           obj = geompy.MakeSection(face, nappes[k]) # normalement une edge, parfois un compound d'edges dont un tout petit
893           edge = obj
894           vs = geompy.ExtractShapes(obj, geompy.ShapeType["VERTEX"], False)
895           if len(vs) > 2:
896             eds = geompy.ExtractShapes(obj, geompy.ShapeType["EDGE"], False)
897             [edsorted, minl,maxl] = sortEdges(eds)
898             edge = edsorted[-1]
899           else:
900             maxl = geompy.BasicProperties(edge)[0]
901           if maxl < 0.01: # problème MakeSection
902             logging.debug("problème MakeSection recherche edge radiale %s, longueur trop faible: %s, utilisation partition", k, maxl)
903             partNappeFace = geompy.MakePartition([face, nappes[k]], [] , [], [], geompy.ShapeType["FACE"], 0, [], 0)
904             edps= geompy.ExtractShapes(partNappeFace, geompy.ShapeType["EDGE"], False)
905             ednouv = []
906             for ii, ed in enumerate(edps):
907               vxs = geompy.ExtractShapes(ed, geompy.ShapeType["VERTEX"], False)
908               distx = [geompy.MinDistance(vx, face) for vx in vxs]
909               distx += [geompy.MinDistance(vx, nappes[k]) for vx in vxs]
910               dmax = max(distx)
911               logging.debug("  dmax %s",dmax)
912               if dmax < 0.01:
913                 ednouv.append(ed)
914             logging.debug("  edges issues de la partition: %s", ednouv)
915             for ii, ed in enumerate(ednouv):
916               geompy.addToStudy(ed, "ednouv%d"%ii)
917             [edsorted, minl,maxl] = sortEdges(ednouv)
918             logging.debug("  longueur edge trouvée: %s", maxl) 
919             edge = edsorted[-1]
920           edges.append(edge)
921           name = 'edgeEndPipe%d'%k
922           geompy.addToStudy(edge, name)
923       listEdges.append(edges)
924
925   # --- création des points du maillage du pipe sur la face de peau
926   for i, edges in enumerate(listEdges):
927     id = idFacesDebouchantes[i] # indice de face débouchante (facesPipePeau)
928     if id >= 0:
929       gptdsk = []
930       if id > 0: # id vaut 0 ou 1
931         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)
932       centre = ptEdgeFond[idFillingFromBout[i]][id]
933       name = "centre%d"%id
934       geompy.addToStudy(centre, name)
935       vertPipePeau = ptFisExtPi[idFillingFromBout[i]][id]
936       geompy.addToStudyInFather(centre, vertPipePeau, "vertPipePeau")
937       grpsEdgesCirc = edCircPeau[idFillingFromBout[i]] # liste de groupes
938       edgesCirc = []
939       for grpEdgesCirc in grpsEdgesCirc:
940         edgesCirc += geompy.ExtractShapes(grpEdgesCirc, geompy.ShapeType["EDGE"], False)
941       for k, edge in enumerate(edges):
942         extrems = geompy.ExtractShapes(edge, geompy.ShapeType["VERTEX"], True)
943         if geompy.MinDistance(centre, extrems[0]) < geompy.MinDistance(centre, extrems[1]):
944           bout = extrems[1]
945         else:
946           bout = extrems[0]
947         # ajustement du point extrémité (bout) sur l'edge circulaire en face de peau
948         logging.debug("edgesCirc: %s", edgesCirc)
949         distEdgeCirc = [(geompy.MinDistance(bout, edgeCirc), k2, edgeCirc) for k2, edgeCirc in enumerate(edgesCirc)]
950         distEdgeCirc.sort()
951         logging.debug("distEdgeCirc: %s", distEdgeCirc)
952         u = projettePointSurCourbe(bout, distEdgeCirc[0][2])
953         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.
954           extrCircs = geompy.ExtractShapes(distEdgeCirc[0][2], geompy.ShapeType["VERTEX"], True)
955           if geompy.MinDistance(bout, extrCircs[0]) < geompy.MinDistance(bout, extrCircs[1]):
956             bout = extrCircs[0]
957           else:
958             bout = extrCircs[1]
959           pass
960         else:
961           bout = geompy.MakeVertexOnCurve(distEdgeCirc[0][2], u)
962         name ="bout%d"%k
963         geompy.addToStudyInFather(centre, bout, name)
964         # enregistrement des points dans la structure
965         points = []
966         for j in range(nbsegRad +1):
967           u = j/float(nbsegRad)
968           points.append(geompy.MakeVertexOnCurve(edge, u))
969         if geompy.MinDistance(bout, points[0]) < geompy.MinDistance(centre, points[0]):
970           points.reverse()
971         points[0] = centre
972         points[-1] = bout
973         gptdsk.append(points)
974       if i == 0:
975         gptsdisks[idisklim[0] -1] = gptdsk
976         idisklim[0] = idisklim[0] -1
977       else:
978         gptsdisks[idisklim[1] +1] = gptdsk
979         idisklim[1] = idisklim[1] +1
980
981   # --- ajustement precis des points sur edgesPipeFissureExterneC
982   
983   edgesPFE = geompy.ExtractShapes(edgesPipeFissureExterneC, geompy.ShapeType["EDGE"], False)
984   verticesPFE = findWireIntermediateVertices(wirePipeFissureExterne)  # vertices intermédiaires (des points en trop dans ptsInWireFissExtPipe)
985   idiskmin = idisklim[0] + 1 # on ne prend pas le disque sur la peau, déjà ajusté
986   idiskmax = idisklim[1]     # on ne prend pas le disque sur la peau, déjà ajusté
987   idiskint = []
988   for vtx in verticesPFE:
989     distPtVt = []
990     for idisk in range(idiskmin, idiskmax):
991       gptdsk = gptsdisks[idisk]
992       pt = gptdsk[0][-1]       # le point sur l'edge de la fissure externe au pipe
993       distPtVt.append((geompy.MinDistance(pt, vtx), idisk))
994     distPtVt.sort()
995     idiskint.append(distPtVt[0][1])
996     gptsdisks[idiskint[-1]][0][-1] = vtx
997     logging.debug("ajustement point sur edgePipeFissureExterne, vertex: %s %s", idiskint[-1], distPtVt[0][0])
998   for idisk in range(idiskmin, idiskmax):
999     if idisk in idiskint:
1000       break
1001     logging.debug("ajustement point sur edgePipeFissureExterne: %s", idisk)
1002     gptdsk = gptsdisks[idisk]
1003     pt = gptdsk[0][-1]       # le point sur l'edge de la fissure externe au pipe
1004     distPtEd = [(geompy.MinDistance(pt, edgePFE), k, edgePFE) for k, edgePFE in enumerate(edgesPFE)]
1005     distPtEd.sort()
1006     edgePFE = distPtEd[0][2]
1007     u = projettePointSurCourbe(pt, edgePFE)
1008     ptproj = geompy.MakeVertexOnCurve(edgePFE, u)
1009     gptsdisks[idisk][0][-1] = ptproj
1010   
1011   # -----------------------------------------------------------------------
1012   # --- maillage effectif du pipe
1013
1014   logging.debug("---------------------------- maillage effectif du pipe --------------")
1015   meshPipe = smesh.Mesh(None, "meshPipe")
1016   fondFissGroup = meshPipe.CreateEmptyGroup(SMESH.EDGE, "FONDFISS")
1017   nodesFondFissGroup = meshPipe.CreateEmptyGroup(SMESH.NODE, "nfondfis")
1018   faceFissGroup = meshPipe.CreateEmptyGroup(SMESH.FACE, "fisInPi")
1019   edgeFaceFissGroup = meshPipe.CreateEmptyGroup(SMESH.EDGE, "edgeFaceFiss")
1020   edgeCircPipe0Group = meshPipe.CreateEmptyGroup(SMESH.EDGE, "edgeCircPipe0")
1021   edgeCircPipe1Group = meshPipe.CreateEmptyGroup(SMESH.EDGE, "edgeCircPipe1")
1022   faceCircPipe0Group = meshPipe.CreateEmptyGroup(SMESH.FACE, "faceCircPipe0")
1023   faceCircPipe1Group = meshPipe.CreateEmptyGroup(SMESH.FACE, "faceCircPipe1")
1024   mptsdisks = []  # vertices maillage de tous les disques
1025   mEdges = []     # identifiants edges maillage fond de fissure
1026   mEdgeFaces = [] # identifiants edges maillage edge face de fissure externe
1027   mFaces = []     # identifiants faces maillage fissure
1028   mVols  = []     # identifiants volumes maillage pipe
1029
1030   mptdsk = None
1031   for idisk in range(idisklim[0], idisklim[1]+1): # boucle sur les disques internes
1032     
1033     # -----------------------------------------------------------------------
1034     # --- points
1035     
1036     gptdsk = gptsdisks[idisk]
1037     if idisk > idisklim[0]:
1038       oldmpts = mptdsk
1039     mptdsk = [] # vertices maillage d'un disque
1040     for k in range(nbsegCercle):
1041       points = gptdsk[k]
1042       mptids = []
1043       for j, pt in enumerate(points):
1044         if j == 0 and k > 0:
1045           id = mptdsk[0][0]
1046         else:
1047           coords = geompy.PointCoordinates(pt)
1048           id = meshPipe.AddNode(coords[0], coords[1], coords[2])
1049         mptids.append(id)
1050       mptdsk.append(mptids)
1051     mptsdisks.append(mptdsk)
1052     
1053     # -----------------------------------------------------------------------
1054     # --- groupes edges cercles debouchants
1055     
1056     if idisk == idisklim[0]:
1057       pts = []
1058       for k in range(nbsegCercle):
1059         pts.append(mptdsk[k][-1])
1060       edges = []
1061       for k in range(len(pts)):
1062         k1 = (k+1)%len(pts)
1063         idEdge = meshPipe.AddEdge([pts[k], pts[k1]])
1064         edges.append(idEdge)
1065       edgeCircPipe0Group.Add(edges)
1066        
1067     if idisk == idisklim[1]:
1068       pts = []
1069       for k in range(nbsegCercle):
1070         pts.append(mptdsk[k][-1])
1071       edges = []
1072       for k in range(len(pts)):
1073         k1 = (k+1)%len(pts)
1074         idEdge = meshPipe.AddEdge([pts[k], pts[k1]])
1075         edges.append(idEdge)
1076       edgeCircPipe1Group.Add(edges)
1077     
1078     # -----------------------------------------------------------------------
1079     # --- groupes faces  debouchantes
1080     
1081     if idisk == idisklim[0]:
1082       faces = []
1083       for j in range(nbsegRad):
1084         for k in range(nbsegCercle):
1085           k1 = k+1
1086           if k ==  nbsegCercle-1:
1087             k1 = 0
1088           if j == 0:
1089             idf = meshPipe.AddFace([mptdsk[k][0], mptdsk[k][1], mptdsk[k1][1]]) # triangle
1090           else:
1091             idf = meshPipe.AddFace([mptdsk[k][j], mptdsk[k][j+1], mptdsk[k1][j+1], mptdsk[k1][j]]) # quadrangle
1092           faces.append(idf)
1093       faceCircPipe0Group.Add(faces)
1094
1095     if idisk == idisklim[1]:
1096       faces = []
1097       for j in range(nbsegRad):
1098         for k in range(nbsegCercle):
1099           k1 = k+1
1100           if k ==  nbsegCercle-1:
1101             k1 = 0
1102           if j == 0:
1103             idf = meshPipe.AddFace([mptdsk[k][0], mptdsk[k][1], mptdsk[k1][1]]) # triangle
1104           else:
1105             idf = meshPipe.AddFace([mptdsk[k][j], mptdsk[k][j+1], mptdsk[k1][j+1], mptdsk[k1][j]]) # quadrangle
1106           faces.append(idf)
1107       faceCircPipe1Group.Add(faces)
1108           
1109     # -----------------------------------------------------------------------
1110     # --- mailles volumiques, groupes noeuds et edges de fond de fissure, groupe de face de fissure
1111     
1112     if idisk == idisklim[0]:
1113       mEdges.append(0)
1114       mEdgeFaces.append(0)
1115       mFaces.append([0])
1116       mVols.append([[0]])
1117       nodesFondFissGroup.Add([mptdsk[0][0]])
1118     else:
1119       ide = meshPipe.AddEdge([oldmpts[0][0], mptdsk[0][0]])
1120       mEdges.append(ide)
1121       fondFissGroup.Add([ide])
1122       nodesFondFissGroup.Add([mptdsk[0][0]])
1123       ide2 = meshPipe.AddEdge([oldmpts[0][-1], mptdsk[0][-1]])
1124       mEdgeFaces.append(ide2)
1125       edgeFaceFissGroup.Add([ide2])
1126       idFaces = []
1127       idVols = []
1128       
1129       for j in range(nbsegRad):
1130         idf = meshPipe.AddFace([oldmpts[0][j], mptdsk[0][j], mptdsk[0][j+1], oldmpts[0][j+1]])
1131         faceFissGroup.Add([idf])
1132         idFaces.append(idf)
1133         
1134         idVolCercle = []
1135         for k in range(nbsegCercle):
1136           k1 = k+1
1137           if k ==  nbsegCercle-1:
1138             k1 = 0
1139           if j == 0:
1140             idv = meshPipe.AddVolume([mptdsk[k][j], mptdsk[k][j+1], mptdsk[k1][j+1],
1141                                       oldmpts[k][j], oldmpts[k][j+1], oldmpts[k1][j+1]])
1142           else:
1143             idv = meshPipe.AddVolume([mptdsk[k][j], mptdsk[k][j+1], mptdsk[k1][j+1], mptdsk[k1][j],
1144                                       oldmpts[k][j], oldmpts[k][j+1], oldmpts[k1][j+1], oldmpts[k1][j]])
1145           idVolCercle.append(idv)
1146         idVols.append(idVolCercle)  
1147         
1148       mFaces.append(idFaces)
1149       mVols.append(idVols)
1150
1151   pipeFissGroup = meshPipe.CreateEmptyGroup( SMESH.VOLUME, 'PIPEFISS' )
1152   nbAdd = pipeFissGroup.AddFrom( meshPipe.GetMesh() )
1153
1154   nb, new_mesh, new_group = meshPipe.MakeBoundaryElements(SMESH.BND_2DFROM3D, "pipeBoundaries")
1155   edgesCircPipeGroup = [edgeCircPipe0Group, edgeCircPipe1Group]
1156
1157   # --- fin du maillage du pipe
1158   # -----------------------------------------------------------------------
1159   # --- edges de bord, faces défaut à respecter
1160
1161   aFilterManager = smesh.CreateFilterManager()
1162   nbAdded, internalBoundary, _NoneGroup = internalBoundary.MakeBoundaryElements( SMESH.BND_1DFROM2D, '', '', 0, [  ])
1163   criteres = []
1164   unCritere = smesh.GetCriterion(SMESH.EDGE,SMESH.FT_FreeBorders,SMESH.FT_Undefined,0)
1165   criteres.append(unCritere)
1166   filtre = smesh.GetFilterFromCriteria(criteres)
1167   bordsLibres = internalBoundary.MakeGroupByFilter( 'bords', filtre )
1168   smesh.SetName(bordsLibres, 'bordsLibres')
1169
1170   # --- pour aider l'algo hexa-tetra à ne pas mettre de pyramides à l'exterieur des volumes repliés sur eux-mêmes
1171   #     on désigne les faces de peau en quadrangles par le groupe "skinFaces"
1172
1173   skinFaces = internalBoundary.CreateEmptyGroup( SMESH.FACE, 'skinFaces' )
1174   nbAdd = skinFaces.AddFrom( internalBoundary.GetMesh() )
1175
1176   # --- maillage des éventuelles arêtes vives entre faces reconstruites
1177   
1178   if len(aretesVivesCoupees) > 0:
1179     aretesVivesC = geompy.MakeCompound(aretesVivesCoupees)
1180     meshAretesVives = smesh.Mesh(aretesVivesC)
1181     algo1d = meshAretesVives.Segment()
1182     hypo1d = algo1d.LocalLength(dmoyen/3.0,[],1e-07)
1183     putName(algo1d.GetSubMesh(), "aretesVives")
1184     putName(algo1d, "algo1d_aretesVives")
1185     putName(hypo1d, "hypo1d_aretesVives")
1186     isDone = meshAretesVives.Compute()
1187     logging.info("aretesVives fini")
1188     grpAretesVives = meshAretesVives.CreateEmptyGroup( SMESH.EDGE, 'grpAretesVives' )
1189     nbAdd = grpAretesVives.AddFrom( meshAretesVives.GetMesh() )
1190
1191   # -----------------------------------------------------------------------
1192   # --- maillage faces de fissure
1193   
1194   logging.debug("---------------------------- maillage faces de fissure externes au pipe :%s --------------", len(facesFissExt))
1195
1196   meshFaceFiss = smesh.Mesh(faceFissureExterne)
1197   algo2d = meshFaceFiss.Triangle(algo=smeshBuilder.NETGEN_1D2D)
1198   hypo2d = algo2d.Parameters()
1199   hypo2d.SetMaxSize( areteFaceFissure )
1200   hypo2d.SetSecondOrder( 0 )
1201   hypo2d.SetOptimize( 1 )
1202   hypo2d.SetFineness( 2 )
1203   hypo2d.SetMinSize( rayonPipe/float(nbsegRad) )
1204   hypo2d.SetQuadAllowed( 0 )
1205   putName(algo2d.GetSubMesh(), "faceFiss")
1206   putName(algo2d, "algo2d_faceFiss")
1207   putName(hypo2d, "hypo2d_faceFiss")
1208   
1209   algo1d = meshFaceFiss.UseExisting1DElements(geom=edgesPipeFissureExterneC)
1210   hypo1d = algo1d.SourceEdges([ edgeFaceFissGroup ],0,0)
1211   putName(algo1d.GetSubMesh(), "edgeFissPeau")
1212   putName(algo1d, "algo1d_edgeFissPeau")
1213   putName(hypo1d, "hypo1d_edgeFissPeau")
1214   
1215   isDone = meshFaceFiss.Compute()
1216   logging.info("meshFaceFiss fini")
1217
1218   grpFaceFissureExterne = meshFaceFiss.GroupOnGeom(faceFissureExterne, "fisOutPi", SMESH.FACE)
1219   grpEdgesPeauFissureExterne = meshFaceFiss.GroupOnGeom(edgesPeauFissureExterneC,'edgesPeauFissureExterne',SMESH.EDGE)
1220   grpEdgesPipeFissureExterne = meshFaceFiss.GroupOnGeom(edgesPipeFissureExterneC,'edgesPipeFissureExterne',SMESH.EDGE)
1221
1222   # --- maillage faces de peau
1223     
1224   boutFromIfil = [None for i in range(nbFacesFilling)]
1225   if idFillingFromBout[0] != idFillingFromBout[1]: # repérage des extremites du pipe quand elles débouchent sur des faces différentes
1226     boutFromIfil[idFillingFromBout[0]] = 0
1227     boutFromIfil[idFillingFromBout[1]] = 1
1228   
1229   logging.debug("---------------------------- maillage faces de peau --------------")
1230   meshesFacesPeau = []
1231   for ifil in range(nbFacesFilling):
1232     meshFacePeau = None
1233     if partitionsPeauFissFond[ifil] is None: # face de peau maillage sain intacte
1234       
1235       # --- edges de bord de la face de filling
1236       filling = facesDefaut[ifil]
1237       edgesFilling = geompy.ExtractShapes(filling, geompy.ShapeType["EDGE"], False)
1238       groupEdgesBordPeau = geompy.CreateGroup(filling, geompy.ShapeType["EDGE"])
1239       geompy.UnionList(groupEdgesBordPeau, edgesFilling)
1240       geompy.addToStudyInFather(filling, groupEdgesBordPeau , "EdgesBords")
1241       
1242       meshFacePeau = smesh.Mesh(facesDefaut[ifil])
1243       
1244       algo1d = meshFacePeau.UseExisting1DElements(geom=groupEdgesBordPeau)
1245       hypo1d = algo1d.SourceEdges([ bordsLibres ],0,0)
1246       putName(algo1d.GetSubMesh(), "bordsLibres", ifil)
1247       putName(algo1d, "algo1d_bordsLibres", ifil)
1248       putName(hypo1d, "hypo1d_bordsLibres", ifil)
1249       
1250     else:
1251       
1252       facePeau           = facesPeaux[ifil] # pour chaque face : la face de peau finale a mailler (percée des faces débouchantes)
1253       edgesCircPeau      = edCircPeau[ifil] # pour chaque face de peau : [subshape edge circulaire aux débouchés du pipe]
1254       verticesCircPeau   = ptCircPeau[ifil] # pour chaque face de peau : [subshape point sur edge circulaire aux débouchés du pipe]
1255       groupEdgesBordPeau = gpedgeBord[ifil] # pour chaque face de peau : groupe subshape des edges aux bords liés à la partie saine
1256       bordsVifs          = gpedgeVifs[ifil] # pour chaque face de peau : groupe subshape des edges aux bords correspondant à des arêtes vives
1257       edgesFissurePeau   = edFissPeau[ifil] # pour chaque face de peau : [subshape edge en peau des faces de fissure externes]
1258
1259       meshFacePeau = smesh.Mesh(facePeau)
1260       
1261       algo1d = meshFacePeau.UseExisting1DElements(geom=groupEdgesBordPeau)
1262       hypo1d = algo1d.SourceEdges([ bordsLibres ],0,0)
1263       putName(algo1d.GetSubMesh(), "bordsLibres", ifil)
1264       putName(algo1d, "algo1d_bordsLibres", ifil)
1265       putName(hypo1d, "hypo1d_bordsLibres", ifil)
1266       
1267       algo1d = meshFacePeau.UseExisting1DElements(geom=geompy.MakeCompound(edgesFissurePeau))
1268       hypo1d = algo1d.SourceEdges([ grpEdgesPeauFissureExterne ],0,0)
1269       putName(algo1d.GetSubMesh(), "edgePeauFiss", ifil)
1270       putName(algo1d, "algo1d_edgePeauFiss", ifil)
1271       putName(hypo1d, "hypo1d_edgePeauFiss", ifil)
1272       
1273       if bordsVifs is not None:
1274         algo1d = meshFacePeau.UseExisting1DElements(geom=bordsVifs)
1275         hypo1d = algo1d.SourceEdges([ grpAretesVives ],0,0)
1276         putName(algo1d.GetSubMesh(), "bordsVifs", ifil)
1277         putName(algo1d, "algo1d_bordsVifs", ifil)
1278         putName(hypo1d, "hypo1d_bordsVifs", ifil)
1279         
1280       for i, edgeCirc in enumerate(edgesCircPeau):
1281         if edgeCirc is not None:
1282           algo1d = meshFacePeau.UseExisting1DElements(geom=edgeCirc)
1283           if boutFromIfil[ifil] is None:
1284             hypo1d = algo1d.SourceEdges([ edgesCircPipeGroup[i] ],0,0)
1285           else:
1286             hypo1d = algo1d.SourceEdges([ edgesCircPipeGroup[boutFromIfil[ifil]] ],0,0)
1287           name = "cercle%d"%i
1288           putName(algo1d.GetSubMesh(), name, ifil)
1289           putName(algo1d, "algo1d_" + name, ifil)
1290           putName(hypo1d, "hypo1d_" + name, ifil)
1291    
1292     algo2d = meshFacePeau.Triangle(algo=smeshBuilder.NETGEN_1D2D)
1293     hypo2d = algo2d.Parameters()
1294     hypo2d.SetMaxSize( dmoyen )
1295     hypo2d.SetOptimize( 1 )
1296     hypo2d.SetFineness( 2 )
1297     hypo2d.SetMinSize( rayonPipe/float(nbsegRad) )
1298     hypo2d.SetQuadAllowed( 0 )
1299     putName(algo2d.GetSubMesh(), "facePeau", ifil)
1300     putName(algo2d, "algo2d_facePeau", ifil)
1301     putName(hypo2d, "hypo2d_facePeau", ifil)
1302       
1303     isDone = meshFacePeau.Compute()
1304     logging.info("meshFacePeau %d fini", ifil)
1305     GroupFaces = meshFacePeau.CreateEmptyGroup( SMESH.FACE, "facePeau%d"%ifil )
1306     nbAdd = GroupFaces.AddFrom( meshFacePeau.GetMesh() )
1307     meshesFacesPeau.append(meshFacePeau)
1308
1309   # --- regroupement des maillages du défaut
1310
1311   listMeshes = [internalBoundary.GetMesh(),
1312                 meshPipe.GetMesh(),
1313                 meshFaceFiss.GetMesh()]
1314   for mp in meshesFacesPeau:
1315     listMeshes.append(mp.GetMesh())
1316
1317   meshBoiteDefaut = smesh.Concatenate(listMeshes, 1, 1, 1e-05,False)
1318   # pour aider l'algo hexa-tetra à ne pas mettre de pyramides à l'exterieur des volumes repliés sur eux-mêmes
1319   # on désigne les faces de peau en quadrangles par le groupe "skinFaces"
1320   group_faceFissOutPipe = None
1321   group_faceFissInPipe = None
1322   groups = meshBoiteDefaut.GetGroups()
1323   for grp in groups:
1324     if grp.GetType() == SMESH.FACE:
1325       #if "internalBoundary" in grp.GetName():
1326       #  grp.SetName("skinFaces")
1327       if grp.GetName() == "fisOutPi":
1328         group_faceFissOutPipe = grp
1329       elif grp.GetName() == "fisInPi":
1330         group_faceFissInPipe = grp
1331
1332   # le maillage NETGEN ne passe pas toujours ==> utiliser GHS3D
1333   distene=True
1334   if distene:
1335     algo3d = meshBoiteDefaut.Tetrahedron(algo=smeshBuilder.GHS3D)
1336   else:
1337     algo3d = meshBoiteDefaut.Tetrahedron(algo=smeshBuilder.NETGEN)
1338     hypo3d = algo3d.MaxElementVolume(1000.0)
1339   putName(algo3d.GetSubMesh(), "boiteDefaut")
1340   putName(algo3d, "algo3d_boiteDefaut")
1341   isDone = meshBoiteDefaut.Compute()
1342   putName(meshBoiteDefaut, "boiteDefaut")
1343   logging.info("meshBoiteDefaut fini")
1344   
1345   faceFissure = meshBoiteDefaut.GetMesh().UnionListOfGroups( [ group_faceFissOutPipe, group_faceFissInPipe ], 'FACE1' )
1346   maillageSain = enleveDefaut(maillageSain, zoneDefaut, zoneDefaut_skin,
1347                               zoneDefaut_internalFaces, zoneDefaut_internalEdges)
1348   putName(maillageSain, nomFicSain+"_coupe")
1349   extrusionFaceFissure, normfiss = shapeSurFissure(facesPortFissure)
1350   maillageComplet = RegroupeSainEtDefaut(maillageSain, meshBoiteDefaut,
1351                                          None, None, 'COMPLET', normfiss)
1352
1353   logging.info("conversion quadratique")
1354   maillageComplet.ConvertToQuadratic( 1 )
1355   logging.info("groupes")
1356   groups = maillageComplet.GetGroups()
1357   grps = [ grp for grp in groups if grp.GetName() == 'FONDFISS']
1358   fond = maillageComplet.GetMesh().CreateDimGroup( grps, SMESH.NODE, 'FONDFISS' )
1359
1360   logging.info("réorientation face de fissure FACE1")
1361   grps = [ grp for grp in groups if grp.GetName() == 'FACE1']
1362   nb = maillageComplet.Reorient2D( grps[0], normfiss, grps[0].GetID(1))
1363
1364   logging.info("réorientation face de fissure FACE2")
1365   plansim = geompy.MakePlane(O, normfiss, 10000)
1366   fissnorm = geompy.MakeMirrorByPlane(normfiss, plansim)
1367   grps = [ grp for grp in groups if grp.GetName() == 'FACE2']
1368   nb = maillageComplet.Reorient2D( grps[0], fissnorm, grps[0].GetID(1))
1369   fond = maillageComplet.GetMesh().CreateDimGroup( grps, SMESH.NODE, 'FACE2' )
1370
1371   logging.info("export maillage fini")
1372   maillageComplet.ExportMED( fichierMaillageFissure, 0, SMESH.MED_V2_2, 1 )
1373   putName(maillageComplet, nomFicFissure)
1374   logging.info("fichier maillage fissure %s", fichierMaillageFissure)
1375
1376   if salome.sg.hasDesktop():
1377     salome.sg.updateObjBrowser(1)
1378
1379   logging.info("maillage fissure fini")
1380   
1381   return maillageComplet