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