0026206: BRepClass_FaceClassifier returns TopAbs_OUT for internal point
[occt.git] / src / BRepClass / BRepClass_FaceExplorer.cxx
CommitLineData
b311480e 1// Created on: 1992-11-19
2// Created by: Remi LEQUETTE
3// Copyright (c) 1992-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17// Modified by skv - Thu Jul 13 17:42:58 2006 OCC12627
18// Total rewriting of the method Segment; add the method OtherSegment.
19
20#include <BRepClass_FaceExplorer.ixx>
21#include <Precision.hxx>
22#include <Geom2d_Curve.hxx>
23#include <TopoDS.hxx>
24#include <BRep_Tool.hxx>
25
645ff3b1 26static const Standard_Real Probing_Start = 0.123;
27static const Standard_Real Probing_End = 0.7;
28static const Standard_Real Probing_Step = 0.2111;
29
7fd59977 30//=======================================================================
31//function : BRepClass_FaceExplorer
32//purpose :
33//=======================================================================
34
35BRepClass_FaceExplorer::BRepClass_FaceExplorer(const TopoDS_Face& F) :
36 myFace(F),
37 myCurEdgeInd(1),
645ff3b1 38 myCurEdgePar(Probing_Start)
7fd59977 39{
40 myFace.Orientation(TopAbs_FORWARD);
41}
42
43//=======================================================================
44//function : Reject
45//purpose :
46//=======================================================================
47
48Standard_Boolean BRepClass_FaceExplorer::Reject(const gp_Pnt2d&)const
49{
50 return Standard_False;
51}
52
53//=======================================================================
54//function : Segment
55//purpose :
56//=======================================================================
57
58Standard_Boolean BRepClass_FaceExplorer::Segment(const gp_Pnt2d& P,
59 gp_Lin2d& L,
60 Standard_Real& Par)
61{
62 myCurEdgeInd = 1;
645ff3b1 63 myCurEdgePar = Probing_Start;
7fd59977 64
65 return OtherSegment(P, L, Par);
66}
67
68//=======================================================================
69//function : OtherSegment
70//purpose :
71//=======================================================================
72
73Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
74 gp_Lin2d& L,
75 Standard_Real& Par)
76{
77 TopExp_Explorer anExpF(myFace,TopAbs_EDGE);
78 Standard_Integer i;
79 Standard_Real aFPar;
80 Standard_Real aLPar;
81 Handle(Geom2d_Curve) aC2d;
645ff3b1 82 Standard_Real aTolParConf2 = Precision::PConfusion() * Precision::PConfusion();
7fd59977 83 gp_Pnt2d aPOnC;
84 Standard_Real aParamIn;
85
86 for (i = 1; anExpF.More(); anExpF.Next(), i++) {
87 if (i != myCurEdgeInd)
88 continue;
89
90 const TopoDS_Shape &aLocalShape = anExpF.Current();
91 const TopAbs_Orientation anOrientation = aLocalShape.Orientation();
92
93 if (anOrientation == TopAbs_FORWARD || anOrientation == TopAbs_REVERSED) {
94 const TopoDS_Edge &anEdge = TopoDS::Edge(aLocalShape);
95
96 aC2d = BRep_Tool::CurveOnSurface(anEdge, myFace, aFPar, aLPar);
97
98 if (!aC2d.IsNull()) {
99 // Treatment of infinite cases.
100 if (Precision::IsNegativeInfinite(aFPar)) {
101 if (Precision::IsPositiveInfinite(aLPar)) {
102 aFPar = -1.;
103 aLPar = 1.;
104 } else {
105 aFPar = aLPar - 1.;
106 }
107 } else if (Precision::IsPositiveInfinite(aLPar))
108 aLPar = aFPar + 1.;
109
645ff3b1 110 for (; myCurEdgePar < Probing_End ;myCurEdgePar += Probing_Step) {
7fd59977 111 aParamIn = myCurEdgePar*aFPar + (1. - myCurEdgePar)*aLPar;
112
645ff3b1 113 gp_Vec2d aTanVec;
114 aC2d->D1(aParamIn, aPOnC, aTanVec);
115 Par = aPOnC.SquareDistance(P);
7fd59977 116
645ff3b1 117 if (Par > aTolParConf2) {
7fd59977 118 gp_Vec2d aLinVec(P, aPOnC);
119 gp_Dir2d aLinDir(aLinVec);
120
645ff3b1 121 Standard_Real aTanMod = aTanVec.SquareMagnitude();
122 if (aTanMod < aTolParConf2)
123 continue;
124 aTanVec /= Sqrt(aTanMod);
125 Standard_Real aSinA = aTanVec.Crossed(aLinDir.XY());
126 const Standard_Real SmallAngle = 0.001;
127 if (Abs(aSinA) < SmallAngle)
128 {
129 // The line from the input point P to the current point on edge
130 // is tangent to the edge curve. This condition is bad for classification.
131 // Therefore try to go to another point in the hope that there will be
132 // no tangent. If there tangent is preserved then leave the last point in
133 // order to get this edge chanse to participate in classification.
134 if (myCurEdgePar + Probing_Step < Probing_End)
135 continue;
136 }
137
7fd59977 138 L = gp_Lin2d(P, aLinDir);
139
140 // Check if ends of a curve lie on a line.
141 aC2d->D0(aFPar, aPOnC);
142
645ff3b1 143 if (L.SquareDistance(aPOnC) > aTolParConf2) {
7fd59977 144 aC2d->D0(aLPar, aPOnC);
145
645ff3b1 146 if (L.SquareDistance(aPOnC) > aTolParConf2) {
147 myCurEdgePar += Probing_Step;
7fd59977 148
645ff3b1 149 if (myCurEdgePar >= Probing_End) {
7fd59977 150 myCurEdgeInd++;
645ff3b1 151 myCurEdgePar = Probing_Start;
7fd59977 152 }
153
645ff3b1 154 Par = Sqrt(Par);
7fd59977 155 return Standard_True;
156 }
157 }
158 }
159 }
160 } // if (!aC2d.IsNull()) {
161 } // if (anOrientation == TopAbs_FORWARD ...
162
163 // This curve is not valid for line construction. Go to another edge.
164 myCurEdgeInd++;
645ff3b1 165 myCurEdgePar = Probing_Start;
7fd59977 166 }
167
168 // nothing found, return an horizontal line
169 Par = RealLast();
170 L = gp_Lin2d(P,gp_Dir2d(1,0));
171
172 return Standard_False;
173}
174
175//=======================================================================
176//function : InitWires
177//purpose :
178//=======================================================================
179
180void BRepClass_FaceExplorer::InitWires()
181{
182 myWExplorer.Init(myFace,TopAbs_WIRE);
183}
184
185//=======================================================================
186//function : RejectWire NYI
187//purpose :
188//=======================================================================
189
190Standard_Boolean BRepClass_FaceExplorer::RejectWire
191 (const gp_Lin2d& ,
192 const Standard_Real)const
193{
194 return Standard_False;
195}
196
197//=======================================================================
198//function : InitEdges
199//purpose :
200//=======================================================================
201
202void BRepClass_FaceExplorer::InitEdges()
203{
204 myEExplorer.Init(myWExplorer.Current(),TopAbs_EDGE);
205}
206
207//=======================================================================
208//function : RejectEdge NYI
209//purpose :
210//=======================================================================
211
212Standard_Boolean BRepClass_FaceExplorer::RejectEdge
213 (const gp_Lin2d& ,
214 const Standard_Real )const
215{
216 return Standard_False;
217}
218
219
220//=======================================================================
221//function : CurrentEdge
222//purpose :
223//=======================================================================
224
225void BRepClass_FaceExplorer::CurrentEdge(BRepClass_Edge& E,
226 TopAbs_Orientation& Or) const
227{
228 E.Edge() = TopoDS::Edge(myEExplorer.Current());
229 E.Face() = myFace;
230 Or = E.Edge().Orientation();
231}
232