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