Salome HOME
Build under Windows.
[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   """
40   elements débouchants (intersection pipe et peau), indexés selon les edges du fond de fissure (edgesFondIn)
41   """
42   
43   logging.info('start')
44  
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)
51
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]
61     centre = PointOnEdge
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)
89     else:
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)
94
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
98     else:
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)
110     
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()
117     try:
118       ofp = geompy.BasicProperties(edgesLocSorted[0][2])[0] # distance curviligne centre locPt0
119     except:
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)
129
130     edgePart = geompy.MakePartition([localEdgeInFondFiss], [p1,p2], [], [], geompy.ShapeType["EDGE"], 0, [], 0)
131     edps = geompy.ExtractShapes(edgePart, geompy.ShapeType["EDGE"], True)
132     for edp in edps:
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)
138
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)")
141       edgesPeauFis = []
142       edgesPipeFis = []
143       edgesPipeFnd = []
144       try:
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)
151       except:
152         logging.debug("  pb edges communes %s %s %s",edgesPeauFis, edgesPipeFis, edgesPipeFnd)
153         pass
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)
162           dist = 1.
163           for ipe, edpe in enumerate(edgesPeauFis):
164             for ipi, edpi in enumerate(edgesPipeFis):
165               dist = geompy.MinDistance(edpe, edpi)
166               if dist < 1.e-3:
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)
173                 break
174             if dist < 1.e-3:
175               break
176
177   return (verticesEdgesFondIn, pipexts, cercles, facesFissExt, edgesFissExtPeau, edgesFissExtPipe)