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