1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
22 #define No_Standard_RangeError
23 #define No_Standard_OutOfRange
26 void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult,
27 const TColStd_SequenceOfReal& Vmult,
28 const ThePOPIterator& Pnts1,
29 const ThePOLIterator& Pnts2,
31 Standard_Boolean& Rajout )
32 // *********** Processing of closed line **********************
34 // for any interior non-processed point
35 // calculate the step of advancement=step depending on the arrow and max step
36 // calculate a point of approach (this point is on the tangent to the section
37 // of distance = no interior point)
39 // (all calculated points do not form a closed loop)
41 // (all points do not form an open line going from
42 // one border of the domain to the other or from a point tangent
43 // to the border or from 2 tangent points : single cases)
45 // frame the point of approach on borders if necessary
46 // calculate the point
47 // if point not found divide the step
49 // calculate step depending on the arrow and the max step (stop possible)
51 // ********************************************************************
55 static math_Vector BornInf(1,2),BornSup(1,2);
56 static math_Vector Uvap(1,2);// parameters of current approach
57 Standard_Real PasC; // rate of advancement on the tangent
58 Standard_Real PasCu; // rate of advancement current by U
59 Standard_Real PasCv; // step of advancement current by V
60 Standard_Real PasSav; // save first step of advancement
61 Standard_Boolean Arrive;// show if line ends
62 Standard_Boolean Cadre; // show if on border of the domains
63 Standard_Boolean ArretAjout; // show if on the added point
65 Handle(IntWalk_TheIWLine) CurrentLine; //line under construction
66 ThePointOfPath PathPnt;
67 ThePointOfLoop LoopPnt;
69 Standard_Boolean Tgtbeg,Tgtend;
71 Standard_Integer StepSign;
73 IntWalk_StatusDeflection Status,StatusPrecedent;
74 Standard_Integer NbDivision ; // number of divisions of step
75 // during calculation of 1 section
77 Standard_Integer Ipass ;
78 //index in the iterator of points on edge of point of passage
86 math_FunctionSetRoot Rsnld(Func,tolerance);
87 Standard_Integer nbLoop = Pnts2.Length();
89 for (I = 1;I<=nbLoop;I++) {
90 if (etat2(I) > 12) { // start point of closed line
92 LoopPnt = Pnts2.Value(I);
93 previousPoint.SetValue(ThePointOfLoopTool::Value3d(LoopPnt),reversed,
94 ustart2(I),vstart2(I));
95 previousd3d = ThePointOfLoopTool::Direction3d(LoopPnt);
96 previousd2d = ThePointOfLoopTool::Direction2d(LoopPnt);
98 CurrentLine = new IntWalk_TheIWLine ();
99 CurrentLine->AddPoint(previousPoint);
100 CurrentLine->SetTangentVector(previousd3d,1);
101 Tgtbeg = Standard_False;
102 Tgtend = Standard_False;
103 Uvap(1) = ustart2(I);
104 Uvap(2) = vstart2(I);
108 // first step of advancement
110 Standard_Real d2dx = Abs(previousd2d.X());
111 Standard_Real d2dy = Abs(previousd2d.Y());
112 if (d2dx < tolerance(1)) {
113 PasC = pas * (VM-Vm)/d2dy;
115 else if (d2dy < tolerance(2)) {
116 PasC = pas * (UM-Um)/d2dx;
119 PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy);
124 Arrive = Standard_False;
125 ArretAjout = Standard_False;
127 StatusPrecedent = IntWalk_OK;
128 while (!Arrive) { // as no test of stop is passed
129 Cadre=Cadrage(BornInf,BornSup,Uvap,PasC, StepSign); // border?
134 Rsnld.Perform(Func,Uvap,BornInf,BornSup);
140 if (Cadre) { // update of limits.
141 BornInf(1) = Um;BornSup(1) = UM;BornInf(2) = Vm;BornSup(2) = VM;
143 if (Rsnld.IsDone()) {
144 if (Abs(Func.Root()) > Func.Tolerance()) { // no solution for the tolerance
146 PasCu = Abs(PasC*previousd2d.X());
147 PasCv = Abs(PasC*previousd2d.Y());
149 if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
150 if (CurrentLine->NbPoints()==1) break;
151 Arrive = Standard_True;
152 CurrentLine->AddStatusFirstLast(Standard_False,
153 Standard_False,Standard_False);
154 Rajout = Standard_True;
155 seqAjout.Append(lines.Length()+1);
156 Tgtend = Standard_True;
159 else { // there is a solution
161 Arrive = TestArretPassage(Umult,Vmult,Uvap,I,Ipass);
162 if (Arrive) {//reset proper parameter to test the arrow.
163 Psol = CurrentLine->Value(1);
165 Psol.ParametersOnS2(Uvap(1),Uvap(2));
168 Psol.ParametersOnS1(Uvap(1),Uvap(2));
170 Cadre=Standard_False;
171 //in case if there is a frame and arrival at the same time
173 else { // modif jag 940615
175 if (Rajout) { // test on added points
176 ArretAjout =TestArretAjout(Func,Uvap,N,Psol);
179 Tgtend = lines.Value(N)->IsTangentAtEnd();
183 Tgtend = lines.Value(-N)->IsTangentAtBegining();
185 Arrive = (etat2(I) == 12);
189 if (!ArretAjout&& Cadre) { // test on already marked points
190 if (CurrentLine->NbPoints() == 1) break; // cancel the line
191 TestArretCadre(Umult,Vmult,CurrentLine,Func,Uvap,N);
193 if (N <= 0) { // jag 941017
194 MakeWalkingPoint(2,Uvap(1),Uvap(2),Func,Psol);
195 Tgtend = Func.IsTangent(); // jag 940616
198 Arrive = (etat2(I) == 12); // the line is open
201 Status = TestDeflection(Func, Arrive,Uvap,StatusPrecedent,
202 NbDivision,PasC,StepSign);
203 StatusPrecedent = Status;
204 if (Status == IntWalk_PasTropGrand) {// division of the step
205 Arrive = Standard_False;
206 ArretAjout = Standard_False;
207 Tgtend = Standard_False; // jag 940616
209 previousPoint.ParametersOnS2(Uvap(1),Uvap(2));
212 previousPoint.ParametersOnS1(Uvap(1),Uvap(2));
215 else if (ArretAjout || Cadre) {
217 if (Arrive) { // line s is open
218 CurrentLine->AddStatusLast(Standard_False);
219 if (Status != IntWalk_ArretSurPointPrecedent) {
220 CurrentLine->AddPoint(Psol);
223 Rajout = Standard_True;
224 seqAjout.Append(lines.Length()+1);
229 etat2(I) = 12; // declare it open
231 Tgtend = Standard_False;
232 ArretAjout = Standard_False;
234 StatusPrecedent = IntWalk_OK;
236 if (Status == IntWalk_ArretSurPointPrecedent) {
237 OpenLine(0,Psol,Pnts1,Func,CurrentLine);
240 OpenLine(-lines.Length()-1,Psol,Pnts1,Func,CurrentLine);
243 Rajout = Standard_True;
244 seqAjout.Append(-lines.Length()-1);
249 else if ( Status == IntWalk_ArretSurPointPrecedent) {
250 if (CurrentLine->NbPoints() == 1) { //cancel the line
251 Arrive = Standard_False;
254 if (etat2(I) >12) { //the line should become open
255 etat2(I) = 12; //declare it open
256 ArretAjout = Standard_False;
257 OpenLine(0,Psol,Pnts1,Func,CurrentLine);
259 StatusPrecedent = IntWalk_OK;
260 Arrive = Standard_False;
262 Rajout = Standard_True;
263 seqAjout.Append(-lines.Length()-1);
265 else { // line s is open
266 Arrive =Standard_True;
267 CurrentLine->AddStatusLast(Standard_False);
268 Rajout = Standard_True;
269 seqAjout.Append(lines.Length()+1);
273 if (etat2(I) > 12) { //line closed good case
274 CurrentLine->AddStatusFirstLast(Standard_True,
275 Standard_False,Standard_False);
276 CurrentLine->AddPoint(CurrentLine->Value(1));
278 else if (N >0) { //point of stop given at input
279 PathPnt = Pnts1.Value(N);
280 CurrentLine->AddStatusLast(Standard_True,N,PathPnt);
281 AddPointInCurrentLine(N,PathPnt,CurrentLine);
284 else if (Status == IntWalk_ArretSurPoint) {
285 if (etat2(I) >12) { //line should become open
286 etat2(I) = 12; //declare it open
287 Tgtbeg = Standard_True;
288 Tgtend = Standard_False;
289 N= -lines.Length()-1;
290 Psol.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
291 OpenLine(N,Psol,Pnts1,Func,CurrentLine);
293 Rajout = Standard_True;
295 StatusPrecedent = IntWalk_OK;
296 Arrive = Standard_False;
300 Arrive = Standard_True;
301 if (Ipass!=0) { //point of passage, point of stop
302 PathPnt = Pnts1.Value(Ipass);
303 CurrentLine->AddStatusLast(Standard_True,Ipass,PathPnt);
304 AddPointInCurrentLine(Ipass,PathPnt,CurrentLine);
307 CurrentLine->AddStatusLast(Standard_False);
308 IntSurf_PntOn2S newP;
309 newP.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
310 CurrentLine->AddPoint(newP);
311 Rajout = Standard_True;
312 seqAjout.Append(lines.Length()+1);
316 else if (Status == IntWalk_OK) {
317 if (Ipass!=0) CurrentLine->AddIndexPassing(Ipass);
318 previousPoint.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
319 previousd3d = Func.Direction3d();
320 previousd2d = Func.Direction2d();
321 CurrentLine->AddPoint(previousPoint);
325 else { //no numerical solution NotDone
327 PasCu = Abs(PasC*previousd2d.X());
328 PasCv = Abs(PasC*previousd2d.Y());
330 if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
331 if (CurrentLine->NbPoints() == 1) break; // cancel the line
332 Arrive = Standard_True;
333 CurrentLine->AddStatusFirstLast(Standard_False,Standard_False,
335 Tgtend = Standard_True;
336 Rajout = Standard_True;
337 seqAjout.Append(lines.Length()+1);
340 }// end of started line
342 CurrentLine->SetTangencyAtBegining(Tgtbeg);
343 CurrentLine->SetTangencyAtEnd(Tgtend);
345 lines.Append(CurrentLine);
346 etat2(I)=-etat2(I); //mark point as processed
348 } //end of processing of start point
349 } //end of all start points