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
24 from .geomsmesh import geompy
25 from .geomsmesh import geomPublish
26 from .geomsmesh import geomPublishInFather
29 from .fissError import fissError
31 from .produitMixte import produitMixte
32 from .whichSide import whichSide
34 def identifieElementsDebouchants(ifil, facesDefaut, partitionPeauFissFond,
35 edgesFondIn, edgesFondFiss, wireFondFiss,
36 aretesVivesC, fillingFaceExterne,
37 edgesPipeIn, verticesPipePeau, rayonPipe,
38 facesInside, facesOnside):
40 elements débouchants (intersection pipe et peau), indexés selon les edges du fond de fissure (edgesFondIn)
45 verticesEdgesFondIn = [] # les points du fond de fissure au débouché du pipe sur la peau (indice de edgesFondIn)
46 pipexts = [] # les segments de pipe associés au points de fond de fissure débouchants (même indice)
47 cercles = [] # les cercles de generation des pipes débouchant (même indice)
48 facesFissExt = [] # les faces de la fissure externe associés au points de fond de fissure débouchants (même indice)
49 edgesFissExtPeau = [] # edges des faces de fissure externe sur la peau (même indice)
50 edgesFissExtPipe = [] # edges des faces de fissure externe sur le pipe (même indice)
52 #logging.debug("edgesFondIn %s", edgesFondIn)
53 for iedf, edge in enumerate(edgesFondIn):
54 name = "edgeFondIn%d"%iedf
55 geomPublishInFather(initLog.debug, partitionPeauFissFond, edge, name)
56 dist = [ geompy.MinDistance(pt, edge) for pt in verticesPipePeau]
57 ptPeau = verticesPipePeau[dist.index(min(dist))] # le point de verticesPipePeau a distance minimale de l'edge
58 [u, PointOnEdge, EdgeInWireIndex] = geompy.MakeProjectionOnWire(ptPeau, wireFondFiss)
59 logging.debug("u:%s, EdgeInWireIndex: %s, len(edgesFondFiss): %s", u, EdgeInWireIndex, len(edgesFondFiss))
60 localEdgeInFondFiss = edgesFondFiss[EdgeInWireIndex]
62 centre2 = geompy.MakeVertexOnCurve(localEdgeInFondFiss, u)
63 geomPublishInFather(initLog.debug, partitionPeauFissFond, centre2, "centre2_%d"%iedf)
64 verticesEdgesFondIn.append(centre)
65 name = "verticeEdgesFondIn%d"%iedf
66 geomPublishInFather(initLog.debug, partitionPeauFissFond, centre, name)
67 norm = geompy.MakeTangentOnCurve(localEdgeInFondFiss, u)
68 geomPublishInFather(initLog.debug, partitionPeauFissFond, centre, "norm%d"%iedf)
69 cercle = geompy.MakeCircle(centre, norm, rayonPipe)
70 geomPublishInFather(initLog.debug, partitionPeauFissFond, cercle, "cerclorig%d"%iedf)
71 [vertex] = geompy.ExtractShapes(cercle, geompy.ShapeType["VERTEX"], False)
72 vec1 = geompy.MakeVector(centre, vertex)
73 vec2 = geompy.MakeVector(centre, ptPeau)
74 angle = geompy.GetAngleRadians(vec1, vec2)
75 # cas général : on reconstitue une portion de pipe, avec l'arête de couture qui coincide
76 # avec la face de fissure, au niveau du débouché sur la face externe
77 # cas dégénéré : le pipe débouche perpendiculairement à une surface plane à l'origine.
78 # La partition filling / pipe reconstruit échoue.
79 # - Si on partitionne le filling avec un simple pipe obtenu par extrusion droite du cercle,
80 # cela donne un point en trop sur le cercle.
81 # - Si on prend une vraie surface plane (pas un filling), on peut faire la partition avec
82 # les pipes reconstruits
83 logging.debug("angle=%s", angle)
84 #if abs(angle) > 1.e-7:
85 sommetAxe = geompy.MakeTranslationVector(centre, norm)
86 pm = produitMixte(centre, vertex, ptPeau, sommetAxe)
87 if pm > 0: # ajout de pi a (-)angle pour éviter des points confondus (partition échoue) dans les cas dégénérés
88 cercle = geompy.MakeRotation(cercle, norm, angle + math.pi)
90 cercle = geompy.MakeRotation(cercle, norm, -angle + math.pi)
91 name = "cercle%d"%iedf
92 geomPublishInFather(initLog.debug,partitionPeauFissFond, cercle, name)
93 cercles.append(cercle)
95 # --- estimation de la longueur du pipe necessaire de part et d'autre du point de sortie
96 if aretesVivesC is None:
97 faceTestPeau = fillingFaceExterne
99 faceTestPeau = facesDefaut[ifil]
100 sideCentre = whichSide(faceTestPeau, centre)
101 locPt0 = geompy.MakeVertexOnCurve(localEdgeInFondFiss, 0.0)
102 locPt1 = geompy.MakeVertexOnCurve(localEdgeInFondFiss, 1.0)
103 sidePt0 = whichSide(faceTestPeau, locPt0)
104 sidePt1 = whichSide(faceTestPeau, locPt1)
105 logging.debug("position centre cercle: %s, extremité edge u0: %s, u1: %s", sideCentre, sidePt0, sidePt1)
106 normFace = geompy.GetNormal(faceTestPeau, ptPeau)
107 inclPipe = abs(geompy.GetAngleRadians(norm, normFace))
108 lgp = max(rayonPipe/2., abs(3*rayonPipe*math.tan(inclPipe)))
109 logging.debug("angle inclinaison Pipe en sortie: %s degres, lgp: %s", inclPipe*180/math.pi, lgp)
111 # --- position des points extremite du pipe sur l'edge debouchante
112 # il faut la distance curviligne ofp du point central par rapport à une extrémité de l'edge débouchante
113 locEdgePart = geompy.MakePartition([localEdgeInFondFiss],[centre], [], [], geompy.ShapeType["EDGE"], 0, [], 0)
114 edgesLoc = geompy.ExtractShapes(locEdgePart, geompy.ShapeType["EDGE"], False)
115 edgesLocSorted =[(geompy.MinDistance(edge, locPt0), kk, edge) for kk, edge in enumerate(edgesLoc)]
116 edgesLocSorted.sort()
118 ofp = geompy.BasicProperties(edgesLocSorted[0][2])[0] # distance curviligne centre locPt0
120 texte = "Identification des éléments au débouché du pipe sur la face externe impossible. "
121 texte += "Cause possible : la ligne de fond de fissure comprend un point géométrique coincidant avec la face externe. "
122 texte += "La ligne de fond de fissure doit déboucher franchement de la face externe, et ne doit pas être coupée au niveau de la face."
123 raise fissError(traceback.extract_stack(),texte)
124 logging.debug("distance curviligne centre extremite0: %s", ofp)
125 p1 = geompy.MakeVertexOnCurveByLength(localEdgeInFondFiss, ofp +lgp, locPt0)
126 p2 = geompy.MakeVertexOnCurveByLength(localEdgeInFondFiss, ofp -lgp, locPt0)
127 geomPublishInFather(initLog.debug, wireFondFiss, p1, "p1_%d"%iedf)
128 geomPublishInFather(initLog.debug, wireFondFiss, p2, "p2_%d"%iedf)
130 edgePart = geompy.MakePartition([localEdgeInFondFiss], [p1,p2], [], [], geompy.ShapeType["EDGE"], 0, [], 0)
131 edps = geompy.ExtractShapes(edgePart, geompy.ShapeType["EDGE"], True)
133 if geompy.MinDistance(centre, edp) < 1.e-3:
134 pipext = geompy.MakePipe(cercle, edp)
135 name = "pipeExt%d"%iedf
136 geomPublishInFather(initLog.debug, partitionPeauFissFond, pipext, name)
137 pipexts.append(pipext)
139 for ifa, face in enumerate(facesInside):
140 logging.debug("recherche edges communes entre une face inside et (faces onside, edges pipe et fond débouchante)")
145 edgesPeauFis = geompy.GetSharedShapesMulti([geompy.MakeCompound(facesOnside), face], geompy.ShapeType["EDGE"])
146 logging.debug(" faces onside %s",edgesPeauFis)
147 edgesPipeFis = geompy.GetSharedShapesMulti([geompy.MakeCompound(edgesPipeIn), face], geompy.ShapeType["EDGE"])
148 logging.debug(" edgesPipeIn %s", edgesPipeFis)
149 edgesPipeFnd = geompy.GetSharedShapesMulti([geompy.MakeCompound(edgesFondIn), face], geompy.ShapeType["EDGE"])
150 logging.debug(" edgesFondIn %s ", edgesPipeFnd)
152 logging.debug(" pb edges communes %s %s %s",edgesPeauFis, edgesPipeFis, edgesPipeFnd)
154 if (len(edgesPeauFis) > 0) and (len(edgesPipeFis) > 0) and (len(edgesPipeFnd) == 0):
155 dist = geompy.MinDistance(geompy.MakeCompound(edgesPeauFis), ptPeau)
156 logging.debug(" test distance extrémité reference %s", dist)
157 if dist < 1.e-3: # c'est la face de fissure externe associée
158 logging.debug(" face %s inside ajoutée", ifa)
159 facesFissExt.append(face)
160 name="faceFissExt%d"%iedf
161 geomPublishInFather(initLog.debug, partitionPeauFissFond, face, name)
163 for ipe, edpe in enumerate(edgesPeauFis):
164 for ipi, edpi in enumerate(edgesPipeFis):
165 dist = geompy.MinDistance(edpe, edpi)
167 edgesFissExtPeau.append(edpe)
168 name="edgesFissExtPeau%d"%iedf
169 geomPublishInFather(initLog.debug, partitionPeauFissFond, edpe, name)
170 edgesFissExtPipe.append(edpi)
171 name="edgesFissExtPipe%d"%iedf
172 geomPublishInFather(initLog.debug, partitionPeauFissFond, edpi, name)
177 return (verticesEdgesFondIn, pipexts, cercles, facesFissExt, edgesFissExtPeau, edgesFissExtPipe)