b311480e |
1 | // Created on: 1991-05-27 |
2 | // Created by: Isabelle GRIGNON |
3 | // Copyright (c) 1991-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 | |
42cf5bc1 |
17 | |
18 | #include <Adaptor2d_HCurve2d.hxx> |
19 | #include <gp_Pnt.hxx> |
20 | #include <gp_Pnt2d.hxx> |
21 | #include <IntPatch_Point.hxx> |
22 | #include <IntPatch_WLine.hxx> |
23 | #include <IntSurf_LineOn2S.hxx> |
24 | #include <IntSurf_PntOn2S.hxx> |
25 | #include <Standard_DomainError.hxx> |
26 | #include <Standard_OutOfRange.hxx> |
27 | #include <Standard_Type.hxx> |
7fd59977 |
28 | |
92efcf78 |
29 | IMPLEMENT_STANDARD_RTTIEXT(IntPatch_WLine,IntPatch_PointLine) |
30 | |
7fd59977 |
31 | #define DEBUG 0 |
32 | #define DEBUGV 0 |
33 | |
34 | #include <IntSurf_PntOn2S.hxx> |
35 | #include <Precision.hxx> |
36 | #include <stdio.h> |
37 | |
38 | |
39 | IntPatch_WLine::IntPatch_WLine (const Handle(IntSurf_LineOn2S)& Line, |
40 | const Standard_Boolean Tang, |
41 | const IntSurf_TypeTrans Trans1, |
42 | const IntSurf_TypeTrans Trans2) : |
d4b867e6 |
43 | IntPatch_PointLine(Tang,Trans1,Trans2),fipt(Standard_False),lapt(Standard_False), |
716037dd |
44 | hasArcOnS1(Standard_False),hasArcOnS2(Standard_False), |
98974dcc |
45 | myIsPurgerAllowed(Standard_True), |
46 | myCreationWay(IntPatch_WLUnknown) |
7fd59977 |
47 | { |
48 | typ = IntPatch_Walking; |
49 | curv = Line; |
7fd59977 |
50 | u1period=v1period=u2period=v2period=0.0; |
51 | } |
52 | |
53 | |
54 | IntPatch_WLine::IntPatch_WLine (const Handle(IntSurf_LineOn2S)& Line, |
55 | const Standard_Boolean Tang, |
56 | const IntSurf_Situation Situ1, |
57 | const IntSurf_Situation Situ2) : |
d4b867e6 |
58 | IntPatch_PointLine(Tang,Situ1,Situ2),fipt(Standard_False),lapt(Standard_False), |
716037dd |
59 | hasArcOnS1(Standard_False),hasArcOnS2(Standard_False), |
98974dcc |
60 | myIsPurgerAllowed(Standard_True), |
61 | myCreationWay(IntPatch_WLUnknown) |
7fd59977 |
62 | { |
63 | typ = IntPatch_Walking; |
64 | curv = Line; |
7fd59977 |
65 | u1period=v1period=u2period=v2period=0.0; |
66 | } |
67 | |
68 | |
69 | IntPatch_WLine::IntPatch_WLine (const Handle(IntSurf_LineOn2S)& Line, |
70 | const Standard_Boolean Tang) : |
d4b867e6 |
71 | IntPatch_PointLine(Tang),fipt(Standard_False),lapt(Standard_False), |
716037dd |
72 | hasArcOnS1(Standard_False),hasArcOnS2(Standard_False), |
98974dcc |
73 | myIsPurgerAllowed(Standard_True), |
74 | myCreationWay(IntPatch_WLUnknown) |
7fd59977 |
75 | { |
76 | typ = IntPatch_Walking; |
77 | curv = Line; |
7fd59977 |
78 | u1period=v1period=u2period=v2period=0.0; |
79 | } |
80 | |
81 | |
82 | void IntPatch_WLine::SetPoint(const Standard_Integer Index, |
83 | const IntPatch_Point& thepoint) |
84 | { |
85 | curv->Value(Index,thepoint.PntOn2S()); |
86 | } |
87 | |
88 | |
89 | Handle(IntSurf_LineOn2S) IntPatch_WLine::Curve() const |
90 | { |
91 | return(curv); |
92 | } |
93 | |
94 | static void RecadreMemePeriode(Standard_Real& u1,Standard_Real& v1, |
95 | Standard_Real& u2,Standard_Real& v2, |
96 | const Standard_Real anu1,const Standard_Real anv1, |
97 | const Standard_Real anu2,const Standard_Real anv2, |
98 | const Standard_Real U1Period,const Standard_Real V1Period, |
99 | const Standard_Real U2Period,const Standard_Real V2Period) { |
100 | if(U1Period) { |
101 | while(anu1-u1 > 0.8*U1Period) { u1+=U1Period; } |
102 | while(u1-anu1 > 0.8*U1Period) { u1-=U1Period; } |
103 | } |
104 | if(U2Period) { |
105 | while(anu2-u2 > 0.8*U2Period) { u2+=U2Period; } |
106 | while(u2-anu2 > 0.8*U2Period) { u2-=U2Period; } |
107 | } |
108 | if(V1Period) { |
109 | while(anv1-v1 > 0.8*V1Period) { v1+=V1Period; } |
110 | while(v1-anv1 > 0.8*V1Period) { v1-=V1Period; } |
111 | } |
112 | if(V2Period) { |
113 | while(anv2-v2 > 0.8*V2Period) { v2+=V2Period; } |
114 | while(v2-anv2 > 0.8*V2Period) { v2-=V2Period; } |
115 | } |
116 | |
117 | } |
118 | |
119 | static void RecadreMemePeriode(IntSurf_PntOn2S& POn2S,const IntSurf_PntOn2S& RefPOn2S, |
120 | const Standard_Real up1, |
121 | const Standard_Real vp1, |
122 | const Standard_Real up2, |
123 | const Standard_Real vp2) { |
124 | Standard_Real u1,v1,u2,v2,pu1,pv1,pu2,pv2; |
125 | POn2S.Parameters(u1,v1,u2,v2); |
126 | RefPOn2S.Parameters(pu1,pv1,pu2,pv2); |
127 | RecadreMemePeriode(u1,v1,u2,v2,pu1,pv1,pu2,pv2,up1,vp1,up2,vp2); |
128 | POn2S.SetValue(u1,v1,u2,v2); |
129 | } |
130 | |
68cdb44b |
131 | static Standard_Boolean CompareVertexAndPoint(const gp_Pnt& V, const gp_Pnt& P, const Standard_Real& Tol) { |
c0e32b3c |
132 | const Standard_Real aSQDist = V.SquareDistance(P); |
133 | const Standard_Real aSQTol = Tol*Tol; |
134 | return (aSQDist <= aSQTol); |
7fd59977 |
135 | } |
136 | |
137 | void IntPatch_WLine::SetPeriod(const Standard_Real pu1, |
138 | const Standard_Real pv1, |
139 | const Standard_Real pu2, |
140 | const Standard_Real pv2) { |
141 | u1period=pu1; v1period=pv1; u2period=pu2; v2period=pv2; |
142 | } |
143 | Standard_Real IntPatch_WLine::U1Period() const { return(u1period); } |
144 | Standard_Real IntPatch_WLine::V1Period() const { return(v1period); } |
145 | Standard_Real IntPatch_WLine::U2Period() const { return(u2period); } |
146 | Standard_Real IntPatch_WLine::V2Period() const { return(v2period); } |
147 | |
148 | |
149 | //------------------------------------------------------------------------ |
150 | //-- En Entree : Une ligne de cheminement + Une Liste de Vetex |
151 | //-- |
152 | //-- LineOn2S : 1------2-------3-------4-----5---- ----nbp |
153 | //-- |
154 | //-- Vertex : a b c d e f |
155 | //-- |
156 | //-- |
157 | //-- En Sortie |
158 | //-- |
159 | //-- 1--2-3-4--5--------6----7--8--9--10-------- |
160 | //-- |
161 | //-- avec a de parametre 1 |
162 | //-- b 3 |
163 | //-- |
164 | //-- etc ... |
165 | //-- |
166 | //-- |
167 | //-- !!!!!!!!!!!!!!! On considere que deux vertex ne peuvent pas etre |
168 | //-- !!!!!!!!!!!!!!! a une distance inferieure a Tol |
169 | //------------------------------------------------------------------------ |
170 | //-- |
171 | //-- On Teste si la LineOn2S contient des points confondus. |
172 | //-- Dans ce cas, on remove ces points. |
173 | //-- |
174 | //------------------------------------------------------------------------ |
175 | |
176 | Standard_Boolean SameVtxRst(const IntPatch_Point& vtx1,const IntPatch_Point& vtx2) { |
177 | if(vtx1.IsOnDomS1()) { |
178 | if(vtx2.IsOnDomS1()) { |
179 | if(vtx1.ArcOnS1() == vtx2.ArcOnS1()) { |
180 | if(vtx1.ParameterOnArc1() == vtx2.ParameterOnArc1()) { |
181 | |
182 | } |
183 | else { |
184 | return(Standard_False); |
185 | } |
186 | } |
187 | else { |
188 | return(Standard_False); |
189 | } |
190 | } |
191 | else { |
192 | return(Standard_False); |
193 | } |
194 | } |
195 | else { |
196 | if(vtx2.IsOnDomS1()) { |
197 | return(Standard_False); |
198 | } |
199 | } |
200 | if(vtx1.IsOnDomS2()) { |
201 | if(vtx2.IsOnDomS2()) { |
202 | if(vtx1.ArcOnS2() == vtx2.ArcOnS2()) { |
203 | if(vtx1.ParameterOnArc2() == vtx2.ParameterOnArc2()) { |
204 | |
205 | } |
206 | else { |
207 | return(Standard_False); |
208 | } |
209 | } |
210 | else { |
211 | return(Standard_False); |
212 | } |
213 | } |
214 | else { |
215 | return(Standard_False); |
216 | } |
217 | } |
218 | else { |
219 | if(vtx2.IsOnDomS2()) { |
220 | return(Standard_False); |
221 | } |
222 | } |
223 | return(Standard_True); |
224 | } |
225 | |
226 | |
227 | static Standard_Boolean CompareVerticesOnSurf(const IntPatch_Point& vtx1, |
228 | const IntPatch_Point& vtx2, |
229 | const Standard_Boolean onFirst) |
230 | { |
231 | Standard_Real u1,v1,u2,v2, tolU, tolV; |
232 | if (onFirst) { |
233 | vtx1.ParametersOnS1(u1,v1); |
234 | vtx2.ParametersOnS1(u2,v2); |
235 | } |
236 | else { |
237 | vtx1.ParametersOnS2(u1,v1); |
238 | vtx2.ParametersOnS2(u2,v2); |
239 | } |
240 | tolU = Precision::PConfusion(); |
241 | tolV = Precision::PConfusion(); |
242 | return (Abs(u1-u2) <= tolU && Abs(v1-v2) <= tolV); |
243 | } |
244 | |
245 | inline Standard_Boolean CompareVerticesOnS1(const IntPatch_Point& vtx1, const IntPatch_Point& vtx2) |
246 | {return CompareVerticesOnSurf (vtx1, vtx2, Standard_True);} |
247 | |
248 | inline Standard_Boolean CompareVerticesOnS2(const IntPatch_Point& vtx1, const IntPatch_Point& vtx2) |
249 | {return CompareVerticesOnSurf (vtx1, vtx2, Standard_False);} |
250 | |
251 | |
882e1d11 |
252 | void IntPatch_WLine::ComputeVertexParameters( const Standard_Real RTol) |
c2c2f2b6 |
253 | { |
7fd59977 |
254 | // MSV Oct 15, 2001: use tolerance of vertex instead of RTol where |
255 | // it is possible |
256 | |
257 | Standard_Integer i,j,k,nbvtx,nbponline; |
258 | Standard_Integer indicevertexonline; |
259 | Standard_Real indicevertex; |
260 | |
7fd59977 |
261 | Standard_Boolean APointDeleted = Standard_False; |
262 | //---------------------------------------------------------- |
263 | //-- F i l t r e s u r r e s t r i c t i o n s -- |
264 | //---------------------------------------------------------- |
265 | //-- deux vertex sur la meme restriction et seulement |
266 | //-- sur celle ci ne doivent pas avoir le meme parametre |
267 | //-- |
268 | Standard_Real Tol=RTol; |
269 | nbvtx = NbVertex(); |
270 | |
271 | #if DEBUGV |
272 | cout<<"\n----------- avant ComputeVertexParameters -------------"<<endl; |
273 | for(i=1;i<=nbvtx;i++) { |
274 | Vertex(i).Dump(); |
275 | Standard_Real polr = Vertex(i).ParameterOnLine(); |
276 | Standard_Real pol = (Standard_Integer)polr; |
277 | if(pol>=1 && pol<=nbvtx) { |
278 | cout<<"----> IntSurf_PntOn2S : "<<polr<<" Pnt ("<<Vertex(pol).Value().X() |
279 | <<","<<Vertex(pol).Value().Y() |
280 | <<","<<Vertex(pol).Value().Z()<<")"<<endl; |
281 | } |
282 | } |
283 | cout<<"\n----------------------------------------------------------"<<endl; |
284 | #endif |
285 | |
286 | |
287 | //-- ---------------------------------------------------------------------- |
288 | //-- Traitement des aretes de couture : On duplique les points situes |
289 | //-- sur des restrictions differentes |
290 | //-- |
291 | //-- Phase Creation de nouveaux points sur S1 |
292 | Standard_Boolean encoreunefois; |
293 | do { |
294 | nbvtx=NbVertex(); |
295 | encoreunefois=Standard_False; |
296 | for(i=1; i<=nbvtx && encoreunefois==Standard_False; i++) { |
297 | IntPatch_Point& VTXi = svtx.ChangeValue(i); |
298 | for(j=1; j<=nbvtx && encoreunefois==Standard_False; j++) { |
299 | if(i!=j) { |
300 | IntPatch_Point& VTXj = svtx.ChangeValue(j); |
301 | if(VTXi.ParameterOnLine() != VTXj.ParameterOnLine()) { |
302 | Standard_Real d = VTXi.Value().Distance(VTXj.Value()); |
303 | Standard_Real toli = VTXi.Tolerance(); |
304 | Standard_Real tolj = VTXj.Tolerance(); |
305 | Standard_Real maxtol = Max(toli,tolj); |
306 | // MSV Oct 30, 2001: compare in 2D space also; |
307 | // increase tolerances |
308 | if (d < maxtol || |
309 | CompareVerticesOnS1(VTXi,VTXj) || CompareVerticesOnS2(VTXi,VTXj)) { |
310 | //-- Creation Vtx (REF:S1(i) S2(j)) (On Garde S1(i)) |
311 | Standard_Real newtoli = Max (toli, tolj+d*1.01); |
312 | Standard_Real newtolj = Max (tolj, toli+d*1.01); |
313 | Standard_Boolean acreer=Standard_False; |
314 | if(VTXi.IsOnDomS1()) { |
315 | if(VTXj.IsOnDomS1()) { |
316 | if(VTXj.ArcOnS1() != VTXi.ArcOnS1()) { |
317 | acreer=Standard_True; |
318 | } |
319 | } |
320 | else { |
321 | acreer=Standard_True; |
322 | } |
323 | } |
324 | if(acreer) { |
325 | IntPatch_Point vtx; |
326 | vtx = VTXj; |
327 | vtx.SetArc(Standard_True, |
328 | VTXi.ArcOnS1(), |
329 | VTXi.ParameterOnArc1(), |
330 | VTXi.TransitionLineArc1(), |
331 | VTXi.TransitionOnS1()); |
332 | for(k=1; encoreunefois==Standard_False && k<=nbvtx; k++) { |
333 | const IntPatch_Point& VTXk = svtx.Value(k); |
334 | if(SameVtxRst(VTXk,vtx)) { |
335 | encoreunefois=Standard_True; |
336 | } |
337 | } |
338 | if(encoreunefois==Standard_False) { |
339 | VTXi.SetTolerance(newtoli); |
340 | VTXj.SetTolerance(newtolj); |
341 | vtx.SetTolerance(newtolj); |
342 | svtx.Append(vtx); |
343 | encoreunefois=Standard_True; |
344 | } |
345 | else { |
346 | encoreunefois=Standard_False; |
347 | } |
348 | } |
349 | //-- ----------------------------------------------------- |
350 | //-- Creation Vtx (REF:S2(i) S1(j)) (On Garde S2(i)) |
351 | acreer=Standard_False; |
352 | if(VTXi.IsOnDomS2()) { |
353 | if(VTXj.IsOnDomS2()) { |
354 | if(VTXj.ArcOnS2() != VTXi.ArcOnS2()) { |
355 | acreer=Standard_True; |
356 | } |
357 | } |
358 | else { |
359 | acreer=Standard_True; |
360 | } |
361 | } |
362 | if(acreer) { |
363 | IntPatch_Point vtx; |
364 | vtx = VTXj; |
365 | vtx.SetArc(Standard_False, |
366 | VTXi.ArcOnS2(), |
367 | VTXi.ParameterOnArc2(), |
368 | VTXi.TransitionLineArc2(), |
369 | VTXi.TransitionOnS2()); |
370 | for(k=1; encoreunefois==Standard_False && k<=nbvtx; k++) { |
371 | const IntPatch_Point& VTXk = svtx.Value(k); |
372 | if(SameVtxRst(VTXk,vtx)) { |
373 | encoreunefois=Standard_True; |
374 | } |
375 | } |
376 | if(encoreunefois==Standard_False) { |
377 | VTXi.SetTolerance(newtoli); |
378 | VTXj.SetTolerance(newtolj); |
379 | vtx.SetTolerance(newtolj); |
380 | svtx.Append(vtx); |
381 | encoreunefois=Standard_True; |
382 | } |
383 | else { |
384 | encoreunefois=Standard_False; |
385 | } |
386 | } |
387 | } |
388 | } |
389 | } |
390 | } |
391 | } |
392 | } |
393 | while(encoreunefois); |
394 | |
395 | |
396 | |
397 | //-- ---------------------------------------------------------------------- |
398 | |
399 | |
400 | |
401 | do { |
402 | APointDeleted = Standard_False; |
403 | for(i=1; (i<=nbvtx) && (APointDeleted==Standard_False) ;i++) { |
404 | const IntPatch_Point& VTXi = svtx.Value(i); |
405 | if(VTXi.Tolerance() > Tol) Tol = VTXi.Tolerance(); //-- 9 oct 97 |
406 | if((VTXi.IsOnDomS1()==Standard_True) && (VTXi.IsOnDomS2()==Standard_False)) { |
407 | for(j=1; (j<=nbvtx) && (APointDeleted==Standard_False) ;j++) { |
408 | if(i!=j) { |
409 | const IntPatch_Point& VTXj = svtx.Value(j); |
410 | if((VTXj.IsOnDomS1()==Standard_True) && (VTXj.IsOnDomS2()==Standard_False)) { |
411 | if(VTXi.ParameterOnLine() == VTXj.ParameterOnLine()) { |
412 | if(VTXi.ArcOnS1() == VTXj.ArcOnS1()) { |
413 | svtx.Remove(j); |
414 | nbvtx--; |
415 | if(lapt) { if(indl>=j) indl--; } |
416 | if(fipt) { if(indf>=j) indf--; } |
417 | APointDeleted = Standard_True; |
418 | } |
419 | } |
420 | } |
421 | } |
422 | } |
423 | } |
424 | } |
425 | } |
426 | while(APointDeleted == Standard_True); |
427 | |
428 | |
429 | do { |
430 | APointDeleted = Standard_False; |
431 | for(i=1; (i<=nbvtx) && (APointDeleted==Standard_False) ;i++) { |
432 | const IntPatch_Point& VTXi = svtx.Value(i); |
433 | if((VTXi.IsOnDomS2()==Standard_True) && (VTXi.IsOnDomS1()==Standard_False)) { |
434 | for(j=1; (j<=nbvtx) && (APointDeleted==Standard_False) ;j++) { |
435 | if(i!=j) { |
436 | const IntPatch_Point& VTXj = svtx.Value(j); |
437 | if((VTXj.IsOnDomS2()==Standard_True) && (VTXj.IsOnDomS1()==Standard_False)) { |
438 | if(VTXi.ParameterOnLine() == VTXj.ParameterOnLine()) { |
439 | if(VTXi.ArcOnS2() == VTXj.ArcOnS2()) { |
440 | svtx.Remove(j); |
441 | nbvtx--; |
442 | if(lapt) { if(indl>=j) indl--; } |
443 | if(fipt) { if(indf>=j) indf--; } |
444 | APointDeleted = Standard_True; |
445 | } |
446 | } |
447 | } |
448 | } |
449 | } |
450 | } |
451 | } |
452 | } |
453 | while(APointDeleted == Standard_True); |
454 | |
455 | nbvtx = NbVertex(); |
456 | nbponline = NbPnts(); |
457 | |
458 | //---------------------------------------------------- |
459 | //-- On trie les Vertex |
460 | Standard_Boolean SortIsOK; |
461 | do { |
462 | SortIsOK = Standard_True; |
463 | for(i=2; i<=nbvtx; i++) { |
464 | if(svtx.Value(i-1).ParameterOnLine() > svtx.Value(i).ParameterOnLine()) { |
465 | SortIsOK = Standard_False; |
466 | svtx.Exchange(i-1,i); |
467 | } |
468 | } |
469 | } |
470 | while(!SortIsOK); |
471 | |
472 | //---------------------------------------------------- |
473 | //-- On detecte les points confondus dans la LineOn2S |
474 | Standard_Real dmini = Precision::Confusion(); |
475 | dmini*=dmini; |
f73c584c |
476 | for(i=2; (i<=nbponline) && (nbponline > 2); i++) { |
c2c2f2b6 |
477 | const IntSurf_PntOn2S& aPnt1=curv->Value(i-1); |
478 | const IntSurf_PntOn2S& aPnt2=curv->Value(i); |
479 | Standard_Real d = (aPnt1.Value()).SquareDistance((aPnt2.Value())); |
7fd59977 |
480 | if(d < dmini) { |
481 | curv->RemovePoint(i); |
482 | nbponline--; |
483 | //---------------------------------------------- |
484 | //-- On recadre les Vertex si besoin |
485 | //-- |
486 | for(j=1; j<=nbvtx; j++) { |
c2c2f2b6 |
487 | indicevertex = svtx.Value(j).ParameterOnLine(); |
488 | if(indicevertex >= i) { |
489 | svtx.ChangeValue(j).SetParameter(indicevertex-1.0); |
490 | } |
7fd59977 |
491 | } |
492 | //modified by NIZNHY-PKV Mon Feb 11 09:28:02 2002 f |
493 | i--; |
494 | //modified by NIZNHY-PKV Mon Feb 11 09:28:04 2002 t |
495 | } |
496 | } |
497 | //---------------------------------------------------- |
498 | for(i=1; i<=nbvtx; i++) { |
499 | const gp_Pnt& P = svtx.Value(i).Value(); |
500 | Standard_Real vTol = svtx.Value(i).Tolerance(); |
882e1d11 |
501 | |
502 | indicevertex = svtx.Value(i).ParameterOnLine(); |
7fd59977 |
503 | indicevertexonline = (Standard_Integer)indicevertex; |
504 | //-------------------------------------------------- |
505 | //-- On Compare le vertex avec les points de la ligne |
506 | //-- d indice indicevertexOnLine-1 |
507 | //-- indicevertexOnLine |
508 | //-- indicevertexOnLine+1 |
509 | //-------------------------------------------------- |
510 | if(indicevertexonline<1) { |
511 | if(CompareVertexAndPoint(P,curv->Value(1).Value(),vTol)) { |
512 | //------------------------------------------------------- |
513 | //-- On remplace le point cheminement(1) par vertex(i) |
514 | //-- et vertex(i) prend pour parametre 1 |
515 | //------------------------------------------------------- |
516 | |
517 | IntSurf_PntOn2S POn2S = svtx.Value(i).PntOn2S(); |
518 | RecadreMemePeriode(POn2S,curv->Value(1),U1Period(),V1Period(),U2Period(),V2Period()); |
519 | curv->Value(1,POn2S); |
520 | |
521 | //--curv->Value(1,svtx.Value(i).PntOn2S()); |
522 | svtx.ChangeValue(i).SetParameter(1.0); |
523 | } |
524 | else { |
525 | //------------------------------------------------------- |
526 | //-- On insere le point de cheminement Vertex(i) |
527 | //-- On recadre les parametres des autres vertex |
528 | //------------------------------------------------------- |
529 | IntSurf_PntOn2S POn2S = svtx.Value(i).PntOn2S(); |
530 | RecadreMemePeriode(POn2S,curv->Value(1),U1Period(),V1Period(),U2Period(),V2Period()); |
531 | curv->InsertBefore(1,POn2S); |
532 | |
533 | //-- curv->InsertBefore(1,svtx.Value(i).PntOn2S()); |
534 | svtx.ChangeValue(i).SetParameter(1.0); |
535 | nbponline++; |
536 | for(j=1;j<=nbvtx;j++) { |
537 | if(j!=1) { |
538 | Standard_Real t = svtx.Value(j).ParameterOnLine(); |
539 | if(t>1.0) { |
540 | svtx.ChangeValue(j).SetParameter(t+1.0); |
541 | } |
542 | } |
543 | } |
544 | } |
545 | } //--- fin : if(indicevertexonline<1) |
546 | else { |
547 | //--------------------------------------------------------- |
548 | //-- vertex(i) == cheminement (indicevertexonline-1) |
549 | //-- vertex(i) == cheminement (indicevertexonline) |
550 | //-- vertex(i) == cheminement (indicevertexonline+1) |
551 | //--------------------------------------------------------- |
552 | Standard_Boolean Substitution = Standard_False; |
553 | //-- for(k=indicevertexonline+1; !Substitution && k>=indicevertexonline-1;k--) { avant le 9 oct 97 |
554 | for(k=indicevertexonline+1; k>=indicevertexonline-1;k--) { |
555 | if(k>0 && k<=nbponline) { |
556 | if(CompareVertexAndPoint(P,curv->Value(k).Value(),vTol)) { |
557 | //------------------------------------------------------- |
558 | //-- On remplace le point cheminement(k) |
559 | //-- par vertex(i) et vertex(i) prend pour parametre k |
560 | //------------------------------------------------------- |
561 | IntSurf_PntOn2S POn2S = svtx.Value(i).PntOn2S(); |
562 | RecadreMemePeriode(POn2S,curv->Value(k),U1Period(),V1Period(),U2Period(),V2Period()); |
563 | curv->Value(k,POn2S); |
564 | Standard_Real mu1,mv1,mu2,mv2; |
565 | POn2S.Parameters(mu1,mv1,mu2,mv2); |
566 | svtx.ChangeValue(i).SetParameter(k); |
567 | svtx.ChangeValue(i).SetParameters(mu1,mv1,mu2,mv2); |
568 | Substitution = Standard_True; |
569 | } |
570 | } |
571 | } |
e9a6ce82 |
572 | |
573 | //Remove duplicating points |
574 | if (Substitution) |
575 | { |
576 | Standard_Integer ind_point; |
1406e955 |
577 | for(ind_point = 2; (ind_point <= nbponline && nbponline > 1); ind_point++) { |
e9a6ce82 |
578 | Standard_Real d = (curv->Value(ind_point-1).Value()).SquareDistance((curv->Value(ind_point).Value())); |
579 | if(d < dmini) { |
580 | curv->RemovePoint(ind_point); |
581 | nbponline--; |
582 | //---------------------------------------------- |
583 | //-- On recadre les Vertex si besoin |
584 | //-- |
585 | for(j=1; j<=nbvtx; j++) { |
586 | indicevertex = svtx.Value(j).ParameterOnLine(); |
587 | if(indicevertex >= ind_point) { |
588 | svtx.ChangeValue(j).SetParameter(indicevertex-1.0); |
589 | } |
590 | } |
591 | //modified by NIZNHY-PKV Mon Feb 11 09:28:02 2002 f |
592 | ind_point--; |
593 | //modified by NIZNHY-PKV Mon Feb 11 09:28:04 2002 t |
594 | } |
595 | } |
596 | } |
7fd59977 |
597 | |
598 | //--static int deb6nov98=1; Ne resout rien (a part partiellement BUC60409) |
599 | //--if(deb6nov98) { |
600 | //--Substitution=Standard_True; |
601 | //-- } |
602 | |
603 | if(Substitution==Standard_False) { |
604 | //------------------------------------------------------- |
605 | //-- On insere le point de cheminement Vertex(i) |
606 | //-- On recadre les parametres des autres vertex |
607 | //------------------------------------------------------- |
608 | IntSurf_PntOn2S POn2S = svtx.Value(i).PntOn2S(); |
609 | if(indicevertexonline >= nbponline) { |
610 | RecadreMemePeriode(POn2S,curv->Value(nbponline),U1Period(),V1Period(),U2Period(),V2Period()); |
611 | curv->Add(POn2S); |
612 | } |
613 | else { |
614 | RecadreMemePeriode(POn2S,curv->Value(indicevertexonline+1),U1Period(),V1Period(),U2Period(),V2Period()); |
615 | curv->InsertBefore(indicevertexonline+1,POn2S); |
616 | } |
617 | //-- curv->InsertBefore(indicevertexonline+1,svtx.Value(i).PntOn2S()); |
618 | svtx.ChangeValue(i).SetParameter(indicevertexonline+1); |
619 | nbponline++; |
620 | for(j=1;j<=nbvtx;j++) { |
621 | if(j!=i) { |
622 | Standard_Real t = svtx.Value(j).ParameterOnLine(); |
623 | if(t>(Standard_Real)indicevertexonline) { |
624 | svtx.ChangeValue(j).SetParameter(t+1.0); |
625 | } |
626 | } |
627 | } |
628 | } //-- Substitution |
629 | } //-- indicevertexonline>=1 |
630 | |
631 | } //-- boucle i sur vertex |
632 | |
633 | |
634 | |
635 | |
636 | do { |
637 | APointDeleted = Standard_False; |
638 | for(i=1; i<=nbvtx && (APointDeleted == Standard_False); i++) { |
639 | const IntPatch_Point& VTX = svtx.Value(i); |
640 | for(j=1; j<=nbvtx && (APointDeleted == Standard_False) ; j++) { |
641 | if(i!=j) { |
642 | const IntPatch_Point& VTXM1 = svtx.Value(j); |
643 | |
644 | Standard_Boolean kill = Standard_False; |
645 | Standard_Boolean killm1 = Standard_False; |
646 | if(VTXM1.ParameterOnLine() == VTX.ParameterOnLine()) { |
647 | if(VTXM1.IsOnDomS1() && VTX.IsOnDomS1()) { //-- OnS1 OnS1 |
648 | if(VTXM1.ArcOnS1() == VTX.ArcOnS1()) { //-- OnS1 == OnS1 |
649 | if(VTXM1.IsOnDomS2()) { //-- OnS1 == OnS1 OnS2 |
650 | if(VTX.IsOnDomS2()==Standard_False) { //-- OnS1 == OnS1 OnS2 PasOnS2 |
651 | kill=Standard_True; |
652 | } |
653 | else { |
654 | if(VTXM1.ArcOnS2() == VTX.ArcOnS2()) { //-- OnS1 == OnS1 OnS2 == OnS2 |
655 | kill=Standard_True; |
656 | } |
657 | } |
658 | } |
659 | else { //-- OnS1 == OnS1 PasOnS2 |
660 | if(VTX.IsOnDomS2()) { //-- OnS1 == OnS1 PasOnS2 OnS2 |
661 | killm1=Standard_True; |
662 | } |
663 | } |
664 | } |
665 | } |
666 | |
667 | if(!(kill || killm1)) { |
668 | if(VTXM1.IsOnDomS2() && VTX.IsOnDomS2()) { //-- OnS2 OnS2 |
669 | if(VTXM1.ArcOnS2() == VTX.ArcOnS2()) { //-- OnS2 == OnS2 |
670 | if(VTXM1.IsOnDomS1()) { //-- OnS2 == OnS2 OnS1 |
671 | if(VTX.IsOnDomS1()==Standard_False) { //-- OnS2 == OnS2 OnS1 PasOnS1 |
672 | kill=Standard_True; |
673 | } |
674 | else { |
675 | if(VTXM1.ArcOnS1() == VTX.ArcOnS1()) { //-- OnS2 == OnS2 OnS1 == OnS1 |
676 | kill=Standard_True; |
677 | } |
678 | } |
679 | } |
680 | else { //-- OnS2 == OnS2 PasOnS1 |
681 | if(VTX.IsOnDomS1()) { //-- OnS2 == OnS2 PasOnS1 OnS1 |
682 | killm1=Standard_True; |
683 | } |
684 | } |
685 | } |
686 | } |
687 | } |
688 | if(kill) { |
689 | APointDeleted = Standard_True; |
690 | svtx.Remove(i); |
691 | nbvtx--; |
692 | } |
693 | else if(killm1) { |
694 | APointDeleted = Standard_True; |
695 | svtx.Remove(j); |
696 | nbvtx--; |
697 | } |
698 | } |
699 | } |
700 | } |
701 | } |
702 | } |
703 | while(APointDeleted == Standard_True); |
704 | |
705 | do { |
706 | SortIsOK = Standard_True; |
707 | for(i=2; i<=nbvtx && SortIsOK; i++) { |
708 | const IntPatch_Point& Pim1=svtx.Value(i-1); |
709 | const IntPatch_Point& Pii =svtx.Value(i); |
710 | if(Pim1.ParameterOnLine()==Pii.ParameterOnLine()) { |
711 | if( (Pii.IsOnDomS1() == Standard_False) |
712 | && (Pii.IsOnDomS2() == Standard_False)) { |
713 | SortIsOK = Standard_False; |
714 | svtx.Remove(i); |
715 | nbvtx--; |
716 | } |
717 | else { |
718 | if( (Pim1.IsOnDomS1() == Standard_False) |
719 | && (Pim1.IsOnDomS2() == Standard_False)) { |
720 | SortIsOK = Standard_False; |
721 | svtx.Remove(i-1); |
722 | nbvtx--; |
723 | } |
724 | } |
725 | } |
726 | } |
727 | } |
728 | while(!SortIsOK); |
729 | //-- ---------------------------------------------------------------------------- |
730 | //-- On ajoute les vertex de debut et de fin de ligne s il ne sont pas presents. |
731 | //-- |
732 | //-- Existe t il un vertex de debut de ligne, de fin . |
733 | //-- |
734 | //-- Si Besoin : il faudra dedoubler les points de debut et de fin sur les periodiques ?????? |
735 | |
736 | |
737 | |
738 | |
739 | Standard_Boolean bFirst = Standard_False; |
740 | Standard_Boolean bLast = Standard_False; |
741 | nbponline = NbPnts(); |
742 | for(i=1;i<=nbvtx;i++) { |
743 | Standard_Real pol = svtx.Value(i).ParameterOnLine(); |
744 | if(pol==1.0) { |
745 | bFirst = fipt = Standard_True; |
746 | indf = i; |
747 | } |
748 | if(pol==nbponline) { |
749 | bLast = lapt = Standard_True; |
750 | indl = i; |
751 | } |
752 | } |
753 | if(bFirst == Standard_False) { |
754 | Standard_Real pu1,pv1,pu2,pv2; |
755 | Standard_Boolean vtxfound = Standard_False; |
756 | IntPatch_Point vtx; |
757 | curv->Value(1).Parameters(pu1,pv1,pu2,pv2); |
758 | for(i=1; |
759 | (vtxfound==Standard_False) && (i<=nbvtx);i++) { |
760 | const IntPatch_Point& V = svtx.Value(i); |
68cdb44b |
761 | //jgv: to avoid loops |
762 | //Standard_Real vTol = V.Tolerance(); |
763 | if(CompareVertexAndPoint(V.Value(), curv->Value(1).Value(), Precision::Confusion()/*vTol*/)) { |
7fd59977 |
764 | vtx = V; |
765 | vtx.SetParameters(pu1,pv1,pu2,pv2); |
766 | vtxfound = Standard_True; |
767 | } |
768 | } |
769 | if(vtxfound == Standard_False) { |
770 | vtx.SetValue(curv->Value(1).Value(),Tol,Standard_False); |
771 | vtx.SetParameters(pu1,pv1,pu2,pv2); |
772 | } |
773 | vtx.SetParameter(1); |
774 | svtx.Prepend(vtx); nbvtx++; |
775 | fipt = Standard_True; |
776 | indf = 1; |
777 | } |
778 | if(bLast == Standard_False) { |
779 | Standard_Real pu1,pv1,pu2,pv2; |
780 | Standard_Boolean vtxfound = Standard_False; |
781 | IntPatch_Point vtx; |
782 | curv->Value(nbponline).Parameters(pu1,pv1,pu2,pv2); |
783 | for(i=1; |
784 | (vtxfound==Standard_False) && (i<=nbvtx);i++) { |
785 | const IntPatch_Point& V = svtx.Value(i); |
68cdb44b |
786 | //jgv: to avoid loops |
787 | //Standard_Real vTol = V.Tolerance(); |
788 | if(CompareVertexAndPoint(V.Value(), curv->Value(nbponline).Value(), Precision::Confusion()/*vTol*/)) { |
7fd59977 |
789 | vtx = V; |
790 | vtx.SetParameters(pu1,pv1,pu2,pv2); |
791 | vtxfound = Standard_True; |
792 | } |
793 | } |
794 | if(vtxfound == Standard_False) { |
795 | vtx.SetValue(curv->Value(nbponline).Value(),Tol,Standard_False); |
796 | vtx.SetParameters(pu1,pv1,pu2,pv2); |
797 | } |
798 | vtx.SetParameter(nbponline); |
799 | svtx.Append(vtx); nbvtx++; |
800 | lapt = Standard_True; |
801 | indl = nbvtx; |
802 | } |
803 | |
804 | |
805 | |
806 | |
807 | //-------------------------------------------------------------- |
808 | //-- ** Detection de points trouves sur une meme restriction |
809 | //-- avec la meme transition et avec des params on line |
810 | //-- voisins. |
811 | //-- ** Dans ce cas (-> donnerait un baillemenmt) on supprime |
812 | //-- le point 'intermediaire'. |
813 | //-- ** (exemple Vtx(1) ..... Vtx(204) Vtx(205)) |
814 | //-- on supprime le Vtx(204) |
815 | //-- ** (exemple Vtx(1) Vtx(2) ..... Vtx(205)) |
816 | //-- on supprime le Vtx(2) |
817 | //-- ** (exemple Vtx(1) ... Vtx(100) Vtx(101) ... Vtx(205)) |
818 | //-- on supprime le Vtx(100) (Vtx(100)et101 sur m restr) |
819 | |
820 | //-------------------------------------------------------------- |
821 | nbvtx = NbVertex(); |
822 | do { |
823 | APointDeleted = Standard_False; |
824 | for(i=1; (i<=nbvtx) && (APointDeleted==Standard_False) ;i++) { |
825 | const IntPatch_Point& VTXi = svtx.Value(i); |
826 | if((VTXi.IsOnDomS1()==Standard_True) && (VTXi.IsOnDomS2()==Standard_False)) { |
827 | for(j=1; (j<=nbvtx) && (APointDeleted==Standard_False) ;j++) { |
828 | if(i!=j) { |
829 | const IntPatch_Point& VTXj = svtx.Value(j); |
830 | if((VTXj.IsOnDomS1()==Standard_True) && (VTXj.IsOnDomS2()==Standard_False)) { |
831 | if( (VTXi.ParameterOnLine() == VTXj.ParameterOnLine()+1) |
832 | || (VTXi.ParameterOnLine() == VTXj.ParameterOnLine()-1)) { |
833 | if(VTXi.ArcOnS1() == VTXj.ArcOnS1()) { |
834 | IntSurf_Transition t1 = VTXi.TransitionLineArc1(); |
835 | IntSurf_Transition t2 = VTXj.TransitionLineArc1(); |
836 | if(t1.TransitionType()==t2.TransitionType()) { |
837 | if((VTXj.ParameterOnLine()!=1) && (VTXj.ParameterOnLine()!=NbPnts())) { |
838 | svtx.Remove(j); |
839 | nbvtx--; |
840 | if(lapt) { if(indl>=j) indl--; } |
841 | if(fipt) { if(indf>=j) indf--; } |
842 | APointDeleted = Standard_True; |
843 | } |
844 | } |
845 | } |
846 | } |
847 | } |
848 | } |
849 | } |
850 | } |
851 | } |
852 | } |
853 | |
854 | //-- meme traitement sur les restrictions du second shape |
855 | |
856 | while(APointDeleted == Standard_True); |
857 | nbvtx = NbVertex(); |
858 | do { |
859 | APointDeleted = Standard_False; |
860 | for(i=1; (i<=nbvtx) && (APointDeleted==Standard_False) ;i++) { |
861 | const IntPatch_Point& VTXi = svtx.Value(i); |
862 | if((VTXi.IsOnDomS1()==Standard_False) && (VTXi.IsOnDomS2()==Standard_True)) { |
863 | for(j=1; (j<=nbvtx) && (APointDeleted==Standard_False) ;j++) { |
864 | if(i!=j) { |
865 | const IntPatch_Point& VTXj = svtx.Value(j); |
866 | if((VTXj.IsOnDomS1()==Standard_False) && (VTXj.IsOnDomS2()==Standard_True)) { |
867 | if( (VTXi.ParameterOnLine() == VTXj.ParameterOnLine()+1) |
868 | || (VTXi.ParameterOnLine() == VTXj.ParameterOnLine()-1)) { |
869 | if(VTXi.ArcOnS2() == VTXj.ArcOnS2()) { |
870 | IntSurf_Transition t1 = VTXi.TransitionLineArc2(); |
871 | IntSurf_Transition t2 = VTXj.TransitionLineArc2(); |
872 | if(t1.TransitionType()==t2.TransitionType()) { |
873 | if((VTXj.ParameterOnLine()!=1) && (VTXj.ParameterOnLine()!=NbPnts())) { |
874 | svtx.Remove(j); |
875 | nbvtx--; |
876 | if(lapt) { if(indl>=j) indl--; } |
877 | if(fipt) { if(indf>=j) indf--; } |
878 | APointDeleted = Standard_True; |
879 | } |
880 | } |
881 | } |
882 | } |
883 | } |
884 | } |
885 | } |
886 | } |
887 | } |
888 | } |
889 | while(APointDeleted == Standard_True); |
890 | //-------------------------------------------------------------- |
891 | |
892 | //-------------------------------------------------------------- |
893 | //-- dans le cas de lignes periodiques du type : |
894 | //-- Un point sur restriction R1 de param p1 -> P3d1 Vtx1 |
895 | //-- Un point sur restriction R2 de param p2 -> P3d1 Vtx2 |
896 | //-- |
897 | //-- Un point sur restriction R1 de param p1 -> P3d1 Vtx3 |
898 | //-- pas de point sur R2 |
899 | //-- |
900 | //-- On doit dans ce cas creer un nouveau Vtx4 = Vtx3 sur la |
901 | //-- restriction R2 |
902 | //-- |
903 | //-- Ce cas se produit qd on a corrige un baillement avec le filtre |
904 | //-- precedent |
905 | //-- |
906 | |
907 | |
908 | |
909 | |
910 | |
911 | |
912 | nbvtx = NbVertex(); |
913 | do { |
914 | SortIsOK = Standard_True; |
915 | for(i=2; i<=nbvtx; i++) { |
916 | if(svtx.Value(i-1).ParameterOnLine() > svtx.Value(i).ParameterOnLine()) { |
917 | SortIsOK = Standard_False; |
918 | svtx.Exchange(i-1,i); |
919 | } |
920 | } |
921 | } |
922 | while(!SortIsOK); |
923 | |
924 | //-- Dump(); |
925 | |
926 | #if DEBUGV |
927 | cout<<"\n----------- apres ComputeVertexParameters -------------"<<endl; |
928 | for(i=1;i<=nbvtx;i++) { |
929 | Vertex(i).Dump(); |
930 | Standard_Real polr = Vertex(i).ParameterOnLine(); |
931 | Standard_Real pol = (Standard_Integer)polr; |
932 | if(pol>=1 && pol<=nbvtx) { |
933 | cout<<"----> IntSurf_PntOn2S : "<<polr<<" Pnt ("<<Vertex(pol).Value().X() |
934 | <<","<<Vertex(pol).Value().Y() |
935 | <<","<<Vertex(pol).Value().Z()<<")"<<endl; |
936 | } |
937 | } |
938 | cout<<"\n----------------------------------------------------------"<<endl; |
939 | #endif |
940 | |
941 | |
942 | } |
943 | |
7fd59977 |
944 | Standard_Boolean IntPatch_WLine::HasArcOnS1() const { |
945 | return(hasArcOnS1); |
946 | } |
947 | |
948 | void IntPatch_WLine::SetArcOnS1(const Handle(Adaptor2d_HCurve2d)& A) { |
949 | hasArcOnS1=Standard_True; |
950 | theArcOnS1=A; |
951 | } |
952 | |
953 | const Handle(Adaptor2d_HCurve2d)& IntPatch_WLine::GetArcOnS1() const { |
954 | return(theArcOnS1); |
955 | } |
956 | |
957 | Standard_Boolean IntPatch_WLine::HasArcOnS2() const { |
958 | return(hasArcOnS2); |
959 | } |
960 | |
961 | void IntPatch_WLine::SetArcOnS2(const Handle(Adaptor2d_HCurve2d)& A) { |
962 | hasArcOnS2=Standard_True; |
963 | theArcOnS2=A; |
964 | } |
965 | |
966 | const Handle(Adaptor2d_HCurve2d)& IntPatch_WLine::GetArcOnS2() const { |
967 | return(theArcOnS2); |
968 | } |
969 | |
970 | |
eb75e31c |
971 | void IntPatch_WLine::Dump(const Standard_Integer theMode) const |
972 | { |
973 | cout<<" ----------- D u m p I n t P a t c h _ W L i n e -(begin)------"<<endl; |
974 | const Standard_Integer aNbPoints = NbPnts(); |
975 | const Standard_Integer aNbVertex = NbVertex(); |
976 | |
977 | switch(theMode) |
978 | { |
979 | case 0: |
980 | printf("Num [X Y Z] [U1 V1] [U2 V2]\n"); |
981 | for(Standard_Integer i=1; i<=aNbPoints; i++) |
982 | { |
983 | Standard_Real u1,v1,u2,v2; |
984 | Point(i).Parameters(u1,v1,u2,v2); |
985 | printf("%4d [%+10.20f %+10.20f %+10.20f] [%+10.20f %+10.20f] [%+10.20f %+10.20f]\n", |
986 | i,Point(i).Value().X(),Point(i).Value().Y(),Point(i).Value().Z(), |
987 | u1,v1,u2,v2); |
988 | } |
7fd59977 |
989 | |
eb75e31c |
990 | for(Standard_Integer i=1;i<=aNbVertex;i++) |
991 | { |
992 | Vertex(i).Dump(); |
993 | Standard_Real polr = Vertex(i).ParameterOnLine(); |
994 | Standard_Integer pol = static_cast<Standard_Integer>(polr); |
995 | |
996 | if(pol>=1 && pol<=aNbVertex) |
997 | { |
998 | cout<<"----> IntSurf_PntOn2S : "<< |
999 | polr <<", Pnt (" << Vertex(pol).Value().X() << "," << |
1000 | Vertex(pol).Value().Y() << "," << |
1001 | Vertex(pol).Value().Z() <<")" <<endl; |
1002 | } |
1003 | } |
1004 | |
1005 | break; |
1006 | case 1: |
1007 | for(Standard_Integer i = 1; i <= aNbPoints; i++) |
1008 | { |
1009 | Standard_Real u1,v1,u2,v2; |
1010 | Point(i).Parameters(u1,v1,u2,v2); |
1011 | printf("point p%d %+10.20f %+10.20f %+10.20f\n", |
1012 | i,Point(i).Value().X(),Point(i).Value().Y(),Point(i).Value().Z()); |
1013 | } |
1014 | |
1015 | break; |
1016 | case 2: |
1017 | for(Standard_Integer i = 1; i <= aNbPoints; i++) |
1018 | { |
1019 | Standard_Real u1,v1,u2,v2; |
1020 | Point(i).Parameters(u1,v1,u2,v2); |
1021 | printf("point p%d %+10.20f %+10.20f\n", i, u1, v1); |
1022 | } |
1023 | |
1024 | break; |
1025 | default: |
1026 | for(Standard_Integer i = 1; i <= aNbPoints; i++) |
1027 | { |
1028 | Standard_Real u1,v1,u2,v2; |
1029 | Point(i).Parameters(u1,v1,u2,v2); |
1030 | printf("point p%d %+10.20f %+10.20f\n", i, u2, v2); |
7fd59977 |
1031 | } |
eb75e31c |
1032 | |
1033 | break; |
7fd59977 |
1034 | } |
eb75e31c |
1035 | cout<<"\n--------------------------------------------------- (end) -------"<<endl; |
7fd59977 |
1036 | } |
1037 | |