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