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