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