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