0024057: Eliminate compiler warning C4100 in MSVC++ with warning level 4
[occt.git] / src / MAT2d / MAT2d_Circuit.cxx
CommitLineData
b311480e 1// Created on: 1993-11-19
2// Created by: Yves FRICAUD
3// Copyright (c) 1993-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21
22#ifdef DRAW
23#include <Draw_Appli.hxx>
24#include <DrawTrSurf_Curve2d.hxx>
25#include <Draw_Marker2D.hxx>
26#endif
27#ifdef DEB
28#include <GCE2d_MakeSegment.hxx>
29#include <Geom2d_Curve.hxx>
30#include <Geom2d_Parabola.hxx>
31#include <Geom2d_Hyperbola.hxx>
32#include <Geom2d_TrimmedCurve.hxx>
33#include <Geom2d_CartesianPoint.hxx>
34#include <Geom2d_Line.hxx>
35#include <Geom2d_Circle.hxx>
36#endif
37
38#include <MAT2d_Circuit.ixx>
39#include <Geom2d_TrimmedCurve.hxx>
40#include <Geom2d_CartesianPoint.hxx>
41#include <Geom2d_Geometry.hxx>
42#include <TColStd_SequenceOfInteger.hxx>
43#include <TColStd_Array1OfBoolean.hxx>
44#include <TColStd_Array1OfInteger.hxx>
45#include <MAT2d_BiInt.hxx>
46#include <MAT2d_MiniPath.hxx>
47#include <MAT2d_Connexion.hxx>
48#include <MAT2d_SequenceOfConnexion.hxx>
49#include <MAT2d_DataMapOfIntegerConnexion.hxx>
50#include <MAT2d_SequenceOfSequenceOfGeometry.hxx>
51#include <MAT2d_DataMapOfBiIntSequenceOfInteger.hxx>
52#include <MAT2d_DataMapIteratorOfDataMapOfBiIntSequenceOfInteger.hxx>
53#include <Precision.hxx>
54#include <Adaptor3d_OffsetCurve.hxx>
55#include <Geom2dInt_GInter.hxx>
56#include <Geom2dAdaptor_HCurve.hxx>
57#include <IntRes2d_IntersectionPoint.hxx>
58
59#ifdef DRAW
60 static Handle(DrawTrSurf_Curve2d) draw;
61 Standard_EXPORT Draw_Viewer dout;
62#endif
63#ifdef DEB
64 static void MAT2d_DrawCurve(const Handle(Geom2d_Curve)& aCurve,
65 const Standard_Integer Indice);
66 static Standard_Boolean AffichCircuit = 0;
67#endif
68
69// static functions:
70
71static Standard_Real CrossProd(const Handle(Geom2d_Geometry)& Geom1,
72 const Handle(Geom2d_Geometry)& Geom2,
73 Standard_Real& DotProd);
74
75static Standard_Boolean IsSharpCorner (const Handle(Geom2d_Geometry)& Geom1,
76 const Handle(Geom2d_Geometry)& Geom2,
77 const Standard_Real& Direction);
78
79//=============================================================================
80//function : Constructor
81//purpose :
82//=============================================================================
83MAT2d_Circuit::MAT2d_Circuit()
84{
85}
86
87//=============================================================================
88//function : Perform
89//purpose :
90//=============================================================================
91void MAT2d_Circuit::Perform
92 ( MAT2d_SequenceOfSequenceOfGeometry& FigItem,
93 const TColStd_SequenceOfBoolean & IsClosed,
94 const Standard_Integer IndRefLine,
95 const Standard_Boolean Trigo)
96{
97 Standard_Integer NbLines = FigItem.Length();
98 Standard_Integer i;
99 TColStd_Array1OfBoolean Open(1,NbLines);
100 MAT2d_SequenceOfConnexion SVide;
101 Handle(MAT2d_Connexion) ConnexionNul;
102
103 if (Trigo) direction = 1.; else direction = -1.;
104
105 //---------------------
106 // Reinitialisation SD.
107 //---------------------
108 geomElements.Clear();
109 connexionMap.Clear();
110 linkRefEqui.Clear();
111 linesLength.Clear();
112
113 //----------------------------
114 // Detection Lignes ouvertes.
115 //----------------------------
116 for ( i = 1; i <= NbLines; i++) {
117 Handle_Geom2d_TrimmedCurve Curve;
118 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(FigItem.Value(i).First());
119 gp_Pnt2d P1 = Curve->StartPoint();
120 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(FigItem.Value(i).Last());
121 gp_Pnt2d P2 = Curve->EndPoint();
122// Modified by Sergey KHROMOV - Wed Mar 6 16:59:01 2002 Begin
123// if ( P1.IsEqual(P2,Precision::Confusion())) Open(i) = Standard_False;
124// else Open(i) = Standard_True;
125 if (IsClosed(i)) Open(i) = Standard_False;
126 else if (P1.IsEqual(P2,Precision::Confusion())) Open(i) = Standard_False;
127 else Open(i) = Standard_True;
128// Modified by Sergey KHROMOV - Wed Mar 6 16:59:04 2002 End
129 }
130
131 //---------------------------------------------------------------
132 // Insertion des cassures saillantes ou
133 // ajout des extremites de chaque courbe si la ligne est ouverte.
134 //---------------------------------------------------------------
135 for ( i = 1; i <= NbLines; i++) {
136 if (Open(i)) {
137 InitOpen(FigItem.ChangeValue(i));
138 linesLength.Append(FigItem.Value(i).Length());
139 }
140 else {
141 InsertCorner(FigItem.ChangeValue(i));
142 linesLength.Append(FigItem.Value(i).Length());
143 }
144 }
145
146 //---------------------------------
147 // Une seule ligne => Rien a faire.
148 //---------------------------------
149 if (NbLines == 1) {
150 if (Open(1)) {
151 DoubleLine(FigItem.ChangeValue(1),SVide,ConnexionNul,direction);
152 linesLength.SetValue(1,FigItem.Value(1).Length());
153 }
154 geomElements = FigItem.Value(1);
155 UpDateLink(1,1,1,geomElements.Length());
156 linesLength.Append(FigItem.Value(1).Length());
157 return;
158 }
159
160 //------------------
161 // Plusieurs lignes.
162 //------------------
163
164 //---------------------------------------------------------
165 // Calcul de l ensemble des connexions realisant le chemin.
166 //---------------------------------------------------------
167 MAT2d_MiniPath Road;
168 Road.Perform(FigItem,IndRefLine,Trigo);
169
170 //------------------------
171 // Fermeture ligne ouverte.
172 //-------------------------
173 for ( i = 1; i <= NbLines; i++) {
174 if (Open(i)) {
175 Handle(MAT2d_Connexion) CF;
176 if (Road.IsRoot(i)) CF = ConnexionNul; else CF = Road.Father(i);
177 if (Road.IsConnexionsFrom(i)) {
178 DoubleLine(FigItem.ChangeValue(i),Road.ConnexionsFrom(i),
179 CF,direction);
180 }
181 else {
182 DoubleLine(FigItem.ChangeValue(i),SVide,CF,direction);
183 }
184 linesLength.SetValue(i,FigItem.Value(i).Length());
185 }
186 }
187
188 //------------------------
189 // Construction du chemin.
190 //------------------------
191 Road.RunOnConnexions();
192
193#ifdef DEB
194 if (AffichCircuit) {
195 Standard_Integer NbConnexions = Road.Path().Length();
196 for (i = 1; i <= NbConnexions; i++) {
197 Handle(Geom2d_TrimmedCurve) edge;
198 edge = GCE2d_MakeSegment(Road.Path().Value(i)->PointOnFirst(),
199 Road.Path().Value(i)->PointOnSecond());
200 MAT2d_DrawCurve(edge,2);
201 }
202 }
203#endif
204
205 //-------------------------
206 // Construction du Circuit.
207 //-------------------------
208 ConstructCircuit(FigItem,IndRefLine,Road);
209}
210
211//=======================================================================
212//function : SubSequence
213//purpose :
214//=======================================================================
215static void SubSequence(const TColGeom2d_SequenceOfGeometry& S1,
216 Standard_Integer IF,
217 Standard_Integer IL,
218 TColGeom2d_SequenceOfGeometry& S2)
219{
220 S2.Clear();
221 for (Standard_Integer i = IF; i<= IL; i++){
222 S2.Append(S1.Value(i));
223 }
224}
225
226
227//=============================================================================
228//function : ConstructCircuit
229//purpose :
230//=============================================================================
231void MAT2d_Circuit::ConstructCircuit
232 (const MAT2d_SequenceOfSequenceOfGeometry& FigItem,
233 const Standard_Integer IndRefLine,
234 const MAT2d_MiniPath& Road)
235{
236 Handle(MAT2d_Connexion) PrevC,CurC;
237 TColGeom2d_SequenceOfGeometry SetOfItem;
238 Standard_Integer NbConnexions;
239 Standard_Integer ILastItem;
240 Standard_Integer IndLast;
241 Standard_Integer i;
242
243 NbConnexions = Road.Path().Length();
244 //-----------------------------------------------------
245 // Depart du premier element de la ligne de reference.
246 //-----------------------------------------------------
247 PrevC = Road.Path().Value(1);
248 SubSequence(FigItem.Value(IndRefLine),
249 1,
250 PrevC->IndexItemOnFirst(),
251 geomElements);
252 UpDateLink(1,IndRefLine,1,PrevC->IndexItemOnFirst());
253 connexionMap.Bind(geomElements.Length()+1,PrevC);
254 ILastItem = geomElements.Length();
255
256 //-----------------------------------------------------------------------
257 // Ajout des portion de lignes delimites par deux connexions successives.
258 //-----------------------------------------------------------------------
259 for ( i = 2; i <= NbConnexions; i++) {
260 CurC = Road.Path().Value(i);
261 if (PassByLast(PrevC,CurC)) {
262 //------------------------------------------------------
263 // La portion passe par le dernier element de la ligne.
264 // - ajout de la portion de PrevC au dernier element
265 // de la ligne.
266 // - Si la ligne contient plus d'un element ajout de la
267 // portion du premier element de la ligne a CurC.
268 //------------------------------------------------------
269 IndLast = FigItem.Value(CurC->IndexFirstLine()).Length();
270 SubSequence (FigItem.Value(CurC->IndexFirstLine()),
271 PrevC->IndexItemOnSecond(),
272 IndLast,
273 SetOfItem);
274 UpDateLink(ILastItem+1,CurC->IndexFirstLine(),
275 PrevC->IndexItemOnSecond(),IndLast);
276 geomElements.Append(SetOfItem);
277 ILastItem = geomElements.Length();
278
279 if (FigItem.Value(CurC->IndexFirstLine()).Length() > 1) {
280 SubSequence(FigItem.Value(CurC->IndexFirstLine()),
281 1,
282 CurC->IndexItemOnFirst(),
283 SetOfItem);
284 UpDateLink(ILastItem+1,CurC->IndexFirstLine(),
285 1,CurC->IndexItemOnFirst());
286 geomElements.Append(SetOfItem);
287 ILastItem = geomElements.Length();
288 }
289 connexionMap.Bind(ILastItem+1,CurC);
290 }
291 else{
292
293 //------------------------------------------------------
294 // La portion ne passe par le dernier element de la ligne.
295 //------------------------------------------------------
296 SubSequence(FigItem.Value(CurC->IndexFirstLine()),
297 PrevC->IndexItemOnSecond(),
298 CurC ->IndexItemOnFirst(),
299 SetOfItem);
300 UpDateLink(ILastItem+1,CurC->IndexFirstLine(),
301 PrevC->IndexItemOnSecond(),CurC->IndexItemOnFirst());
302 geomElements.Append(SetOfItem);
303 ILastItem = geomElements.Length();
304 connexionMap.Bind(ILastItem+1,CurC);
305 }
306 PrevC = CurC;
307 }
308
309 //-------------------------------------------------------------
310 // Fermeture : de la derniere connexion au dernier element de la
311 // ligne de reference.
312 //-------------------------------------------------------------
313 IndLast = FigItem.Value(IndRefLine).Length();
314 if (IndLast == 1) {
315 connexionMap.Bind(1,CurC);
316 connexionMap.UnBind(ILastItem+1);
317 }
318 else {
319 SubSequence(FigItem.Value(IndRefLine),
320 PrevC->IndexItemOnSecond(),
321 IndLast,
322 SetOfItem);
323 UpDateLink(ILastItem+1,IndRefLine,PrevC->IndexItemOnSecond(),IndLast);
324 geomElements.Append(SetOfItem);
325 ILastItem = geomElements.Length();
326 }
327
328 //--------------------------------------
329 // Tri des RefToEqui pour chaque element.
330 //--------------------------------------
331 MAT2d_DataMapIteratorOfDataMapOfBiIntSequenceOfInteger Ite;
332
333 for ( Ite.Initialize(linkRefEqui); Ite.More(); Ite.Next()) {
334 if (Ite.Value().Length() > 1) {
335 SortRefToEqui(Ite.Key());
336 }
337 }
338
339#ifdef DEB
340 if (AffichCircuit) {
341 ILastItem = geomElements.Length();
342 for (i = 1; i <= ILastItem; i++) {
343 if (geomElements.Value(i)->DynamicType() != STANDARD_TYPE(Geom2d_CartesianPoint) ){
344 MAT2d_DrawCurve
345 (Handle(Geom2d_Curve)::DownCast(geomElements.Value(i)),2);
346 }
347 }
348 }
349#endif
350}
351
352//=============================================================================
353//function : InitOpen
354//purpose :
355//=============================================================================
356void MAT2d_Circuit::InitOpen (TColGeom2d_SequenceOfGeometry& Line) const
357{
358 Handle(Geom2d_TrimmedCurve) Curve;
359 Standard_Real DotProd;
360
361 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.First());
362 Line.InsertBefore(1,new Geom2d_CartesianPoint(Curve->StartPoint()));
363 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Last());
364 Line.Append(new Geom2d_CartesianPoint(Curve->EndPoint()));
365
366 for ( Standard_Integer i = 2; i <= Line.Length() - 2; i++) {
367 if ( Abs(CrossProd(Line.Value(i),Line.Value(i+1),DotProd)) > 1.E-8 ||
368 DotProd < 0. ) {
369 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(i));
370 Line.InsertAfter(i,new Geom2d_CartesianPoint(Curve->EndPoint()));
371 i++;
372 }
373 }
374}
375
376//=============================================================================
377//function : DoubleLine
378//purpose :
379//=============================================================================
380void MAT2d_Circuit::DoubleLine
381 ( TColGeom2d_SequenceOfGeometry& Line,
382 MAT2d_SequenceOfConnexion& ConnexionFrom,
383 const Handle(MAT2d_Connexion)& ConnexionFather,
384 const Standard_Real SideRef)
385const
386{
387 Handle(Standard_Type) Type;
388 Handle(Geom2d_TrimmedCurve) Curve;
389 Standard_Integer NbItems = Line.Length();
390 Standard_Integer i;
391 Standard_Real ProVec,DotProd;
392 Handle(MAT2d_Connexion) CC;
393
394 //--------------------------
395 // Completion de la ligne.
396 //--------------------------
397 for ( i = NbItems - 1; i > 1; i--){
398 Type = Line.Value(i)->DynamicType();
399 if ( Type == STANDARD_TYPE(Geom2d_CartesianPoint) ){
400 Line.Append(Line.Value(i));
401 }
402 else {
403 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(i)->Copy());
404 Curve->Reverse();
405 Line.Append(Curve);
406 }
407 }
408
409 //------------------------------------------
410 // Repartition des connexions sur la ligne
411 //------------------------------------------
412 Standard_Integer IAfter = ConnexionFrom.Length();
413 Standard_Integer NbConnexions = IAfter;
414 Standard_Integer IndCOF;
415
416 for (i = 1; i <= IAfter; i++) {
417 CC = ConnexionFrom.Value(i);
418 IndCOF = CC->IndexItemOnFirst();
419 Type = Line.Value(IndCOF)->DynamicType();
420
421 if ( Type == STANDARD_TYPE(Geom2d_CartesianPoint) ){
422 if (IndCOF!= NbItems && IndCOF!= 1) {
423 ProVec = CrossProd(Line.Value(IndCOF - 1),Line.Value(IndCOF + 1),DotProd);
424 if ((ProVec)*SideRef > 0){
425 CC->IndexItemOnFirst(2*NbItems - IndCOF);
426 ConnexionFrom.InsertAfter(IAfter,CC);
427 ConnexionFrom.Remove(i);
428 IAfter--;
429 i--;
430 }
431 }
432 }
433 else if (Side(CC,Line) != SideRef){
434 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(IndCOF));
435 CC->IndexItemOnFirst(2*NbItems - IndCOF);
436 CC->ParameterOnFirst(Curve->ReversedParameter(CC->ParameterOnFirst()));
437 ConnexionFrom.InsertAfter(IAfter,CC);
438 ConnexionFrom.Remove(i);
439 IAfter--;
440 i--;
441 }
442 }
443
444 //---------------------------
445 // Mise a jour connexion pere.
446 //---------------------------
447 if (!ConnexionFather.IsNull()) {
448 CC = ConnexionFather->Reverse();
449 IndCOF = CC->IndexItemOnFirst();
450 Type = Line.Value(IndCOF)->DynamicType();
451
452 if ( Type == STANDARD_TYPE(Geom2d_CartesianPoint) ){
453 if (IndCOF != NbItems && IndCOF != 1) {
454 ProVec = CrossProd(Line.Value(IndCOF - 1),Line.Value(IndCOF + 1),DotProd);
455 if ((ProVec)*SideRef > 0){
456 ConnexionFather->IndexItemOnSecond(2*NbItems - IndCOF);
457 }
458 }
459 }
460 else if (Side(CC,Line) != SideRef){
461 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(IndCOF));
462 ConnexionFather->IndexItemOnSecond(2*NbItems - IndCOF);
463 ConnexionFather->ParameterOnSecond
464 (Curve->ReversedParameter(ConnexionFather->ParameterOnSecond()));
465 }
466 }
467
468 //-------------------------------------
469 // Suppression des cassures rentrantes.
470 //-------------------------------------
471 Standard_Integer IndLine = 1;
472 Standard_Integer ICorres = 1;
473 TColStd_Array1OfInteger Corres(1,Line.Length());
474
475 while (Line.Value(IndLine) != Line.Last()){
476 Corres(ICorres) = IndLine;
477 Type = Line.Value(IndLine)->DynamicType();
478
479 if (Type == STANDARD_TYPE(Geom2d_CartesianPoint) &&
480 ICorres != 1 && ICorres != NbItems) {
481
482 if (!IsSharpCorner(Line.Value(IndLine - 1),
483 Line.Value(IndLine + 1),SideRef)){
484 Line.Remove(IndLine);
485 IndLine--;
486 Corres(ICorres) =0;
487 }
488 }
489 IndLine++;
490 ICorres++;
491 }
492 Corres(ICorres) = IndLine;
493
494 for (i = 1; i < 2*NbItems - 2; i++) {
495 if (Corres(i) == 0) Corres(i) = Corres(2*NbItems - i);
496 }
497
498#ifdef DEB
499 if (AffichCircuit) {
500 for (i = 1; i <= 2*NbItems - 2; i++) {
501 cout<< "Correspondance "<< i<<" -> "<<Corres(i)<<endl;
502 }
503 }
504#endif
505
506 //----------------------------
507 // Mise a jour des Connexions.
508 //----------------------------
509 for ( i = 1; i <= NbConnexions; i++){
510 CC = ConnexionFrom.ChangeValue(i);
511 CC->IndexItemOnFirst(Corres(CC->IndexItemOnFirst()));
512 }
513
514 if (!ConnexionFather.IsNull()) {
515 ConnexionFather
516 ->IndexItemOnSecond(Corres(ConnexionFather->IndexItemOnSecond()));
517 }
518}
519
520
521//=============================================================================
522//function : InsertCorner
523//purpose :
524//=============================================================================
525void MAT2d_Circuit::InsertCorner (TColGeom2d_SequenceOfGeometry& Line) const
526{
527 Standard_Integer i,isuiv;
528 Handle(Geom2d_TrimmedCurve) Curve;
529 Standard_Boolean Insert;
530
531 for ( i = 1; i <= Line.Length(); i++) {
532 isuiv = (i == Line.Length()) ? 1 : i + 1;
533 Insert = IsSharpCorner(Line.Value(i),Line.Value(isuiv),direction);
534
535#ifdef DEB
536 if (AffichCircuit) {
537 if (Insert) {
538 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(isuiv));
539 gp_Pnt2d P = Curve->StartPoint();
540#ifdef DRAW
541 Handle(Draw_Marker2D) dr = new Draw_Marker2D(P,Draw_Plus,Draw_vert);
542 dout << dr;
543 dout.Flush();
544#endif
545 }
546 }
547#endif
548
549 if (Insert) {
550 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(isuiv));
551 Line.InsertAfter(i,new Geom2d_CartesianPoint(Curve->StartPoint()));
552 i++;
553 }
554 }
555}
556
557//=============================================================================
558//function : NumberOfItem
559//purpose :
560//=============================================================================
561Standard_Integer MAT2d_Circuit::NumberOfItems()const
562{
563 return geomElements.Length();
564}
565
566//=============================================================================
567//function : LineLength
568//purpose :
569//=============================================================================
570Standard_Integer MAT2d_Circuit::LineLength(const Standard_Integer I) const
571{
572 return linesLength(I);
573}
574
575//=============================================================================
576//function : Value
577//purpose :
578//=============================================================================
579Handle(Geom2d_Geometry) MAT2d_Circuit::Value
580 (const Standard_Integer Index)const
581{
582 return geomElements.Value(Index);
583}
584
585//=============================================================================
586//function : RefToEqui
587//purpose :
588//=============================================================================
589const TColStd_SequenceOfInteger& MAT2d_Circuit::RefToEqui
590 (const Standard_Integer IndLine,
591 const Standard_Integer IndCurve) const
592{
593 MAT2d_BiInt Key(IndLine,IndCurve);
594 return linkRefEqui(Key);
595}
596
597//=============================================================================
598//function : SortRefToEqui
599//purpose :
600//=============================================================================
601void MAT2d_Circuit::SortRefToEqui (const MAT2d_BiInt& BiRef)
602{
603 Standard_Integer i;
604 TColStd_SequenceOfInteger& S = linkRefEqui.ChangeFind(BiRef);
605 TColStd_SequenceOfInteger SFin;
606
607 for( i = 1; i <= S.Length(); i++){
608 if (!ConnexionOn(S.Value(i))) break;
609 }
610 if ( i > 1 && i <= S.Length()) {
611 SFin = S;
612 SFin.Split(i,S);
613 S.Append(SFin);
614 }
615}
616
617//=============================================================================
618//function : Connexion
619//purpose :
620//=============================================================================
621Handle(MAT2d_Connexion) MAT2d_Circuit::Connexion(const Standard_Integer I)const
622{
623 return connexionMap(I);
624}
625
626//=============================================================================
627//function : ConnexionOn
628//purpose :
629//=============================================================================
630Standard_Boolean MAT2d_Circuit::ConnexionOn(const Standard_Integer I)const
631{
632 return connexionMap.IsBound(I);
633}
634
635//=============================================================================
636//function : Side
637//purpose :
638//=============================================================================
639Standard_Real MAT2d_Circuit::Side
640 (const Handle(MAT2d_Connexion)& C1,
641 const TColGeom2d_SequenceOfGeometry& Line)
642const
643{
644 Handle(Geom2d_TrimmedCurve) Curve;
645
646 gp_Vec2d Vect1(C1->PointOnSecond().X() - C1->PointOnFirst().X(),
647 C1->PointOnSecond().Y() - C1->PointOnFirst().Y());
648 Curve = Handle(Geom2d_TrimmedCurve)::DownCast
649 (Line.Value(C1->IndexItemOnFirst()));
650 gp_Vec2d Vect2 = Curve->DN(C1->ParameterOnFirst(),1);
651 if ( (Vect1^Vect2) > 0.) return - 1.; else return 1.;
652}
653
654//=============================================================================
655//function : PassByLast
656//purpose :
657//=============================================================================
658Standard_Boolean MAT2d_Circuit::PassByLast
659 (const Handle(MAT2d_Connexion)& C1,
660 const Handle(MAT2d_Connexion)& C2) const
661{
662 if (C2->IndexFirstLine() == C1->IndexSecondLine()){
663 if (C2->IndexItemOnFirst() < C1->IndexItemOnSecond()) {
664 return Standard_True;
665 }
666 else if (C2->IndexItemOnFirst() == C1->IndexItemOnSecond()) {
667 if (C1->IndexFirstLine() == C2->IndexSecondLine()) {
668 return Standard_True;
669 }
670 if (C2->ParameterOnFirst() == C1->ParameterOnSecond()) {
671 gp_Vec2d Vect1(C1->PointOnSecond(),C1->PointOnFirst());
672 gp_Vec2d Vect2(C2->PointOnFirst(),C2->PointOnSecond());
673 if ((Vect1^Vect2)*direction > 0) {
674 return Standard_True;
675 }
676 }
677 else if (C2->ParameterOnFirst() < C1->ParameterOnSecond()) {
678 return Standard_True;
679 }
680 }
681 }
682 return Standard_False;
683}
684
685//=============================================================================
686//function : UpDateLink
687//purpose :
688//=============================================================================
689void MAT2d_Circuit::UpDateLink(const Standard_Integer IFirst,
690 const Standard_Integer ILine,
691 const Standard_Integer ICurveFirst,
692 const Standard_Integer ICurveLast)
693{
694 Standard_Integer IEqui = IFirst;
695 Standard_Integer i;
696
697 for (i = ICurveFirst; i <= ICurveLast; i++) {
698 MAT2d_BiInt Key(ILine,i);
699 if (linkRefEqui.IsBound(Key)) {
700 linkRefEqui(Key).Append(IEqui);
701 }
702 else {
703 TColStd_SequenceOfInteger L;
704 linkRefEqui.Bind(Key,L);
705 linkRefEqui(Key).Append(IEqui);
706 }
707 IEqui++;
708 }
709}
710
711//==========================================================================
712//function : CrossProd
713//purpose : Calcul le produit vectoriel et scalaire entre les directions des
714// tangentes a la fin de Geom1 et au debut de Geom2.
715// Geom1 et Geom2 doivent etre des courbes.
716//==========================================================================
717static Standard_Real CrossProd(const Handle(Geom2d_Geometry)& Geom1,
718 const Handle(Geom2d_Geometry)& Geom2,
719 Standard_Real& DotProd)
720{
721 Handle(Geom2d_TrimmedCurve) Curve;
722
723 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Geom1);
724 gp_Dir2d Dir1(Curve->DN(Curve->LastParameter(),1));
725 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Geom2);
726 gp_Dir2d Dir2(Curve->DN(Curve->FirstParameter(),1));
727 DotProd = Dir1.Dot(Dir2);
728 return Dir1^Dir2;
729}
730
731
732//=======================================================================
733//function : IsSharpCorner
734//purpose : Return True Si le point commun entre <Geom1> et <Geom2> est
735// une cassure saillante par rapport <Direction>
736//=======================================================================
737
738static Standard_Boolean IsSharpCorner (const Handle(Geom2d_Geometry)& Geom1,
739 const Handle(Geom2d_Geometry)& Geom2,
740 const Standard_Real& Direction)
741{
742 Standard_Real DotProd;
743 Standard_Real ProVec = CrossProd (Geom1,Geom2,DotProd);
744 Standard_Integer NbTest = 1;
745 Standard_Real DU = Precision::Confusion();
746 Handle(Geom2d_TrimmedCurve) C1,C2;
747
748 C1= Handle(Geom2d_TrimmedCurve)::DownCast(Geom1);
749 C2= Handle(Geom2d_TrimmedCurve)::DownCast(Geom2);
750// Modified by Sergey KHROMOV - Thu Oct 24 19:02:46 2002 Begin
751// Add the same criterion as it is in MAT2d_Circuit::InitOpen(..)
752// Standard_Real TolAng = 1.E-5;
753 Standard_Real TolAng = 1.E-8;
754// Modified by Sergey KHROMOV - Thu Oct 24 19:02:47 2002 End
755
756 while (NbTest <= 10) {
757 if ((ProVec)*Direction < -TolAng)
758 return Standard_True; // Saillant.
759 if ((ProVec)*Direction > TolAng)
760 return Standard_False; // Rentrant.
761 else {
762 if (DotProd > 0) {
763 return Standard_False; // Plat.
764 }
765 TolAng = 1.E-8;
766 Standard_Real U1 = C1->LastParameter() - NbTest*DU;
767 Standard_Real U2 = C2->FirstParameter() + NbTest*DU;
768 gp_Dir2d Dir1(C1->DN(U1,1));
769 gp_Dir2d Dir2(C2->DN(U2,1));
770 DotProd = Dir1.Dot(Dir2);
771 ProVec = Dir1^Dir2;
772 NbTest++;
773 }
774 }
775
776
777
778 // Rebroussement.
779 // on calculde des paralleles aux deux courbes du cote du domaine
780 // de calcul
781 // Si pas dintersection => saillant.
782 // Sinon => rentrant.
783 Standard_Real D ;
784 Standard_Real Tol = Precision::Confusion();
785 Standard_Real MilC1 = (C1->LastParameter() + C1->FirstParameter())*0.5;
786 Standard_Real MilC2 = (C2->LastParameter() + C2->FirstParameter())*0.5;
787 gp_Pnt2d P = C1->Value(C1->LastParameter());
788 gp_Pnt2d P1 = C1->Value(MilC1);
789 gp_Pnt2d P2 = C2->Value(MilC2);
790
791 D = Min(P1.Distance(P),P2.Distance(P));
792 D /= 10;
793
794 if (Direction > 0.) D = -D;
795
796 Handle(Geom2dAdaptor_HCurve) HC1 = new Geom2dAdaptor_HCurve(C1);
797 Handle(Geom2dAdaptor_HCurve) HC2 = new Geom2dAdaptor_HCurve(C2);
798 Adaptor3d_OffsetCurve OC1(HC1,D,MilC1,C1->LastParameter());
799 Adaptor3d_OffsetCurve OC2(HC2,D,C2->FirstParameter(),MilC2);
800 Geom2dInt_GInter Intersect;
801 Intersect.Perform(OC1,OC2,Tol,Tol);
802
803#ifdef DEB
804 static Standard_Boolean Affich = 0;
805 if (Affich) {
806 Standard_Real DU1 = (OC1.LastParameter() - OC1.FirstParameter())/9.;
807 Standard_Real DU2 = (OC2.LastParameter() - OC2.FirstParameter())/9.;
808 for (Standard_Integer ki = 0; ki <= 9; ki++) {
809 gp_Pnt2d P1 = OC1.Value(OC1.FirstParameter()+ki*DU1);
810 gp_Pnt2d P2 = OC2.Value(OC2.FirstParameter()+ki*DU2);
811#ifdef DRAW
812 Handle(Draw_Marker2D) dr1 = new Draw_Marker2D(P1,Draw_Plus,Draw_vert);
813 Handle(Draw_Marker2D) dr2 = new Draw_Marker2D(P2,Draw_Plus,Draw_rouge);
814 dout << dr1;
815 dout << dr2;
816 }
817 dout.Flush();
818#else
819 }
820#endif
821
822 }
823#endif
824
825 if (Intersect.IsDone() && !Intersect.IsEmpty()) {
826 return Standard_False;
827 }
828 else {
829 return Standard_True;
830 }
7fd59977 831}
832
833
834
835#ifdef DEB
836//==========================================================================
837//function : MAT2d_DrawCurve
838//purpose : Affichage d une courbe <aCurve> de Geom2d. dans une couleur
839// definie par <Indice>.
840// Indice = 1 jaune,
841// Indice = 2 bleu,
842// Indice = 3 rouge,
843// Indice = 4 vert.
844//==========================================================================
845void MAT2d_DrawCurve(const Handle(Geom2d_Curve)& aCurve,
35e08fe8 846 const Standard_Integer /*Indice*/)
7fd59977 847{
848 Handle(Standard_Type) type = aCurve->DynamicType();
849 Handle(Geom2d_Curve) curve,CurveDraw;
850#ifdef DRAW
851 Handle(DrawTrSurf_Curve2d) dr;
852 Draw_Color Couleur;
853#endif
854
855 if (type == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
856 curve = Handle(Geom2d_TrimmedCurve)::DownCast(aCurve)->BasisCurve();
857 type = curve->DynamicType();
858 // PB de representation des courbes semi_infinies.
859 gp_Parab2d gpParabola;
860 gp_Hypr2d gpHyperbola;
861 Standard_Real Focus;
862 Standard_Real Limit = 50000.;
863 Standard_Real delta = 400;
864
865 // PB de representation des courbes semi_infinies.
866 if (aCurve->LastParameter() == Precision::Infinite()) {
867
868 if (type == STANDARD_TYPE(Geom2d_Parabola)) {
869 gpParabola = Handle(Geom2d_Parabola)::DownCast(curve)->Parab2d();
870 Focus = gpParabola.Focal();
871 Standard_Real Val1 = Sqrt(Limit*Focus);
872 Standard_Real Val2 = Sqrt(Limit*Limit);
873 delta= (Val1 <= Val2 ? Val1:Val2);
874 }
875 else if (type == STANDARD_TYPE(Geom2d_Hyperbola)) {
876 gpHyperbola = Handle(Geom2d_Hyperbola)::DownCast(curve)->Hypr2d();
877 Standard_Real Majr = gpHyperbola.MajorRadius();
878 Standard_Real Minr = gpHyperbola.MinorRadius();
879 Standard_Real Valu1 = Limit/Majr;
880 Standard_Real Valu2 = Limit/Minr;
881 Standard_Real Val1 = Log(Valu1+Sqrt(Valu1*Valu1-1));
882 Standard_Real Val2 = Log(Valu2+Sqrt(Valu2*Valu2+1));
883 delta = (Val1 <= Val2 ? Val1:Val2);
884 }
885 CurveDraw = new Geom2d_TrimmedCurve(aCurve,
886 aCurve->FirstParameter(),
887 aCurve->FirstParameter() + delta);
888 }
889 else {
890 CurveDraw = aCurve;
891 }
892 // fin PB.
893 }
894 else {
895 CurveDraw = aCurve;
896 }
897
898#ifdef DRAW
899 if (Indice == 1) Couleur = Draw_jaune;
900 else if (Indice == 2) Couleur = Draw_bleu;
901 else if (Indice == 3) Couleur = Draw_rouge;
902 else if (Indice == 4) Couleur = Draw_vert;
903
904 if (type == STANDARD_TYPE(Geom2d_Circle))
905 dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,30);
906 else if (type == STANDARD_TYPE(Geom2d_Line))
907 dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,2);
908 else
909 dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,500);
910
911 dout << dr;
912 dout.Flush();
913#endif
914}
915
916#endif
917