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