1 # -*- coding: utf-8 -*-
6 from .geomsmesh import geompy
7 from .geomsmesh import geomPublish
8 from .geomsmesh import geomPublishInFather
11 from .fissError import fissError
13 from .produitMixte import produitMixte
14 from .whichSide import whichSide
16 def identifieElementsDebouchants(ifil, facesDefaut, partitionPeauFissFond,
17 edgesFondIn, edgesFondFiss, wireFondFiss,
18 aretesVivesC, fillingFaceExterne,
19 edgesPipeIn, verticesPipePeau, rayonPipe,
20 facesInside, facesOnside):
22 elements débouchants (intersection pipe et peau), indexés selon les edges du fond de fissure (edgesFondIn)
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)
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]
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)
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)
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
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)
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)]
100 ofp = geompy.BasicProperties(edgesLocSorted[0][2])[0] # distance curviligne centre locPt0
102 texte = "Identification des éléments au débouché du pipe sur la face externe impossible. "
103 texte += "Cause possible : 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)
112 edgePart = geompy.MakePartition([localEdgeInFondFiss], [p1,p2], [], [], geompy.ShapeType["EDGE"], 0, [], 0)
113 edps = geompy.ExtractShapes(edgePart, geompy.ShapeType["EDGE"], True)
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)
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)")
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)
134 logging.debug(" pb edges communes %s %s %s",edgesPeauFis, edgesPipeFis, edgesPipeFnd)
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)
145 for ipe, edpe in enumerate(edgesPeauFis):
146 for ipi, edpi in enumerate(edgesPipeFis):
147 dist = geompy.MinDistance(edpe, edpi)
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)
159 return (verticesEdgesFondIn, pipexts, cercles, facesFissExt, edgesFissExtPeau, edgesFissExtPipe)