1 # -*- coding: utf-8 -*-
5 from geomsmesh import geompy
7 from geomsmesh import smesh
8 from salome.smesh import smeshBuilder
13 from extractionOrientee import extractionOrientee
14 from extractionOrienteeMulti import extractionOrienteeMulti
15 from sortFaces import sortFaces
16 from sortEdges import sortEdges
17 from eliminateDoubles import eliminateDoubles
18 from substractSubShapes import substractSubShapes
19 from produitMixte import produitMixte
20 from findWireEndVertices import findWireEndVertices
21 from findWireIntermediateVertices import findWireIntermediateVertices
22 from orderEdgesFromWire import orderEdgesFromWire
23 from getSubshapeIds import getSubshapeIds
24 from putName import putName
25 from distance2 import distance2
26 from enleveDefaut import enleveDefaut
27 from shapeSurFissure import shapeSurFissure
28 from regroupeSainEtDefaut import RegroupeSainEtDefaut
29 from triedreBase import triedreBase
30 from checkDecoupePartition import checkDecoupePartition
31 from whichSide import whichSide
32 from whichSideMulti import whichSideMulti
33 from whichSideVertex import whichSideVertex
34 from projettePointSurCourbe import projettePointSurCourbe
35 from prolongeWire import prolongeWire
36 from restreintFaceFissure import restreintFaceFissure
37 from partitionneFissureParPipe import partitionneFissureParPipe
38 from construitPartitionsPeauFissure import construitPartitionsPeauFissure
39 from compoundFromList import compoundFromList
40 from identifieElementsGeometriquesPeau import identifieElementsGeometriquesPeau
42 # -----------------------------------------------------------------------------
43 # --- procédure complète fissure générale
45 def construitFissureGenerale(maillagesSains,
46 shapesFissure, shapeFissureParams,
47 maillageFissureParams, elementsDefaut, step=-1):
53 shapeDefaut = shapesFissure[0] # faces de fissure, débordant
54 fondFiss = shapesFissure[4] # groupe d'edges de fond de fissure
56 rayonPipe = shapeFissureParams['rayonPipe']
57 if shapeFissureParams.has_key('lenSegPipe'):
58 lenSegPipe = shapeFissureParams['lenSegPipe']
60 lenSegPipe = rayonPipe
62 nomRep = maillageFissureParams['nomRep']
63 nomFicSain = maillageFissureParams['nomFicSain']
64 nomFicFissure = maillageFissureParams['nomFicFissure']
66 nbsegRad = maillageFissureParams['nbsegRad'] # nombre de couches selon un rayon du pipe
67 nbsegCercle = maillageFissureParams['nbsegCercle'] # nombre de secteur dans un cercle du pipe
68 areteFaceFissure = maillageFissureParams['areteFaceFissure']
73 isPointInterne = False
74 if shapeFissureParams.has_key('pointIn_x'):
75 pointIn_x = shapeFissureParams['pointIn_x']
77 if shapeFissureParams.has_key('pointIn_y'):
78 pointIn_y = shapeFissureParams['pointIn_y']
80 if shapeFissureParams.has_key('pointIn_z'):
81 pointIn_z = shapeFissureParams['pointIn_z']
84 pointInterne = geompy.MakeVertex(pointIn_x, pointIn_y, pointIn_z)
88 #fichierMaillageSain = nomRep + '/' + nomFicSain + '.med'
89 fichierMaillageFissure = nomRep + '/' + nomFicFissure + '.med'
91 # fillings des faces en peau
92 facesDefaut = elementsDefaut[0]
93 #centresDefaut = elementsDefaut[1]
94 #normalsDefaut = elementsDefaut[2]
95 #extrusionsDefaut = elementsDefaut[3]
96 dmoyen = elementsDefaut[4]
97 bordsPartages = elementsDefaut[5]
98 fillconts = elementsDefaut[6]
99 idFilToCont = elementsDefaut[7]
100 maillageSain = elementsDefaut[8]
101 internalBoundary = elementsDefaut[9]
102 zoneDefaut = elementsDefaut[10]
103 zoneDefaut_skin = elementsDefaut[11]
104 zoneDefaut_internalFaces = elementsDefaut[12]
105 zoneDefaut_internalEdges = elementsDefaut[13]
106 edgeFondExt = elementsDefaut[14]
107 centreFondFiss = elementsDefaut[15]
108 tgtCentre = elementsDefaut[16]
110 O, OX, OY, OZ = triedreBase()
112 # --- restriction de la face de fissure au domaine solide :
113 # partition face fissure étendue par fillings, on garde la face interne
115 facesPortFissure = restreintFaceFissure(shapeDefaut, facesDefaut, pointInterne)
117 # --- pipe de fond de fissure, prolongé, partition face fissure par pipe
118 # identification des edges communes pipe et face fissure
120 (fissPipe, edgesPipeFiss, edgesFondFiss, wirePipeFiss, wireFondFiss) = partitionneFissureParPipe(shapesFissure, elementsDefaut, rayonPipe)
121 edgesFondFiss, edgesIdByOrientation = orderEdgesFromWire(wireFondFiss)
122 for i,edge in enumerate(edgesFondFiss):
123 geompy.addToStudyInFather(wireFondFiss, edge, "edgeFondFiss%d"%i)
125 # --- peau et face de fissure
127 # --- partition peau défaut - face de fissure prolongée - wire de fond de fissure prolongée
128 # il peut y avoir plusieurs faces externes, dont certaines sont découpées par la fissure
129 # liste de faces externes : facesDefaut
130 # liste de partitions face externe - fissure : partitionPeauFissFond (None quand pas d'intersection)
132 partitionsPeauFissFond = construitPartitionsPeauFissure(facesDefaut, fissPipe)
134 # --- arêtes vives détectées (dans quadranglesToShapeNoCorner
135 # et quadranglesToShapeWithCorner)
137 aretesVivesCoupees = [] #= global
139 aretesVivesC = compoundFromList(bordsPartages, "areteVive")
141 # -------------------------------------------------------
142 # --- inventaire des faces de peau coupées par la fissure
143 # pour chaque face de peau : 0, 1 ou 2 faces débouchante du fond de fissure
144 # 0, 1 ou plus edges de la face de fissure externe au pipe
146 nbFacesFilling = len(partitionsPeauFissFond)
148 ptEdgeFond = [ [] for i in range(nbFacesFilling)] # pour chaque face [points edge fond de fissure aux débouchés du pipe]
149 fsPipePeau = [ [] for i in range(nbFacesFilling)] # pour chaque face [faces du pipe débouchantes]
150 edRadFPiPo = [ [] for i in range(nbFacesFilling)] # pour chaque face [edge radiale des faces du pipe débouchantes ]
151 fsFissuExt = [ [] for i in range(nbFacesFilling)] # pour chaque face [faces de fissure externes au pipe]
152 edFisExtPe = [ [] for i in range(nbFacesFilling)] # pour chaque face [edge en peau des faces de fissure externes (pas subshape facePeau)]
153 edFisExtPi = [ [] for i in range(nbFacesFilling)] # pour chaque face [edge commun au pipe des faces de fissure externes]
154 facesPeaux = [None for i in range(nbFacesFilling)] # pour chaque face : la face de peau finale a mailler (percée des faces débouchantes)
155 edCircPeau = [ [] for i in range(nbFacesFilling)] # pour chaque face de peau : [subshape edge circulaire aux débouchés du pipe]
156 ptCircPeau = [ [] for i in range(nbFacesFilling)] # pour chaque face de peau : [subshape point sur edge circulaire aux débouchés du pipe]
157 gpedgeBord = [None for i in range(nbFacesFilling)] # pour chaque face de peau : groupe subshape des edges aux bords liés à la partie saine
158 gpedgeVifs = [None for i in range(nbFacesFilling)] # pour chaque face de peau : groupes subshape des edges aux arêtes vives entre fillings
159 edFissPeau = [ [] for i in range(nbFacesFilling)] # pour chaque face de peau : [subshape edge en peau des faces de fissure externes]
160 ptFisExtPi = [ [] for i in range(nbFacesFilling)] # pour chaque face de peau : [point commun edFissPeau edCircPeau]
162 for ifil, partitionPeauFissFond in enumerate(partitionsPeauFissFond):
163 if partitionPeauFissFond is not None:
164 dataPPFF,aretesVivesCoupees = identifieElementsGeometriquesPeau(ifil, partitionPeauFissFond, edgesPipeFiss,
165 edgesFondFiss, wireFondFiss, aretesVivesC,
166 facesDefaut, centreFondFiss, rayonPipe,
169 ptEdgeFond[ifil] = dataPPFF['endsEdgeFond']
170 fsPipePeau[ifil] = dataPPFF['facesPipePeau']
171 edRadFPiPo[ifil] = dataPPFF['edgeRadFacePipePeau']
172 fsFissuExt[ifil] = dataPPFF['facesFissExt']
173 edFisExtPe[ifil] = dataPPFF['edgesFissExtPeau']
174 edFisExtPi[ifil] = dataPPFF['edgesFissExtPipe']
175 facesPeaux[ifil] = dataPPFF['facePeau']
176 edCircPeau[ifil] = dataPPFF['edgesCircPeau']
177 ptCircPeau[ifil] = dataPPFF['verticesCircPeau']
178 gpedgeBord[ifil] = dataPPFF['groupEdgesBordPeau']
179 gpedgeVifs[ifil] = dataPPFF['bordsVifs']
180 edFissPeau[ifil] = dataPPFF['edgesFissurePeau']
181 ptFisExtPi[ifil] = dataPPFF['verticesPipePeau']
183 # -----------------------------------------------------------------------
184 # fin de la boucle sur les faces de filling
185 # -----------------------------------------------------------------------
187 for i, avc in enumerate(aretesVivesCoupees):
188 name = "areteViveCoupee%d"%i
189 geompy.addToStudy(avc, name)
191 # --- identification des faces et edges de fissure externe pour maillage
194 edgesFissExtPeau = []
195 edgesFissExtPipe = []
196 for ifil in range(nbFacesFilling): # TODO: éliminer les doublons (comparer tous les vertices triés, avec mesure de distance ?)
197 facesFissExt += fsFissuExt[ifil]
198 edgesFissExtPeau += edFisExtPe[ifil]
199 edgesFissExtPipe += edFisExtPi[ifil]
200 logging.debug("---------------------------- identification faces de fissure externes au pipe :%s ", len(facesFissExt))
201 # regroupement des faces de fissure externes au pipe.
203 if len(facesFissExt) > 1:
204 faceFissureExterne = geompy.MakePartition(facesFissExt, [], [], [], geompy.ShapeType["FACE"], 0, [], 0)
205 edgesPipeFissureExterneC = geompy.GetInPlace(faceFissureExterne, geompy.MakeCompound(edgesPipeFiss)) # edgesFissExtPipe peut ne pas couvrir toute la longueur
206 # edgesPeauFissureExterneC = geompy.GetInPlace(faceFissureExterne, geompy.MakeCompound(edgesFissExtPeau))
207 # il peut manquer des edges de faceFissureExterne en contact avec la peau dans edgesFissExtPeau
208 (isDone, closedFreeBoundaries, openFreeBoundaries) = geompy.GetFreeBoundary(faceFissureExterne)
210 for bound in closedFreeBoundaries:
211 edgesBordFFE += geompy.ExtractShapes(bound, geompy.ShapeType["EDGE"], False)
212 edgesBordFFEid = [ (ed,geompy.GetSubShapeID(faceFissureExterne, ed)) for ed in edgesBordFFE]
213 logging.debug("edgesBordFFEid %s", edgesBordFFEid)
214 edgesPPE = geompy.ExtractShapes(edgesPipeFissureExterneC, geompy.ShapeType["EDGE"], False)
215 edgesPPEid = [ geompy.GetSubShapeID(faceFissureExterne, ed) for ed in edgesPPE]
216 logging.debug("edgesPPEid %s", edgesPPEid)
217 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
218 logging.debug("edgesPFE %s", edgesPFE)
219 edgesPeauFissureExterneC = geompy.MakeCompound(edgesPFE)
221 faceFissureExterne = facesFissExt[0]
222 edgesPeauFissureExterneC = geompy.MakeCompound(edgesFissExtPeau)
223 edgesPipeFissureExterneC = geompy.MakeCompound(edgesFissExtPipe)
224 wirePipeFissureExterne = geompy.MakeWire(geompy.ExtractShapes(edgesPipeFissureExterneC, geompy.ShapeType["EDGE"], False))
225 geompy.addToStudy(faceFissureExterne, "faceFissureExterne")
226 geompy.addToStudyInFather(faceFissureExterne, edgesPeauFissureExterneC, "edgesPeauFissureExterne")
227 geompy.addToStudyInFather(faceFissureExterne, edgesPipeFissureExterneC, "edgesPipeFissureExterne")
229 logging.debug("---------------------------- Preparation Maillage du Pipe --------------")
230 # -----------------------------------------------------------------------
231 # --- preparation maillage du pipe :
232 # - détections des points a respecter : jonction des edges/faces constituant
233 # la face de fissure externe au pipe
234 # - points sur les edges de fond de fissure et edges pipe/face fissure,
235 # - vecteurs tangents au fond de fissure (normal au disque maillé)
237 # --- option de maillage selon le rayon de courbure du fond de fissure
239 for edff in edgesFondFiss:
240 lenEdgeFondExt += geompy.BasicProperties(edff)[0]
243 for filling in facesDefaut:
244 disfond.append(geompy.MinDistance(centreFondFiss, filling))
247 nbSegQuart = 5 # on veut 5 segments min sur un quart de cercle
248 alpha = math.pi/(4*nbSegQuart)
249 deflexion = rcourb*(1.0 -math.cos(alpha))
250 lgmin = lenSegPipe*0.25
251 lgmax = lenSegPipe*1.5
252 logging.debug("rcourb: %s, lenFond:%s, deflexion: %s, lgmin: %s, lgmax: %s", rcourb, lenEdgeFondExt, deflexion, lgmin, lgmax)
254 meshFondExt = smesh.Mesh(wireFondFiss)
255 algo1d = meshFondExt.Segment()
256 hypo1d = algo1d.Adaptive(lgmin, lgmax, deflexion) # a ajuster selon la profondeur de la fissure
257 isDone = meshFondExt.Compute()
259 ptGSdic = {} # dictionnaire [paramètre sur la courbe] --> point géométrique
260 allNodeIds = meshFondExt.GetNodesId()
261 for nodeId in allNodeIds:
262 xyz = meshFondExt.GetNodeXYZ(nodeId)
263 #logging.debug("nodeId %s, coords %s", nodeId, str(xyz))
264 pt = geompy.MakeVertex(xyz[0], xyz[1], xyz[2])
265 u, PointOnEdge, EdgeInWireIndex = geompy.MakeProjectionOnWire(pt, wireFondFiss) # u compris entre 0 et 1
266 edgeOrder = edgesIdByOrientation[EdgeInWireIndex]
267 ptGSdic[(edgeOrder, EdgeInWireIndex, u)] = pt
268 #logging.debug("nodeId %s, u %s", nodeId, str(u))
269 usort = sorted(ptGSdic)
270 logging.debug("nombre de points obtenus par deflexion %s",len(usort))
278 vertcx = ptGSdic[edu]
279 norm = geompy.MakeTangentOnCurve(edgesFondFiss[ied], u)
280 plan = geompy.MakePlane(vertcx, norm, 3*rayonPipe)
281 part = geompy.MakePartition([plan], [wirePipeFiss], [], [], geompy.ShapeType["VERTEX"], 0, [], 0)
282 liste = geompy.ExtractShapes(part, geompy.ShapeType["VERTEX"], True)
283 if len(liste) == 5: # 4 coins du plan plus intersection recherchée
285 if geompy.MinDistance(point, vertcx) < 1.1*rayonPipe: # les quatre coins sont plus loin
288 centres.append(vertcx)
289 origins.append(vertpx)
291 # name = "vertcx%d"%i
292 # geompy.addToStudyInFather(wireFondFiss, vertcx, name)
293 # name = "vertpx%d"%i
294 # geompy.addToStudyInFather(wireFondFiss, vertpx, name)
296 # geompy.addToStudyInFather(wireFondFiss, plan, name)
298 # --- maillage du pipe étendu, sans tenir compte de l'intersection avec la face de peau
300 logging.debug("nbsegCercle %s", nbsegCercle)
302 # -----------------------------------------------------------------------
303 # --- points géométriques
305 gptsdisks = [] # vertices géométrie de tous les disques
306 raydisks = [[] for i in range(nbsegCercle)]
307 for i in range(len(centres)): # boucle sur les disques
308 gptdsk = [] # vertices géométrie d'un disque
312 vec1 = geompy.MakeVector(vertcx, vertpx)
314 points = [vertcx] # les points du rayon de référence
315 for j in range(nbsegRad):
316 pt = geompy.MakeTranslationVectorDistance(vertcx, vec1, (j+1)*float(rayonPipe)/nbsegRad)
318 gptdsk.append(points)
319 pt = geompy.MakeTranslationVectorDistance(vertcx, vec1, 1.5*rayonPipe)
320 rayon = geompy.MakeLineTwoPnt(vertcx, pt)
321 raydisks[0].append(rayon)
323 for k in range(nbsegCercle-1):
324 angle = (k+1)*2*math.pi/nbsegCercle
325 pts = [vertcx] # les points d'un rayon obtenu par rotation
326 for j in range(nbsegRad):
327 pt = geompy.MakeRotation(points[j+1], normal, angle)
330 ray = geompy.MakeRotation(rayon, normal, angle)
331 raydisks[k+1].append(ray)
333 gptsdisks.append(gptdsk)
335 # -----------------------------------------------------------------------
336 # --- recherche des points en trop (externes au volume à remailler)
337 # - on associe chaque extrémité du pipe à une face filling
338 # - on part des disques aux extrémités du pipe
339 # - pour chaque disque, on prend les vertices de géométrie,
340 # on marque leur position relative à la face.
341 # - on s'arrete quand tous les noeuds sont dedans
343 logging.debug("---------------------------- recherche des points du pipe a éliminer --------------")
347 idFillingFromBout = [None, None] # contiendra l'index du filling pour les extrémités 0 et 1
348 for ifil in range(nbFacesFilling):
349 for ipt, pt in enumerate(ptEdgeFond[ifil]): # il y a un ou deux points débouchant sur cette face
350 if geompy.MinDistance(pt,pt0) < geompy.MinDistance(pt,pt1): # TODO: trouver plus fiable pour les cas tordus...
351 idFillingFromBout[0] = ifil
353 idFillingFromBout[1] = ifil
354 logging.debug("association bouts du pipe - faces de filling: %s", idFillingFromBout)
357 edgeRadFacePipePeau = []
358 for ifil in range(nbFacesFilling):
359 facesPipePeau += fsPipePeau[ifil]
360 edgeRadFacePipePeau += edRadFPiPo[ifil]
362 logging.debug("recherche des disques de noeuds complètement internes")
363 idisklim = [] # indices des premier et dernier disques internes
364 idiskout = [] # indices des premier et dernier disques externes
365 for bout in range(2):
371 idisk = len(gptsdisks)
373 numout = len(gptsdisks)
378 logging.debug("examen disque %s", idisk)
379 gptdsk = gptsdisks[idisk]
381 for k in range(nbsegCercle):
383 for j, pt in enumerate(points):
384 side = whichSideVertex(facesDefaut[idFillingFromBout[bout]], pt)
386 if outside: # premier point detecté dedans
388 numout = idisk -inc # le disque précédent était dehors
390 inside = False # ce point est dehors
391 if not inside and not outside:
393 idisklim.append(idisk) # premier et dernier disques internes
394 idiskout.append(numout) # premier et dernier disques externes
396 # --- listes de nappes radiales en filling à chaque extrémité débouchante
397 facesDebouchantes = [False, False]
398 idFacesDebouchantes = [-1, -1] # contiendra les indices des faces disque débouchantes (facesPipePeau)
400 for i, idisk in enumerate(idisklim):
402 logging.debug("extremité %s, indices disques interne %s, externe %s",i, idisk, numout)
404 if (idisk != 0) and (idisk != len(gptsdisks)-1): # si extrémité débouchante
405 for k in range(nbsegCercle):
407 iddeb = max(0, numout)
408 idfin = max(iddeb+3,idisk+1) # il faut 3 rayons pour faire un filling qui suive le fond de fissure
409 #logging.debug("extremité %s, indices retenus interne %s, externe %s",i, idfin, iddeb)
410 comp = geompy.MakeCompound(raydisks[k][iddeb:idfin])
411 name='compoundRay%d'%k
412 geompy.addToStudy(comp, name)
414 idfin = min(len(gptsdisks), numout+1)
415 iddeb = min(idfin-3, idisk) # il faut 3 rayons pour faire un filling qui suive le fond de fissure
416 #logging.debug("extremité %s, indices retenus interne %s, externe %s",i, idfin, iddeb)
417 comp = geompy.MakeCompound(raydisks[k][iddeb:idfin])
418 name='compoundRay%d'%k
419 geompy.addToStudy(comp, name)
420 nappe = geompy.MakeFilling(comp, 2, 5, 0.0001, 0.0001, 0, GEOM.FOM_Default)
423 geompy.addToStudy(nappe, name)
424 facesDebouchantes[i] = True
425 listNappes.append(nappes)
427 # --- mise en correspondance avec les indices des faces disque débouchantes (facesPipePeau)
428 for i, nappes in enumerate(listNappes):
429 if facesDebouchantes[i]:
430 for k, face in enumerate(facesPipePeau):
431 edge = geompy.MakeSection(face, nappes[0])
432 if geompy.NbShapes(edge, geompy.ShapeType["EDGE"]) > 0:
433 idFacesDebouchantes[i] = k
435 logging.debug("idFacesDebouchantes: %s", idFacesDebouchantes)
437 # --- construction des listes d'edges radiales sur chaque extrémité débouchante
439 for i, nappes in enumerate(listNappes):
440 id = idFacesDebouchantes[i] # indice de face débouchante (facesPipePeau)
444 face = facesPipePeau[id]
445 edges = [edgeRadFacePipePeau[id]]
446 for k, nappe in enumerate(nappes):
448 obj = geompy.MakeSection(face, nappes[k]) # normalement une edge, parfois un compound d'edges dont un tout petit
450 vs = geompy.ExtractShapes(obj, geompy.ShapeType["VERTEX"], False)
452 eds = geompy.ExtractShapes(obj, geompy.ShapeType["EDGE"], False)
453 [edsorted, minl,maxl] = sortEdges(eds)
456 maxl = geompy.BasicProperties(edge)[0]
457 if maxl < 0.01: # problème MakeSection
458 logging.debug("problème MakeSection recherche edge radiale %s, longueur trop faible: %s, utilisation partition", k, maxl)
459 partNappeFace = geompy.MakePartition([face, nappes[k]], [] , [], [], geompy.ShapeType["FACE"], 0, [], 0)
460 edps= geompy.ExtractShapes(partNappeFace, geompy.ShapeType["EDGE"], False)
462 for ii, ed in enumerate(edps):
463 vxs = geompy.ExtractShapes(ed, geompy.ShapeType["VERTEX"], False)
464 distx = [geompy.MinDistance(vx, face) for vx in vxs]
465 distx += [geompy.MinDistance(vx, nappes[k]) for vx in vxs]
467 logging.debug(" dmax %s",dmax)
470 logging.debug(" edges issues de la partition: %s", ednouv)
471 for ii, ed in enumerate(ednouv):
472 geompy.addToStudy(ed, "ednouv%d"%ii)
473 [edsorted, minl,maxl] = sortEdges(ednouv)
474 logging.debug(" longueur edge trouvée: %s", maxl)
477 name = 'edgeEndPipe%d'%k
478 geompy.addToStudy(edge, name)
479 listEdges.append(edges)
481 # --- création des points du maillage du pipe sur la face de peau
482 for i, edges in enumerate(listEdges):
483 id = idFacesDebouchantes[i] # indice de face débouchante (facesPipePeau)
486 if id > 0: # id vaut 0 ou 1
487 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)
488 centre = ptEdgeFond[idFillingFromBout[i]][id]
490 geompy.addToStudy(centre, name)
491 vertPipePeau = ptFisExtPi[idFillingFromBout[i]][id]
492 geompy.addToStudyInFather(centre, vertPipePeau, "vertPipePeau")
493 grpsEdgesCirc = edCircPeau[idFillingFromBout[i]] # liste de groupes
495 for grpEdgesCirc in grpsEdgesCirc:
496 edgesCirc += geompy.ExtractShapes(grpEdgesCirc, geompy.ShapeType["EDGE"], False)
497 for k, edge in enumerate(edges):
498 extrems = geompy.ExtractShapes(edge, geompy.ShapeType["VERTEX"], True)
499 if geompy.MinDistance(centre, extrems[0]) < geompy.MinDistance(centre, extrems[1]):
503 # ajustement du point extrémité (bout) sur l'edge circulaire en face de peau
504 logging.debug("edgesCirc: %s", edgesCirc)
505 distEdgeCirc = [(geompy.MinDistance(bout, edgeCirc), k2, edgeCirc) for k2, edgeCirc in enumerate(edgesCirc)]
507 logging.debug("distEdgeCirc: %s", distEdgeCirc)
508 u = projettePointSurCourbe(bout, distEdgeCirc[0][2])
509 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.
510 extrCircs = geompy.ExtractShapes(distEdgeCirc[0][2], geompy.ShapeType["VERTEX"], True)
511 if geompy.MinDistance(bout, extrCircs[0]) < geompy.MinDistance(bout, extrCircs[1]):
517 bout = geompy.MakeVertexOnCurve(distEdgeCirc[0][2], u)
519 geompy.addToStudyInFather(centre, bout, name)
520 # enregistrement des points dans la structure
522 for j in range(nbsegRad +1):
523 u = j/float(nbsegRad)
524 points.append(geompy.MakeVertexOnCurve(edge, u))
525 if geompy.MinDistance(bout, points[0]) < geompy.MinDistance(centre, points[0]):
529 gptdsk.append(points)
531 gptsdisks[idisklim[0] -1] = gptdsk
532 idisklim[0] = idisklim[0] -1
534 gptsdisks[idisklim[1] +1] = gptdsk
535 idisklim[1] = idisklim[1] +1
537 # --- ajustement precis des points sur edgesPipeFissureExterneC
539 edgesPFE = geompy.ExtractShapes(edgesPipeFissureExterneC, geompy.ShapeType["EDGE"], False)
540 verticesPFE = findWireIntermediateVertices(wirePipeFissureExterne) # vertices intermédiaires (des points en trop dans ptsInWireFissExtPipe)
541 idiskmin = idisklim[0] + 1 # on ne prend pas le disque sur la peau, déjà ajusté
542 idiskmax = idisklim[1] # on ne prend pas le disque sur la peau, déjà ajusté
544 for vtx in verticesPFE:
546 for idisk in range(idiskmin, idiskmax):
547 gptdsk = gptsdisks[idisk]
548 pt = gptdsk[0][-1] # le point sur l'edge de la fissure externe au pipe
549 distPtVt.append((geompy.MinDistance(pt, vtx), idisk))
551 idiskint.append(distPtVt[0][1])
552 gptsdisks[idiskint[-1]][0][-1] = vtx
553 logging.debug("ajustement point sur edgePipeFissureExterne, vertex: %s %s", idiskint[-1], distPtVt[0][0])
554 for idisk in range(idiskmin, idiskmax):
555 if idisk in idiskint:
557 logging.debug("ajustement point sur edgePipeFissureExterne: %s", idisk)
558 gptdsk = gptsdisks[idisk]
559 pt = gptdsk[0][-1] # le point sur l'edge de la fissure externe au pipe
560 distPtEd = [(geompy.MinDistance(pt, edgePFE), k, edgePFE) for k, edgePFE in enumerate(edgesPFE)]
562 edgePFE = distPtEd[0][2]
563 u = projettePointSurCourbe(pt, edgePFE)
564 ptproj = geompy.MakeVertexOnCurve(edgePFE, u)
565 gptsdisks[idisk][0][-1] = ptproj
567 # -----------------------------------------------------------------------
568 # --- maillage effectif du pipe
570 logging.debug("---------------------------- maillage effectif du pipe --------------")
571 meshPipe = smesh.Mesh(None, "meshPipe")
572 fondFissGroup = meshPipe.CreateEmptyGroup(SMESH.EDGE, "FONDFISS")
573 nodesFondFissGroup = meshPipe.CreateEmptyGroup(SMESH.NODE, "nfondfis")
574 faceFissGroup = meshPipe.CreateEmptyGroup(SMESH.FACE, "fisInPi")
575 edgeFaceFissGroup = meshPipe.CreateEmptyGroup(SMESH.EDGE, "edgeFaceFiss")
576 edgeCircPipe0Group = meshPipe.CreateEmptyGroup(SMESH.EDGE, "edgeCircPipe0")
577 edgeCircPipe1Group = meshPipe.CreateEmptyGroup(SMESH.EDGE, "edgeCircPipe1")
578 faceCircPipe0Group = meshPipe.CreateEmptyGroup(SMESH.FACE, "faceCircPipe0")
579 faceCircPipe1Group = meshPipe.CreateEmptyGroup(SMESH.FACE, "faceCircPipe1")
580 mptsdisks = [] # vertices maillage de tous les disques
581 mEdges = [] # identifiants edges maillage fond de fissure
582 mEdgeFaces = [] # identifiants edges maillage edge face de fissure externe
583 mFaces = [] # identifiants faces maillage fissure
584 mVols = [] # identifiants volumes maillage pipe
587 for idisk in range(idisklim[0], idisklim[1]+1): # boucle sur les disques internes
589 # -----------------------------------------------------------------------
592 gptdsk = gptsdisks[idisk]
593 if idisk > idisklim[0]:
595 mptdsk = [] # vertices maillage d'un disque
596 for k in range(nbsegCercle):
599 for j, pt in enumerate(points):
603 coords = geompy.PointCoordinates(pt)
604 id = meshPipe.AddNode(coords[0], coords[1], coords[2])
606 mptdsk.append(mptids)
607 mptsdisks.append(mptdsk)
609 # -----------------------------------------------------------------------
610 # --- groupes edges cercles debouchants
612 if idisk == idisklim[0]:
614 for k in range(nbsegCercle):
615 pts.append(mptdsk[k][-1])
617 for k in range(len(pts)):
619 idEdge = meshPipe.AddEdge([pts[k], pts[k1]])
621 edgeCircPipe0Group.Add(edges)
623 if idisk == idisklim[1]:
625 for k in range(nbsegCercle):
626 pts.append(mptdsk[k][-1])
628 for k in range(len(pts)):
630 idEdge = meshPipe.AddEdge([pts[k], pts[k1]])
632 edgeCircPipe1Group.Add(edges)
634 # -----------------------------------------------------------------------
635 # --- groupes faces debouchantes
637 if idisk == idisklim[0]:
639 for j in range(nbsegRad):
640 for k in range(nbsegCercle):
642 if k == nbsegCercle-1:
645 idf = meshPipe.AddFace([mptdsk[k][0], mptdsk[k][1], mptdsk[k1][1]]) # triangle
647 idf = meshPipe.AddFace([mptdsk[k][j], mptdsk[k][j+1], mptdsk[k1][j+1], mptdsk[k1][j]]) # quadrangle
649 faceCircPipe0Group.Add(faces)
651 if idisk == idisklim[1]:
653 for j in range(nbsegRad):
654 for k in range(nbsegCercle):
656 if k == nbsegCercle-1:
659 idf = meshPipe.AddFace([mptdsk[k][0], mptdsk[k][1], mptdsk[k1][1]]) # triangle
661 idf = meshPipe.AddFace([mptdsk[k][j], mptdsk[k][j+1], mptdsk[k1][j+1], mptdsk[k1][j]]) # quadrangle
663 faceCircPipe1Group.Add(faces)
665 # -----------------------------------------------------------------------
666 # --- mailles volumiques, groupes noeuds et edges de fond de fissure, groupe de face de fissure
668 if idisk == idisklim[0]:
673 nodesFondFissGroup.Add([mptdsk[0][0]])
675 ide = meshPipe.AddEdge([oldmpts[0][0], mptdsk[0][0]])
677 fondFissGroup.Add([ide])
678 nodesFondFissGroup.Add([mptdsk[0][0]])
679 ide2 = meshPipe.AddEdge([oldmpts[0][-1], mptdsk[0][-1]])
680 mEdgeFaces.append(ide2)
681 edgeFaceFissGroup.Add([ide2])
685 for j in range(nbsegRad):
686 idf = meshPipe.AddFace([oldmpts[0][j], mptdsk[0][j], mptdsk[0][j+1], oldmpts[0][j+1]])
687 faceFissGroup.Add([idf])
691 for k in range(nbsegCercle):
693 if k == nbsegCercle-1:
696 idv = meshPipe.AddVolume([mptdsk[k][j], mptdsk[k][j+1], mptdsk[k1][j+1],
697 oldmpts[k][j], oldmpts[k][j+1], oldmpts[k1][j+1]])
699 idv = meshPipe.AddVolume([mptdsk[k][j], mptdsk[k][j+1], mptdsk[k1][j+1], mptdsk[k1][j],
700 oldmpts[k][j], oldmpts[k][j+1], oldmpts[k1][j+1], oldmpts[k1][j]])
701 idVolCercle.append(idv)
702 idVols.append(idVolCercle)
704 mFaces.append(idFaces)
707 pipeFissGroup = meshPipe.CreateEmptyGroup( SMESH.VOLUME, 'PIPEFISS' )
708 nbAdd = pipeFissGroup.AddFrom( meshPipe.GetMesh() )
710 nb, new_mesh, new_group = meshPipe.MakeBoundaryElements(SMESH.BND_2DFROM3D, "pipeBoundaries")
711 edgesCircPipeGroup = [edgeCircPipe0Group, edgeCircPipe1Group]
713 # --- fin du maillage du pipe
714 # -----------------------------------------------------------------------
715 # --- edges de bord, faces défaut à respecter
717 aFilterManager = smesh.CreateFilterManager()
718 nbAdded, internalBoundary, _NoneGroup = internalBoundary.MakeBoundaryElements( SMESH.BND_1DFROM2D, '', '', 0, [ ])
720 unCritere = smesh.GetCriterion(SMESH.EDGE,SMESH.FT_FreeBorders,SMESH.FT_Undefined,0)
721 criteres.append(unCritere)
722 filtre = smesh.GetFilterFromCriteria(criteres)
723 bordsLibres = internalBoundary.MakeGroupByFilter( 'bords', filtre )
724 smesh.SetName(bordsLibres, 'bordsLibres')
726 # --- pour aider l'algo hexa-tetra à ne pas mettre de pyramides à l'exterieur des volumes repliés sur eux-mêmes
727 # on désigne les faces de peau en quadrangles par le groupe "skinFaces"
729 skinFaces = internalBoundary.CreateEmptyGroup( SMESH.FACE, 'skinFaces' )
730 nbAdd = skinFaces.AddFrom( internalBoundary.GetMesh() )
732 # --- maillage des éventuelles arêtes vives entre faces reconstruites
734 if len(aretesVivesCoupees) > 0:
735 aretesVivesC = geompy.MakeCompound(aretesVivesCoupees)
736 meshAretesVives = smesh.Mesh(aretesVivesC)
737 algo1d = meshAretesVives.Segment()
738 hypo1d = algo1d.LocalLength(dmoyen,[],1e-07)
739 putName(algo1d.GetSubMesh(), "aretesVives")
740 putName(algo1d, "algo1d_aretesVives")
741 putName(hypo1d, "hypo1d_aretesVives")
742 isDone = meshAretesVives.Compute()
743 logging.info("aretesVives fini")
744 grpAretesVives = meshAretesVives.CreateEmptyGroup( SMESH.EDGE, 'grpAretesVives' )
745 nbAdd = grpAretesVives.AddFrom( meshAretesVives.GetMesh() )
747 # -----------------------------------------------------------------------
748 # --- maillage faces de fissure
750 logging.debug("---------------------------- maillage faces de fissure externes au pipe :%s --------------", len(facesFissExt))
752 meshFaceFiss = smesh.Mesh(faceFissureExterne)
753 algo2d = meshFaceFiss.Triangle(algo=smeshBuilder.NETGEN_1D2D)
754 hypo2d = algo2d.Parameters()
755 hypo2d.SetMaxSize( areteFaceFissure )
756 hypo2d.SetSecondOrder( 0 )
757 hypo2d.SetOptimize( 1 )
758 hypo2d.SetFineness( 2 )
759 hypo2d.SetMinSize( rayonPipe/float(nbsegRad) )
760 hypo2d.SetQuadAllowed( 0 )
761 putName(algo2d.GetSubMesh(), "faceFiss")
762 putName(algo2d, "algo2d_faceFiss")
763 putName(hypo2d, "hypo2d_faceFiss")
765 algo1d = meshFaceFiss.UseExisting1DElements(geom=edgesPipeFissureExterneC)
766 hypo1d = algo1d.SourceEdges([ edgeFaceFissGroup ],0,0)
767 putName(algo1d.GetSubMesh(), "edgeFissPeau")
768 putName(algo1d, "algo1d_edgeFissPeau")
769 putName(hypo1d, "hypo1d_edgeFissPeau")
771 isDone = meshFaceFiss.Compute()
772 logging.info("meshFaceFiss fini")
774 grpFaceFissureExterne = meshFaceFiss.GroupOnGeom(faceFissureExterne, "fisOutPi", SMESH.FACE)
775 grpEdgesPeauFissureExterne = meshFaceFiss.GroupOnGeom(edgesPeauFissureExterneC,'edgesPeauFissureExterne',SMESH.EDGE)
776 grpEdgesPipeFissureExterne = meshFaceFiss.GroupOnGeom(edgesPipeFissureExterneC,'edgesPipeFissureExterne',SMESH.EDGE)
778 # --- maillage faces de peau
780 boutFromIfil = [None for i in range(nbFacesFilling)]
781 if idFillingFromBout[0] != idFillingFromBout[1]: # repérage des extremites du pipe quand elles débouchent sur des faces différentes
782 boutFromIfil[idFillingFromBout[0]] = 0
783 boutFromIfil[idFillingFromBout[1]] = 1
785 logging.debug("---------------------------- maillage faces de peau --------------")
787 for ifil in range(nbFacesFilling):
789 if partitionsPeauFissFond[ifil] is None: # face de peau maillage sain intacte
791 # --- edges de bord de la face de filling
792 filling = facesDefaut[ifil]
793 edgesFilling = geompy.ExtractShapes(filling, geompy.ShapeType["EDGE"], False)
794 groupEdgesBordPeau = geompy.CreateGroup(filling, geompy.ShapeType["EDGE"])
795 geompy.UnionList(groupEdgesBordPeau, edgesFilling)
796 geompy.addToStudyInFather(filling, groupEdgesBordPeau , "EdgesBords")
798 meshFacePeau = smesh.Mesh(facesDefaut[ifil])
800 algo1d = meshFacePeau.UseExisting1DElements(geom=groupEdgesBordPeau)
801 hypo1d = algo1d.SourceEdges([ bordsLibres ],0,0)
802 putName(algo1d.GetSubMesh(), "bordsLibres", ifil)
803 putName(algo1d, "algo1d_bordsLibres", ifil)
804 putName(hypo1d, "hypo1d_bordsLibres", ifil)
808 facePeau = facesPeaux[ifil] # pour chaque face : la face de peau finale a mailler (percée des faces débouchantes)
809 edgesCircPeau = edCircPeau[ifil] # pour chaque face de peau : [subshape edge circulaire aux débouchés du pipe]
810 verticesCircPeau = ptCircPeau[ifil] # pour chaque face de peau : [subshape point sur edge circulaire aux débouchés du pipe]
811 groupEdgesBordPeau = gpedgeBord[ifil] # pour chaque face de peau : groupe subshape des edges aux bords liés à la partie saine
812 bordsVifs = gpedgeVifs[ifil] # pour chaque face de peau : groupe subshape des edges aux bords correspondant à des arêtes vives
813 edgesFissurePeau = edFissPeau[ifil] # pour chaque face de peau : [subshape edge en peau des faces de fissure externes]
815 meshFacePeau = smesh.Mesh(facePeau)
817 algo1d = meshFacePeau.UseExisting1DElements(geom=groupEdgesBordPeau)
818 hypo1d = algo1d.SourceEdges([ bordsLibres ],0,0)
819 putName(algo1d.GetSubMesh(), "bordsLibres", ifil)
820 putName(algo1d, "algo1d_bordsLibres", ifil)
821 putName(hypo1d, "hypo1d_bordsLibres", ifil)
823 algo1d = meshFacePeau.UseExisting1DElements(geom=geompy.MakeCompound(edgesFissurePeau))
824 hypo1d = algo1d.SourceEdges([ grpEdgesPeauFissureExterne ],0,0)
825 putName(algo1d.GetSubMesh(), "edgePeauFiss", ifil)
826 putName(algo1d, "algo1d_edgePeauFiss", ifil)
827 putName(hypo1d, "hypo1d_edgePeauFiss", ifil)
829 if bordsVifs is not None:
830 algo1d = meshFacePeau.UseExisting1DElements(geom=bordsVifs)
831 hypo1d = algo1d.SourceEdges([ grpAretesVives ],0,0)
832 putName(algo1d.GetSubMesh(), "bordsVifs", ifil)
833 putName(algo1d, "algo1d_bordsVifs", ifil)
834 putName(hypo1d, "hypo1d_bordsVifs", ifil)
836 for i, edgeCirc in enumerate(edgesCircPeau):
837 if edgeCirc is not None:
838 algo1d = meshFacePeau.UseExisting1DElements(geom=edgeCirc)
839 if boutFromIfil[ifil] is None:
840 hypo1d = algo1d.SourceEdges([ edgesCircPipeGroup[i] ],0,0)
842 hypo1d = algo1d.SourceEdges([ edgesCircPipeGroup[boutFromIfil[ifil]] ],0,0)
844 putName(algo1d.GetSubMesh(), name, ifil)
845 putName(algo1d, "algo1d_" + name, ifil)
846 putName(hypo1d, "hypo1d_" + name, ifil)
848 algo2d = meshFacePeau.Triangle(algo=smeshBuilder.NETGEN_1D2D)
849 hypo2d = algo2d.Parameters()
850 hypo2d.SetMaxSize( dmoyen )
851 hypo2d.SetOptimize( 1 )
852 hypo2d.SetFineness( 2 )
853 hypo2d.SetMinSize( rayonPipe/float(nbsegRad) )
854 hypo2d.SetQuadAllowed( 0 )
855 putName(algo2d.GetSubMesh(), "facePeau", ifil)
856 putName(algo2d, "algo2d_facePeau", ifil)
857 putName(hypo2d, "hypo2d_facePeau", ifil)
859 isDone = meshFacePeau.Compute()
860 logging.info("meshFacePeau %d fini", ifil)
861 GroupFaces = meshFacePeau.CreateEmptyGroup( SMESH.FACE, "facePeau%d"%ifil )
862 nbAdd = GroupFaces.AddFrom( meshFacePeau.GetMesh() )
863 meshesFacesPeau.append(meshFacePeau)
865 # --- regroupement des maillages du défaut
867 listMeshes = [internalBoundary.GetMesh(),
869 meshFaceFiss.GetMesh()]
870 for mp in meshesFacesPeau:
871 listMeshes.append(mp.GetMesh())
873 meshBoiteDefaut = smesh.Concatenate(listMeshes, 1, 1, 1e-05,False)
874 # pour aider l'algo hexa-tetra à ne pas mettre de pyramides à l'exterieur des volumes repliés sur eux-mêmes
875 # on désigne les faces de peau en quadrangles par le groupe "skinFaces"
876 group_faceFissOutPipe = None
877 group_faceFissInPipe = None
878 groups = meshBoiteDefaut.GetGroups()
880 if grp.GetType() == SMESH.FACE:
881 #if "internalBoundary" in grp.GetName():
882 # grp.SetName("skinFaces")
883 if grp.GetName() == "fisOutPi":
884 group_faceFissOutPipe = grp
885 elif grp.GetName() == "fisInPi":
886 group_faceFissInPipe = grp
888 # le maillage NETGEN ne passe pas toujours ==> utiliser GHS3D
891 algo3d = meshBoiteDefaut.Tetrahedron(algo=smeshBuilder.GHS3D)
893 algo3d = meshBoiteDefaut.Tetrahedron(algo=smeshBuilder.NETGEN)
894 hypo3d = algo3d.MaxElementVolume(1000.0)
895 putName(algo3d.GetSubMesh(), "boiteDefaut")
896 putName(algo3d, "algo3d_boiteDefaut")
897 isDone = meshBoiteDefaut.Compute()
898 putName(meshBoiteDefaut, "boiteDefaut")
899 logging.info("meshBoiteDefaut fini")
901 faceFissure = meshBoiteDefaut.GetMesh().UnionListOfGroups( [ group_faceFissOutPipe, group_faceFissInPipe ], 'FACE1' )
902 maillageSain = enleveDefaut(maillageSain, zoneDefaut, zoneDefaut_skin,
903 zoneDefaut_internalFaces, zoneDefaut_internalEdges)
904 putName(maillageSain, nomFicSain+"_coupe")
905 extrusionFaceFissure, normfiss = shapeSurFissure(facesPortFissure)
906 maillageComplet = RegroupeSainEtDefaut(maillageSain, meshBoiteDefaut,
907 None, None, 'COMPLET', normfiss)
909 logging.info("conversion quadratique")
910 maillageComplet.ConvertToQuadratic( 1 )
911 logging.info("groupes")
912 groups = maillageComplet.GetGroups()
913 grps = [ grp for grp in groups if grp.GetName() == 'FONDFISS']
914 fond = maillageComplet.GetMesh().CreateDimGroup( grps, SMESH.NODE, 'FONDFISS' )
916 logging.info("réorientation face de fissure FACE1")
917 grps = [ grp for grp in groups if grp.GetName() == 'FACE1']
918 nb = maillageComplet.Reorient2D( grps[0], normfiss, grps[0].GetID(1))
920 logging.info("réorientation face de fissure FACE2")
921 plansim = geompy.MakePlane(O, normfiss, 10000)
922 fissnorm = geompy.MakeMirrorByPlane(normfiss, plansim)
923 grps = [ grp for grp in groups if grp.GetName() == 'FACE2']
924 nb = maillageComplet.Reorient2D( grps[0], fissnorm, grps[0].GetID(1))
925 fond = maillageComplet.GetMesh().CreateDimGroup( grps, SMESH.NODE, 'FACE2' )
927 logging.info("export maillage fini")
928 maillageComplet.ExportMED( fichierMaillageFissure, 0, SMESH.MED_V2_2, 1 )
929 putName(maillageComplet, nomFicFissure)
930 logging.info("fichier maillage fissure %s", fichierMaillageFissure)
932 if salome.sg.hasDesktop():
933 salome.sg.updateObjBrowser(1)
935 logging.info("maillage fissure fini")
937 return maillageComplet