Commit | Line | Data |
---|---|---|
b311480e | 1 | // Copyright (c) 1995-1999 Matra Datavision |
973c2be1 | 2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e | 3 | // |
973c2be1 | 4 | // This file is part of Open CASCADE Technology software library. |
b311480e | 5 | // |
d5f74e42 | 6 | // This library is free software; you can redistribute it and/or modify it under |
7 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 8 | // by the Free Software Foundation, with special exception defined in the file |
9 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
10 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 11 | // |
973c2be1 | 12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. | |
7fd59977 | 14 | |
0797d9d3 | 15 | #ifndef OCCT_DEBUG |
7fd59977 | 16 | #define No_Standard_RangeError |
17 | #define No_Standard_OutOfRange | |
18 | #endif | |
19 | ||
20 | ||
21 | void IntWalk_IWalking::AddPointInCurrentLine | |
22 | (const Standard_Integer N, | |
23 | const ThePointOfPath& PathPnt, | |
24 | const Handle(IntWalk_TheIWLine)& CurrentLine) const { | |
25 | ||
26 | ||
27 | IntSurf_PntOn2S Psol; | |
28 | Psol.SetValue(ThePointOfPathTool::Value3d(PathPnt), | |
96a85238 | 29 | reversed,wd1[N].ustart,wd1[N].vstart); |
7fd59977 | 30 | CurrentLine->AddPoint(Psol); |
31 | } | |
32 | ||
33 | ||
34 | void IntWalk_IWalking::MakeWalkingPoint | |
35 | (const Standard_Integer Case, | |
36 | const Standard_Real U, | |
37 | const Standard_Real V, | |
38 | TheIWFunction& sp, | |
39 | IntSurf_PntOn2S& Psol ) | |
40 | ||
41 | { | |
42 | ||
43 | // Case == 1 : make a WalkinkPoint. | |
44 | // Case == 2 : make a WalkinkPoint. | |
45 | // The computation of the tangency on is done | |
46 | // Case == 10 + i : make a WalkinkPoint according to i. | |
47 | // but F is updated according to U and V | |
48 | // Case == other : the exception Standard_Failure is raised. | |
49 | ||
92a55b01 | 50 | if ((Case == 1) || (Case == 2)) |
51 | { | |
52 | Psol.SetValue(sp.Point(), reversed, U, V); | |
7fd59977 | 53 | } |
92a55b01 | 54 | else if (Case == 11 || Case == 12) |
55 | { | |
1ef32e96 | 56 | Standard_Real aUV[2], aFF[1], aDD[1][2]; |
92a55b01 | 57 | math_Vector UV(aUV, 1, 2); |
58 | math_Vector FF(aFF, 1, 1); | |
59 | math_Matrix DD(aDD, 1, 1, 1, 2); | |
7fd59977 | 60 | UV(1) = U; |
61 | UV(2) = V; | |
62 | sp.Values(UV, FF, DD); | |
92a55b01 | 63 | MakeWalkingPoint(Case - 10, U, V, sp, Psol); |
7fd59977 | 64 | } |
92a55b01 | 65 | else |
66 | { | |
9775fa61 | 67 | throw Standard_ConstructionError(); |
7fd59977 | 68 | } |
7fd59977 | 69 | } |
70 | ||
71 | ||
72 | ||
73 | void IntWalk_IWalking::OpenLine(const Standard_Integer N, | |
74 | const IntSurf_PntOn2S& Psol, | |
75 | const ThePOPIterator& Pnts1, | |
76 | TheIWFunction& sp, | |
77 | const Handle(IntWalk_TheIWLine)& Line ) | |
b1c5c4e6 | 78 | // **************** open the line and restart in the other direction******** |
7fd59977 | 79 | |
80 | { | |
81 | ThePointOfPath PathPnt; | |
82 | ||
1ef32e96 RL |
83 | Standard_Real aUV[2], aFF[1], aDD[1][2]; |
84 | math_Vector UV(aUV,1, 2); | |
85 | math_Vector FF(aFF,1, 1); | |
86 | math_Matrix DD(aDD,1, 1, 1, 2); | |
7fd59977 | 87 | |
88 | previousPoint = Line->Value(1); | |
89 | if (!reversed) { | |
90 | previousPoint.ParametersOnS2(UV(1),UV(2)); | |
91 | } | |
92 | else { | |
93 | previousPoint.ParametersOnS1(UV(1),UV(2)); | |
94 | } | |
95 | sp.Values(UV, FF, DD); | |
96 | previousd3d = sp.Direction3d(); | |
97 | previousd2d = sp.Direction2d(); | |
98 | ||
b1c5c4e6 | 99 | if (N>0) { //departure point given at input |
7fd59977 | 100 | PathPnt = Pnts1.Value(N); |
b1c5c4e6 | 101 | //mark the line as open with a given stop point |
7fd59977 | 102 | Line->AddStatusFirst(Standard_False,Standard_True,N,PathPnt); |
103 | ||
104 | ||
105 | AddPointInCurrentLine(N,PathPnt,Line); | |
106 | ||
107 | } | |
108 | else { | |
109 | if (N <0) Line->AddPoint(Psol); | |
110 | Line->AddStatusFirst(Standard_False,Standard_False); | |
b1c5c4e6 | 111 | //mark the line as open without given stop point |
7fd59977 | 112 | } |
113 | Line->Reverse(); //inverser la ligne | |
114 | Line->SetTangentVector(previousd3d.Reversed(),Line->NbPoints()); | |
115 | } | |
116 | ||
8d795b51 | 117 | Standard_Boolean IntWalk_IWalking::IsValidEndPoint(const Standard_Integer IndOfPoint, |
118 | const Standard_Integer IndOfLine) | |
119 | { | |
120 | if (PointLineLine.IsEmpty()) | |
121 | return Standard_True; | |
122 | ||
123 | TColStd_ListIteratorOfListOfInteger itl(PointLineLine(IndOfPoint)); | |
124 | for (; itl.More(); itl.Next()) | |
125 | if (itl.Value() == IndOfLine) | |
126 | { | |
127 | PointLineLine(IndOfPoint).Remove(itl); | |
128 | return Standard_True; | |
129 | } | |
130 | return Standard_False; | |
131 | } | |
7fd59977 | 132 | |
8d795b51 | 133 | void IntWalk_IWalking::RemoveTwoEndPoints(const Standard_Integer IndOfPoint) |
134 | { | |
135 | if (PointLineLine.IsBound(IndOfPoint)) | |
136 | { | |
137 | Standard_Integer Line1 = PointLineLine(IndOfPoint).First(); | |
138 | Standard_Integer Line2 = PointLineLine(IndOfPoint).Last(); | |
139 | for (Standard_Integer iseq = 1; iseq <= seqAlone.Length(); iseq++) | |
140 | { | |
141 | if (seqAlone(iseq) == Line1 || | |
142 | seqAlone(iseq) == Line2) | |
143 | seqAlone.Remove(iseq--); | |
144 | } | |
145 | } | |
146 | } | |
7fd59977 | 147 | |
8d795b51 | 148 | Standard_Boolean IntWalk_IWalking::IsPointOnLine(const gp_Pnt2d& theP2d, |
149 | const Standard_Integer Irang) | |
150 | { | |
151 | const Handle(IntWalk_TheIWLine)& aLine = lines.Value(Abs(Irang)); | |
152 | for (Standard_Integer i = 1; i <= aLine->NbPoints(); i++) | |
153 | { | |
154 | gp_Pnt2d P2d1 = aLine->Value(i).ValueOnSurface(reversed); | |
155 | if (Abs(P2d1.X() - theP2d.X()) <= tolerance(1) && | |
156 | Abs(P2d1.Y() - theP2d.Y()) <= tolerance(2)) | |
157 | return Standard_True; | |
158 | if (i < aLine->NbPoints()) | |
159 | { | |
160 | gp_Pnt2d P2d2 = aLine->Value(i+1).ValueOnSurface(reversed); | |
161 | gp_Vec2d PP1(theP2d, P2d1); | |
162 | gp_Vec2d PP2(theP2d, P2d2); | |
163 | if (PP1 * PP2 < 0) | |
164 | return Standard_True; | |
165 | } | |
166 | } | |
167 | return Standard_False; | |
168 | } | |
92a55b01 | 169 | |
170 | //================================================================================== | |
171 | //function : IsPointOnLine | |
172 | //purpose : Projects thePOn2S on the nearest segment of the already computed line. | |
173 | // The retrieved projection point (aPa) is refined using theSolver. | |
174 | // After the refinement, we will obtain a point aPb. | |
175 | // If thePOn2S is quite far from aPb then thePOn2S is not | |
176 | // in the line. | |
177 | // Every already computed line is checked. | |
178 | //================================================================================== | |
179 | Standard_Boolean IntWalk_IWalking::IsPointOnLine(const IntSurf_PntOn2S& thePOn2S, | |
180 | const math_Vector& theInfBounds, | |
181 | const math_Vector& theSupBounds, | |
182 | math_FunctionSetRoot& theSolver, | |
183 | TheIWFunction& theFunc) | |
184 | { | |
185 | const gp_Pnt &aP3d = thePOn2S.Value(); | |
186 | ||
187 | for (Standard_Integer aLIdx = 1; aLIdx <= lines.Length(); aLIdx++) | |
188 | { | |
189 | const Handle(IntSurf_LineOn2S) &aL = lines(aLIdx)->Line(); | |
190 | ||
191 | if (aL->IsOutBox(aP3d)) | |
192 | continue; | |
193 | ||
194 | //Look for the nearest segment | |
195 | Standard_Real aUMin = 0.0, aVMin = 0.0; | |
196 | Standard_Real aMinSqDist = RealLast(); | |
197 | for (Standard_Integer aPtIdx = 1; aPtIdx < aL->NbPoints(); aPtIdx++) | |
198 | { | |
199 | const gp_Pnt &aP1 = aL->Value(aPtIdx).Value(); | |
200 | const gp_Pnt &aP2 = aL->Value(aPtIdx + 1).Value(); | |
201 | ||
202 | const gp_XYZ aP1P(aP3d.XYZ() - aP1.XYZ()); | |
203 | const gp_XYZ aP1P2(aP2.XYZ() - aP1.XYZ()); | |
204 | ||
205 | const Standard_Real aSq12 = aP1P2.SquareModulus(); | |
206 | ||
207 | if (aSq12 < gp::Resolution()) | |
208 | continue; | |
209 | ||
210 | const Standard_Real aDP = aP1P.Dot(aP1P2); | |
211 | ||
212 | Standard_Real aSqD = RealLast(); | |
213 | if (aDP < 0.0) | |
214 | { | |
215 | //aSqD = aP1P.SquareModulus(); | |
216 | continue; | |
217 | } | |
218 | else if (aDP > aSq12) | |
219 | { | |
220 | //aSqD = (aP3d.XYZ() - aP2.XYZ()).SquareModulus(); | |
221 | continue; | |
222 | } | |
223 | else | |
224 | { | |
225 | aSqD = aP1P.CrossSquareMagnitude(aP1P2) / aSq12; | |
226 | } | |
227 | ||
228 | if (aSqD < aMinSqDist) | |
229 | { | |
230 | aMinSqDist = aSqD; | |
231 | ||
232 | const Standard_Real aL1 = aDP / aSq12; | |
233 | const Standard_Real aL2 = 1.0 - aL1; | |
234 | ||
235 | Standard_Real aU1, aV1, aU2, aV2; | |
236 | aL->Value(aPtIdx).ParametersOnSurface(reversed, aU1, aV1); | |
237 | aL->Value(aPtIdx + 1).ParametersOnSurface(reversed, aU2, aV2); | |
238 | ||
239 | aUMin = aL1*aU2 + aL2*aU1; | |
240 | aVMin = aL1*aV2 + aL2*aV1; | |
241 | } | |
242 | } | |
243 | ||
244 | if (aMinSqDist == RealLast()) | |
245 | continue; | |
246 | ||
247 | math_Vector aVecPrms(1, 2); | |
248 | aVecPrms(1) = aUMin; | |
249 | aVecPrms(2) = aVMin; | |
250 | theSolver.Perform(theFunc, aVecPrms, theInfBounds, theSupBounds); | |
251 | if (!theSolver.IsDone()) | |
252 | continue; | |
253 | ||
254 | theSolver.Root(aVecPrms); | |
255 | ||
256 | const gp_Pnt aPa(theFunc.PSurface()->Value(aUMin, aVMin)), | |
257 | aPb(theFunc.PSurface()->Value(aVecPrms(1), aVecPrms(2))); | |
258 | const Standard_Real aSqD1 = aPb.SquareDistance(aP3d); | |
259 | const Standard_Real aSqD2 = aPa.SquareDistance(aPb); | |
260 | ||
261 | if (aSqD1 < 4.0*aSqD2) | |
262 | { | |
263 | return Standard_True; | |
264 | } | |
265 | } | |
266 | ||
267 | return Standard_False; | |
268 | } |