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.
20 #include <NCollection_IncAllocator.hxx>
22 void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult,
23 const TColStd_SequenceOfReal& Vmult,
24 const ThePOPIterator& Pnts1,
25 const ThePOLIterator& Pnts2,
27 Standard_Boolean& Rajout )
28 // *********** Processing of closed line **********************
30 // for any interior non-processed point
31 // calculate the step of advancement=step depending on the arrow and max step
32 // calculate a point of approach (this point is on the tangent to the section
33 // of distance = no interior point)
35 // (all calculated points do not form a closed loop)
37 // (all points do not form an open line going from
38 // one border of the domain to the other or from a point tangent
39 // to the border or from 2 tangent points : single cases)
41 // frame the point of approach on borders if necessary
42 // calculate the point
43 // if point not found divide the step
45 // calculate step depending on the arrow and the max step (stop possible)
47 // ********************************************************************
50 Standard_Integer I,N = 0;
51 Standard_Real aBornInf[2], aBornSup[2], aUVap[2];
52 math_Vector BornInf(aBornInf,1,2), BornSup(aBornSup,1,2);
53 math_Vector Uvap(aUVap,1,2);// parameters of current approach
54 Standard_Real PasC; // rate of advancement on the tangent
55 Standard_Real PasCu; // rate of advancement current by U
56 Standard_Real PasCv; // step of advancement current by V
57 Standard_Real PasSav; // save first step of advancement
58 Standard_Boolean Arrive;// show if line ends
59 Standard_Boolean Cadre; // show if on border of the domains
60 Standard_Boolean ArretAjout; // show if on the added point
62 Handle(IntWalk_TheIWLine) CurrentLine; //line under construction
63 ThePointOfPath PathPnt;
64 ThePointOfLoop LoopPnt;
66 Standard_Boolean Tgtbeg,Tgtend;
68 Standard_Integer StepSign;
70 IntWalk_StatusDeflection Status,StatusPrecedent;
71 Standard_Integer NbDivision ; // number of divisions of step
72 // during calculation of 1 section
74 Standard_Integer Ipass ;
75 //index in the iterator of points on edge of point of passage
83 math_FunctionSetRoot Rsnld(Func,tolerance);
84 Standard_Integer nbLoop = Pnts2.Length();
86 for (I = 1;I<=nbLoop;I++) {
87 if (wd2[I].etat > 12) { // start point of closed line
89 LoopPnt = Pnts2.Value(I);
90 previousPoint.SetValue(ThePointOfLoopTool::Value3d(LoopPnt),reversed,
91 wd2[I].ustart,wd2[I].vstart);
92 previousd3d = ThePointOfLoopTool::Direction3d(LoopPnt);
93 previousd2d = ThePointOfLoopTool::Direction2d(LoopPnt);
95 CurrentLine = new IntWalk_TheIWLine (new NCollection_IncAllocator());
96 CurrentLine->AddPoint(previousPoint);
97 CurrentLine->SetTangentVector(previousd3d,1);
98 Tgtbeg = Standard_False;
99 Tgtend = Standard_False;
100 Uvap(1) = wd2[I].ustart;
101 Uvap(2) = wd2[I].vstart;
105 // first step of advancement
107 Standard_Real d2dx = Abs(previousd2d.X());
108 Standard_Real d2dy = Abs(previousd2d.Y());
109 if (d2dx < tolerance(1)) {
110 PasC = pas * (VM-Vm)/d2dy;
112 else if (d2dy < tolerance(2)) {
113 PasC = pas * (UM-Um)/d2dx;
116 PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy);
121 Arrive = Standard_False;
122 ArretAjout = Standard_False;
124 StatusPrecedent = IntWalk_OK;
125 while (!Arrive) { // as no test of stop is passed
126 Cadre=Cadrage(BornInf,BornSup,Uvap,PasC, StepSign); // border?
131 Rsnld.Perform(Func,Uvap,BornInf,BornSup);
137 if (Cadre) { // update of limits.
138 BornInf(1) = Um;BornSup(1) = UM;BornInf(2) = Vm;BornSup(2) = VM;
140 if (Rsnld.IsDone()) {
141 if (Abs(Func.Root()) > Func.Tolerance()) { // no solution for the tolerance
143 PasCu = Abs(PasC*previousd2d.X());
144 PasCv = Abs(PasC*previousd2d.Y());
146 if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
147 if (CurrentLine->NbPoints()==1) break;
148 Arrive = Standard_True;
149 CurrentLine->AddStatusFirstLast(Standard_False,
150 Standard_False,Standard_False);
151 Rajout = Standard_True;
152 seqAjout.Append(lines.Length()+1);
153 Tgtend = Standard_True;
156 else { // there is a solution
158 Arrive = TestArretPassage(Umult,Vmult,Uvap,I,Ipass);
159 if (Arrive) {//reset proper parameter to test the arrow.
160 Psol = CurrentLine->Value(1);
162 Psol.ParametersOnS2(Uvap(1),Uvap(2));
165 Psol.ParametersOnS1(Uvap(1),Uvap(2));
167 Cadre=Standard_False;
168 //in case if there is a frame and arrival at the same time
170 else { // modif jag 940615
172 if (Rajout) { // test on added points
173 ArretAjout =TestArretAjout(Func,Uvap,N,Psol);
176 Tgtend = lines.Value(N)->IsTangentAtEnd();
180 Tgtend = lines.Value(-N)->IsTangentAtBegining();
182 Arrive = (wd2[I].etat == 12);
186 if (!ArretAjout&& Cadre) { // test on already marked points
187 if (CurrentLine->NbPoints() == 1) break; // cancel the line
188 TestArretCadre(Umult,Vmult,CurrentLine,Func,Uvap,N);
190 if (N <= 0) { // jag 941017
191 MakeWalkingPoint(2,Uvap(1),Uvap(2),Func,Psol);
192 Tgtend = Func.IsTangent(); // jag 940616
195 Arrive = (wd2[I].etat == 12); // the line is open
198 Status = TestDeflection(Func, Arrive,Uvap,StatusPrecedent,
199 NbDivision,PasC,StepSign);
200 StatusPrecedent = Status;
201 if (Status == IntWalk_PasTropGrand) {// division of the step
202 Arrive = Standard_False;
203 ArretAjout = Standard_False;
204 Tgtend = Standard_False; // jag 940616
206 previousPoint.ParametersOnS2(Uvap(1),Uvap(2));
209 previousPoint.ParametersOnS1(Uvap(1),Uvap(2));
212 else if (ArretAjout || Cadre) {
214 if (Arrive) { // line s is open
215 CurrentLine->AddStatusLast(Standard_False);
216 if (Status != IntWalk_ArretSurPointPrecedent) {
217 CurrentLine->AddPoint(Psol);
220 Rajout = Standard_True;
221 seqAjout.Append(lines.Length()+1);
226 wd2[I].etat = 12; // declare it open
228 Tgtend = Standard_False;
229 ArretAjout = Standard_False;
231 StatusPrecedent = IntWalk_OK;
233 if (Status == IntWalk_ArretSurPointPrecedent) {
234 OpenLine(0,Psol,Pnts1,Func,CurrentLine);
237 OpenLine(-lines.Length()-1,Psol,Pnts1,Func,CurrentLine);
240 Rajout = Standard_True;
241 seqAjout.Append(-lines.Length()-1);
246 else if ( Status == IntWalk_ArretSurPointPrecedent) {
247 if (CurrentLine->NbPoints() == 1) { //cancel the line
248 Arrive = Standard_False;
251 if (wd2[I].etat >12) { //the line should become open
252 wd2[I].etat = 12; //declare it open
253 ArretAjout = Standard_False;
254 OpenLine(0,Psol,Pnts1,Func,CurrentLine);
256 StatusPrecedent = IntWalk_OK;
257 Arrive = Standard_False;
259 Rajout = Standard_True;
260 seqAjout.Append(-lines.Length()-1);
262 else { // line s is open
263 Arrive =Standard_True;
264 CurrentLine->AddStatusLast(Standard_False);
265 Rajout = Standard_True;
266 seqAjout.Append(lines.Length()+1);
270 if (wd2[I].etat > 12) { //line closed good case
271 CurrentLine->AddStatusFirstLast(Standard_True,
272 Standard_False,Standard_False);
273 CurrentLine->AddPoint(CurrentLine->Value(1));
275 else if (N >0) { //point of stop given at input
276 PathPnt = Pnts1.Value(N);
277 CurrentLine->AddStatusLast(Standard_True,N,PathPnt);
278 AddPointInCurrentLine(N,PathPnt,CurrentLine);
281 else if (Status == IntWalk_ArretSurPoint) {
282 if (wd2[I].etat >12) { //line should become open
283 wd2[I].etat = 12; //declare it open
284 Tgtbeg = Standard_True;
285 Tgtend = Standard_False;
286 N= -lines.Length()-1;
287 Psol.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
288 OpenLine(N,Psol,Pnts1,Func,CurrentLine);
290 Rajout = Standard_True;
292 StatusPrecedent = IntWalk_OK;
293 Arrive = Standard_False;
297 Arrive = Standard_True;
298 if (Ipass!=0) { //point of passage, point of stop
299 PathPnt = Pnts1.Value(Ipass);
300 CurrentLine->AddStatusLast(Standard_True,Ipass,PathPnt);
301 AddPointInCurrentLine(Ipass,PathPnt,CurrentLine);
304 CurrentLine->AddStatusLast(Standard_False);
305 IntSurf_PntOn2S newP;
306 newP.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
307 CurrentLine->AddPoint(newP);
308 Rajout = Standard_True;
309 seqAjout.Append(lines.Length()+1);
313 else if (Status == IntWalk_OK) {
314 if (Ipass!=0) CurrentLine->AddIndexPassing(Ipass);
315 previousPoint.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
316 previousd3d = Func.Direction3d();
317 previousd2d = Func.Direction2d();
318 CurrentLine->AddPoint(previousPoint);
322 else { //no numerical solution NotDone
324 PasCu = Abs(PasC*previousd2d.X());
325 PasCv = Abs(PasC*previousd2d.Y());
327 if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
328 if (CurrentLine->NbPoints() == 1) break; // cancel the line
329 Arrive = Standard_True;
330 CurrentLine->AddStatusFirstLast(Standard_False,Standard_False,
332 Tgtend = Standard_True;
333 Rajout = Standard_True;
334 seqAjout.Append(lines.Length()+1);
337 }// end of started line
339 CurrentLine->SetTangencyAtBegining(Tgtbeg);
340 CurrentLine->SetTangencyAtEnd(Tgtend);
342 lines.Append(CurrentLine);
343 wd2[I].etat=-wd2[I].etat; //mark point as processed
345 } //end of processing of start point
346 } //end of all start points