1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2014-2021 EDF R&D
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.
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.
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
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 """Préparation maillage du pipe"""
25 from .geomsmesh import geompy
26 from .geomsmesh import smesh
28 def calculePointsAxiauxPipe(edgesFondFiss, edgesIdByOrientation, facesDefaut,
29 centreFondFiss, wireFondFiss, wirePipeFiss,
30 lenSegPipe, rayonPipe, nbsegCercle, nbsegRad):
31 """Préparation maillage du pipe :
33 - détections des points a respecter : jonction des edges/faces constituant
34 la face de fissure externe au pipe
35 - points sur les edges de fond de fissure et edges pipe/face fissure,
36 - vecteurs tangents au fond de fissure (normal au disque maillé)
41 # --- option de maillage selon le rayon de courbure du fond de fissure
43 for edff in edgesFondFiss:
44 lenEdgeFondExt += geompy.BasicProperties(edff)[0]
47 for filling in facesDefaut:
48 disfond.append(geompy.MinDistance(centreFondFiss, filling))
51 texte = "rcourb: {}, lenEdgeFondExt: {}, lenSegPipe: {}".format(rcourb, lenEdgeFondExt, lenSegPipe)
53 nbSegQuart = 5 # on veut 5 segments min sur un quart de cercle
54 alpha = math.pi/(4*nbSegQuart)
55 deflexion = rcourb*(1.0 -math.cos(alpha))
56 lgmin = lenSegPipe*0.25
57 lgmax = lenSegPipe*1.5
58 texte = "==> deflexion: {}, lgmin: {}, lgmax: {}".format(deflexion, lgmin, lgmax)
61 meshFondExt = smesh.Mesh(wireFondFiss)
62 algo1d = meshFondExt.Segment()
63 _ = algo1d.Adaptive(lgmin, lgmax, deflexion) # a ajuster selon la profondeur de la fissure
65 is_done = meshFondExt.Compute()
66 text = "calculePointsAxiauxPipe meshFondExt.Compute"
70 text = "Erreur au calcul du maillage.\n" + text
74 ptGSdic = dict() # dictionnaire [paramètre sur la courbe] --> point géométrique
75 allNodeIds = meshFondExt.GetNodesId()
76 for nodeId in allNodeIds:
77 xyz = meshFondExt.GetNodeXYZ(nodeId)
78 #logging.debug("nodeId %s, coords %s", nodeId, str(xyz))
79 point = geompy.MakeVertex(xyz[0], xyz[1], xyz[2])
80 parametre, _, EdgeInWireIndex = geompy.MakeProjectionOnWire(point, wireFondFiss) # parametre compris entre 0 et 1
81 edgeOrder = edgesIdByOrientation[EdgeInWireIndex]
82 ptGSdic[(edgeOrder, EdgeInWireIndex, parametre)] = point
83 #logging.debug("nodeId %s, parametre %s", nodeId, str(parametre))
84 usort = sorted(ptGSdic)
85 logging.debug("nombre de points obtenus par deflexion %s",len(usort))
94 norm = geompy.MakeTangentOnCurve(edgesFondFiss[ied], parametre)
95 plan = geompy.MakePlane(vertcx, norm, 3.*rayonPipe)
96 part = geompy.MakePartition([plan], [wirePipeFiss], list(), list(), geompy.ShapeType["VERTEX"], 0, list(), 0)
97 liste = geompy.ExtractShapes(part, geompy.ShapeType["VERTEX"], True)
98 if len(liste) == 5: # 4 coins du plan plus intersection recherchée
100 if geompy.MinDistance(point, vertcx) < 1.1*rayonPipe: # les quatre coins sont plus loin
103 centres.append(vertcx)
104 origins.append(vertpx)
106 # name = "vertcx%d"%i
107 # geompy.addToStudyInFather(wireFondFiss, vertcx, name)
108 # name = "vertpx%d"%i
109 # geompy.addToStudyInFather(wireFondFiss, vertpx, name)
111 # geompy.addToStudyInFather(wireFondFiss, plan, name)
113 # --- maillage du pipe étendu, sans tenir compte de l'intersection avec la face de peau
115 logging.debug("nbsegCercle %s", nbsegCercle)
117 # -----------------------------------------------------------------------
118 # --- points géométriques
120 gptsdisks = list() # vertices géométrie de tous les disques
121 raydisks = [list() for _ in range(nbsegCercle)]
122 for indice, centres_i in enumerate(centres): # boucle sur les disques
123 gptdsk = list() # vertices géométrie d'un disque
125 vertpx = origins[indice]
126 normal = normals[indice]
127 vec1 = geompy.MakeVector(vertcx, vertpx)
129 points = [vertcx] # les points du rayon de référence
130 dist_0 = rayonPipe/float(nbsegRad)
131 for j in range(nbsegRad):
132 point = geompy.MakeTranslationVectorDistance(vertcx, vec1, (j+1)*dist_0)
134 gptdsk.append(points)
135 point = geompy.MakeTranslationVectorDistance(vertcx, vec1, 1.5*rayonPipe)
136 rayon = geompy.MakeLineTwoPnt(vertcx, point)
137 raydisks[0].append(rayon)
139 angle_0 = 2.*math.pi/float(nbsegCercle)
140 for k in range(nbsegCercle-1):
141 angle = float(k+1)*angle_0
142 pts = [vertcx] # les points d'un rayon obtenu par rotation
143 for j in range(nbsegRad):
144 point = geompy.MakeRotation(points[j+1], normal, angle)
147 ray = geompy.MakeRotation(rayon, normal, angle)
148 raydisks[k+1].append(ray)
150 gptsdisks.append(gptdsk)
152 return (centres, gptsdisks, raydisks)