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