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