Salome HOME
Merge branch 'master' into gni/evolution
[modules/smesh.git] / src / Tools / blocFissure / gmu / identifieElementsDebouchants.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 import logging
22 import math
23
24 from .geomsmesh import geompy
25 from .geomsmesh import geomPublish
26 from .geomsmesh import geomPublishInFather
27 from . import initLog
28 import traceback
29 from .fissError import fissError
30
31 from .produitMixte import produitMixte
32 from .whichSide import whichSide
33
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)"""
40
41   logging.info('start')
42
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)
49
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]
59     centre = PointOnEdge
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)
87     else:
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)
92
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
96     else:
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)
108
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()
115     try:
116       ofp = geompy.BasicProperties(edgesLocSorted[0][2])[0] # distance curviligne centre locPt0
117     except:
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)
127
128     edgePart = geompy.MakePartition([localEdgeInFondFiss], [p1,p2], list(), list(), geompy.ShapeType["EDGE"], 0, list(), 0)
129     edps = geompy.ExtractShapes(edgePart, geompy.ShapeType["EDGE"], True)
130     for edp in edps:
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)
136
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()
142       try:
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)
149       except:
150         logging.debug("  pb edges communes %s %s %s",edgesPeauFis, edgesPipeFis, edgesPipeFnd)
151         pass
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)
160           dist = 1.
161           for ipe, edpe in enumerate(edgesPeauFis):
162             for ipi, edpi in enumerate(edgesPipeFis):
163               dist = geompy.MinDistance(edpe, edpi)
164               if dist < 1.e-3:
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)
171                 break
172             if dist < 1.e-3:
173               break
174
175   return (verticesEdgesFondIn, pipexts, cercles, facesFissExt, edgesFissExtPeau, edgesFissExtPipe)