1 // Created on: 1993-11-19
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <Adaptor2d_OffsetCurve.hxx>
18 #include <Geom2d_CartesianPoint.hxx>
19 #include <Geom2d_Geometry.hxx>
20 #include <Geom2d_TrimmedCurve.hxx>
21 #include <Geom2dAdaptor_Curve.hxx>
22 #include <Geom2dInt_GInter.hxx>
23 #include <MAT2d_Circuit.hxx>
24 #include <MAT2d_Connexion.hxx>
25 #include <MAT2d_DataMapOfBiIntSequenceOfInteger.hxx>
26 #include <MAT2d_MiniPath.hxx>
27 #include <MAT2d_SequenceOfConnexion.hxx>
28 #include <MAT2d_SequenceOfSequenceOfGeometry.hxx>
29 #include <Precision.hxx>
30 #include <Standard_Type.hxx>
31 #include <TColStd_Array1OfBoolean.hxx>
32 #include <TColStd_Array1OfInteger.hxx>
33 #include <TColStd_SequenceOfInteger.hxx>
35 IMPLEMENT_STANDARD_RTTIEXT(MAT2d_Circuit,Standard_Transient)
38 #include <GCE2d_MakeSegment.hxx>
39 #include <Geom2d_Curve.hxx>
40 #include <Geom2d_Parabola.hxx>
41 #include <Geom2d_Hyperbola.hxx>
42 #include <Geom2d_TrimmedCurve.hxx>
43 #include <Geom2d_CartesianPoint.hxx>
44 #include <Geom2d_Line.hxx>
45 #include <Geom2d_Circle.hxx>
49 #include <Draw_Appli.hxx>
50 #include <DrawTrSurf_Curve2d.hxx>
51 #include <Draw_Marker2D.hxx>
52 static Handle(DrawTrSurf_Curve2d) draw;
53 Standard_EXPORT Draw_Viewer dout;
56 static void MAT2d_DrawCurve(const Handle(Geom2d_Curve)& aCurve,
57 const Standard_Integer Indice);
58 static Standard_Boolean AffichCircuit = 0;
63 static Standard_Real CrossProd(const Handle(Geom2d_Geometry)& Geom1,
64 const Handle(Geom2d_Geometry)& Geom2,
65 Standard_Real& DotProd);
68 //=============================================================================
69 //function : Constructor
71 //=============================================================================
72 MAT2d_Circuit::MAT2d_Circuit(const GeomAbs_JoinType aJoinType,
73 const Standard_Boolean IsOpenResult)
76 myJoinType = aJoinType;
77 myIsOpenResult = IsOpenResult;
80 //=============================================================================
83 //=============================================================================
84 void MAT2d_Circuit::Perform
85 ( MAT2d_SequenceOfSequenceOfGeometry& FigItem,
86 const TColStd_SequenceOfBoolean & IsClosed,
87 const Standard_Integer IndRefLine,
88 const Standard_Boolean Trigo)
90 Standard_Integer NbLines = FigItem.Length();
92 TColStd_Array1OfBoolean Open(1,NbLines);
93 MAT2d_SequenceOfConnexion SVide;
94 Handle(MAT2d_Connexion) ConnexionNul;
96 if (Trigo) direction = 1.; else direction = -1.;
98 //---------------------
99 // Reinitialisation SD.
100 //---------------------
101 geomElements.Clear();
102 connexionMap.Clear();
106 //----------------------------
107 // Detection Lignes ouvertes.
108 //----------------------------
109 for ( i = 1; i <= NbLines; i++) {
110 Handle(Geom2d_TrimmedCurve) Curve;
111 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(FigItem.Value(i).First());
112 gp_Pnt2d P1 = Curve->StartPoint();
113 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(FigItem.Value(i).Last());
114 gp_Pnt2d P2 = Curve->EndPoint();
115 // Modified by Sergey KHROMOV - Wed Mar 6 16:59:01 2002 Begin
116 // if ( P1.IsEqual(P2,Precision::Confusion())) Open(i) = Standard_False;
117 // else Open(i) = Standard_True;
118 if (IsClosed(i)) Open(i) = Standard_False;
119 else if (P1.IsEqual(P2,Precision::Confusion())) Open(i) = Standard_False;
120 else Open(i) = Standard_True;
121 // Modified by Sergey KHROMOV - Wed Mar 6 16:59:04 2002 End
124 //---------------------------------------------------------------
125 // Insertion des cassures saillantes ou
126 // ajout des extremites de chaque courbe si la ligne est ouverte.
127 //---------------------------------------------------------------
128 for ( i = 1; i <= NbLines; i++) {
130 InitOpen(FigItem.ChangeValue(i));
131 linesLength.Append(FigItem.Value(i).Length());
134 InsertCorner(FigItem.ChangeValue(i));
135 linesLength.Append(FigItem.Value(i).Length());
139 //---------------------------------
140 // Une seule ligne => Rien a faire.
141 //---------------------------------
144 DoubleLine(FigItem.ChangeValue(1),SVide,ConnexionNul,direction);
145 linesLength.SetValue(1,FigItem.Value(1).Length());
147 geomElements = FigItem.Value(1);
148 UpDateLink(1,1,1,geomElements.Length());
149 linesLength.Append(FigItem.Value(1).Length());
157 //---------------------------------------------------------
158 // Calcul de l ensemble des connexions realisant le chemin.
159 //---------------------------------------------------------
161 Road.Perform(FigItem,IndRefLine,Trigo);
163 //------------------------
164 // Fermeture ligne ouverte.
165 //-------------------------
166 for ( i = 1; i <= NbLines; i++) {
168 Handle(MAT2d_Connexion) CF;
169 if (Road.IsRoot(i)) CF = ConnexionNul; else CF = Road.Father(i);
170 if (Road.IsConnexionsFrom(i)) {
171 DoubleLine(FigItem.ChangeValue(i),Road.ConnexionsFrom(i),
175 DoubleLine(FigItem.ChangeValue(i),SVide,CF,direction);
177 linesLength.SetValue(i,FigItem.Value(i).Length());
181 //------------------------
182 // Construction du chemin.
183 //------------------------
184 Road.RunOnConnexions();
188 Standard_Integer NbConnexions = Road.Path().Length();
189 for (i = 1; i <= NbConnexions; i++) {
190 Handle(Geom2d_TrimmedCurve) edge;
191 edge = GCE2d_MakeSegment(Road.Path().Value(i)->PointOnFirst(),
192 Road.Path().Value(i)->PointOnSecond());
193 MAT2d_DrawCurve(edge,2);
198 //-------------------------
199 // Construction du Circuit.
200 //-------------------------
201 ConstructCircuit(FigItem,IndRefLine,Road);
204 //=======================================================================
205 //function : IsSharpCorner
206 //purpose : Return True Si le point commun entre <Geom1> et <Geom2> est
207 // une cassure saillante par rapport <Direction>
208 //=======================================================================
210 Standard_Boolean MAT2d_Circuit::IsSharpCorner(const Handle(Geom2d_Geometry)& Geom1,
211 const Handle(Geom2d_Geometry)& Geom2,
212 const Standard_Real Direction) const
214 Standard_Real DotProd;
215 Standard_Real ProVec = CrossProd (Geom1,Geom2,DotProd);
216 Standard_Integer NbTest = 1;
217 Standard_Real DU = Precision::Confusion();
218 Handle(Geom2d_TrimmedCurve) C1,C2;
220 C1= Handle(Geom2d_TrimmedCurve)::DownCast(Geom1);
221 C2= Handle(Geom2d_TrimmedCurve)::DownCast(Geom2);
222 // Modified by Sergey KHROMOV - Thu Oct 24 19:02:46 2002 Begin
223 // Add the same criterion as it is in MAT2d_Circuit::InitOpen(..)
224 // Standard_Real TolAng = 1.E-5;
225 Standard_Real TolAng = 1.E-8;
226 // Modified by Sergey KHROMOV - Thu Oct 24 19:02:47 2002 End
228 if (myJoinType == GeomAbs_Arc)
230 while (NbTest <= 10) {
231 if ((ProVec)*Direction < -TolAng)
232 return Standard_True; // Saillant.
233 if ((ProVec)*Direction > TolAng)
234 return Standard_False; // Rentrant.
237 return Standard_False; // Plat.
240 Standard_Real U1 = C1->LastParameter() - NbTest*DU;
241 Standard_Real U2 = C2->FirstParameter() + NbTest*DU;
242 gp_Dir2d Dir1(C1->DN(U1,1));
243 gp_Dir2d Dir2(C2->DN(U2,1));
244 DotProd = Dir1.Dot(Dir2);
253 // on calculde des paralleles aux deux courbes du cote du domaine
255 // Si pas dintersection => saillant.
256 // Sinon => rentrant.
258 Standard_Real Tol = Precision::Confusion();
259 Standard_Real MilC1 = (C1->LastParameter() + C1->FirstParameter())*0.5;
260 Standard_Real MilC2 = (C2->LastParameter() + C2->FirstParameter())*0.5;
261 gp_Pnt2d P = C1->Value(C1->LastParameter());
262 gp_Pnt2d P1 = C1->Value(MilC1);
263 gp_Pnt2d P2 = C2->Value(MilC2);
265 D = Min(P1.Distance(P),P2.Distance(P));
268 if (Direction < 0.) D = -D;
270 Handle(Geom2dAdaptor_Curve) HC1 = new Geom2dAdaptor_Curve(C1);
271 Handle(Geom2dAdaptor_Curve) HC2 = new Geom2dAdaptor_Curve(C2);
272 Adaptor2d_OffsetCurve OC1(HC1, D, MilC1, C1->LastParameter());
273 Adaptor2d_OffsetCurve OC2(HC2, D, C2->FirstParameter(), MilC2);
274 Geom2dInt_GInter Intersect;
275 Intersect.Perform(OC1,OC2,Tol,Tol);
278 static Standard_Boolean Affich = 0;
281 Standard_Real DU1 = (OC1.LastParameter() - OC1.FirstParameter())/9.;
282 Standard_Real DU2 = (OC2.LastParameter() - OC2.FirstParameter())/9.;
283 for (Standard_Integer ki = 0; ki <= 9; ki++) {
284 gp_Pnt2d P1 = OC1.Value(OC1.FirstParameter()+ki*DU1);
285 gp_Pnt2d P2 = OC2.Value(OC2.FirstParameter()+ki*DU2);
286 Handle(Draw_Marker2D) dr1 = new Draw_Marker2D(P1,Draw_Plus,Draw_vert);
287 Handle(Draw_Marker2D) dr2 = new Draw_Marker2D(P2,Draw_Plus,Draw_rouge);
296 if (Intersect.IsDone() && !Intersect.IsEmpty()) {
297 return Standard_False;
300 return Standard_True;
302 } //end of if (myJoinType == GeomAbs_Arc)
303 else if (myJoinType == GeomAbs_Intersection)
305 if (Abs(ProVec) <= TolAng &&
310 Standard_Real U1 = C1->LastParameter() - NbTest*DU;
311 Standard_Real U2 = C2->FirstParameter() + NbTest*DU;
312 gp_Dir2d Dir1(C1->DN(U1,1));
313 gp_Dir2d Dir2(C2->DN(U2,1));
314 DotProd = Dir1.Dot(Dir2);
316 if ((ProVec)*Direction < -TolAng)
317 return Standard_True; // Saillant.
318 if ((ProVec)*Direction > TolAng)
319 return Standard_False; // Rentrant.
323 return Standard_False;
326 return Standard_False;
328 return Standard_False;
331 //=======================================================================
332 //function : SubSequence
334 //=======================================================================
335 static void SubSequence(const TColGeom2d_SequenceOfGeometry& S1,
338 TColGeom2d_SequenceOfGeometry& S2)
341 for (Standard_Integer i = IF; i<= IL; i++){
342 S2.Append(S1.Value(i));
347 //=============================================================================
348 //function : ConstructCircuit
350 //=============================================================================
351 void MAT2d_Circuit::ConstructCircuit
352 (const MAT2d_SequenceOfSequenceOfGeometry& FigItem,
353 const Standard_Integer IndRefLine,
354 const MAT2d_MiniPath& Road)
356 Handle(MAT2d_Connexion) PrevC,CurC;
357 TColGeom2d_SequenceOfGeometry SetOfItem;
358 Standard_Integer NbConnexions;
359 Standard_Integer ILastItem;
360 Standard_Integer IndLast;
363 NbConnexions = Road.Path().Length();
364 //-----------------------------------------------------
365 // Depart du premier element de la ligne de reference.
366 //-----------------------------------------------------
367 PrevC = Road.Path().Value(1);
368 SubSequence(FigItem.Value(IndRefLine),
370 PrevC->IndexItemOnFirst(),
372 UpDateLink(1,IndRefLine,1,PrevC->IndexItemOnFirst());
373 connexionMap.Bind(geomElements.Length()+1,PrevC);
374 ILastItem = geomElements.Length();
376 //-----------------------------------------------------------------------
377 // Ajout des portion de lignes delimites par deux connexions successives.
378 //-----------------------------------------------------------------------
379 for ( i = 2; i <= NbConnexions; i++) {
380 CurC = Road.Path().Value(i);
381 if (PassByLast(PrevC,CurC)) {
382 //------------------------------------------------------
383 // La portion passe par le dernier element de la ligne.
384 // - ajout de la portion de PrevC au dernier element
386 // - Si la ligne contient plus d'un element ajout de la
387 // portion du premier element de la ligne a CurC.
388 //------------------------------------------------------
389 IndLast = FigItem.Value(CurC->IndexFirstLine()).Length();
390 SubSequence (FigItem.Value(CurC->IndexFirstLine()),
391 PrevC->IndexItemOnSecond(),
394 UpDateLink(ILastItem+1,CurC->IndexFirstLine(),
395 PrevC->IndexItemOnSecond(),IndLast);
396 geomElements.Append(SetOfItem);
397 ILastItem = geomElements.Length();
399 if (FigItem.Value(CurC->IndexFirstLine()).Length() > 1) {
400 SubSequence(FigItem.Value(CurC->IndexFirstLine()),
402 CurC->IndexItemOnFirst(),
404 UpDateLink(ILastItem+1,CurC->IndexFirstLine(),
405 1,CurC->IndexItemOnFirst());
406 geomElements.Append(SetOfItem);
407 ILastItem = geomElements.Length();
409 connexionMap.Bind(ILastItem+1,CurC);
413 //------------------------------------------------------
414 // La portion ne passe par le dernier element de la ligne.
415 //------------------------------------------------------
416 SubSequence(FigItem.Value(CurC->IndexFirstLine()),
417 PrevC->IndexItemOnSecond(),
418 CurC ->IndexItemOnFirst(),
420 UpDateLink(ILastItem+1,CurC->IndexFirstLine(),
421 PrevC->IndexItemOnSecond(),CurC->IndexItemOnFirst());
422 geomElements.Append(SetOfItem);
423 ILastItem = geomElements.Length();
424 connexionMap.Bind(ILastItem+1,CurC);
429 //-------------------------------------------------------------
430 // Fermeture : de la derniere connexion au dernier element de la
431 // ligne de reference.
432 //-------------------------------------------------------------
433 IndLast = FigItem.Value(IndRefLine).Length();
435 connexionMap.Bind(1,CurC);
436 connexionMap.UnBind(ILastItem+1);
439 SubSequence(FigItem.Value(IndRefLine),
440 PrevC->IndexItemOnSecond(),
443 UpDateLink(ILastItem+1,IndRefLine,PrevC->IndexItemOnSecond(),IndLast);
444 geomElements.Append(SetOfItem);
445 ILastItem = geomElements.Length();
448 //--------------------------------------
449 // Tri des RefToEqui pour chaque element.
450 //--------------------------------------
451 MAT2d_DataMapIteratorOfDataMapOfBiIntSequenceOfInteger Ite;
453 for ( Ite.Initialize(linkRefEqui); Ite.More(); Ite.Next()) {
454 if (Ite.Value().Length() > 1) {
455 SortRefToEqui(Ite.Key());
461 ILastItem = geomElements.Length();
462 for (i = 1; i <= ILastItem; i++) {
463 if (geomElements.Value(i)->DynamicType() != STANDARD_TYPE(Geom2d_CartesianPoint) ){
465 (Handle(Geom2d_Curve)::DownCast(geomElements.Value(i)),2);
472 //=============================================================================
473 //function : InitOpen
475 //=============================================================================
476 void MAT2d_Circuit::InitOpen (TColGeom2d_SequenceOfGeometry& Line) const
478 Handle(Geom2d_TrimmedCurve) Curve;
479 Standard_Real DotProd;
481 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.First());
482 Line.InsertBefore(1,new Geom2d_CartesianPoint(Curve->StartPoint()));
483 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Last());
484 Line.Append(new Geom2d_CartesianPoint(Curve->EndPoint()));
486 for ( Standard_Integer i = 2; i <= Line.Length() - 2; i++) {
487 if ( Abs(CrossProd(Line.Value(i),Line.Value(i+1),DotProd)) > 1.E-8 ||
489 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(i));
490 Line.InsertAfter(i,new Geom2d_CartesianPoint(Curve->EndPoint()));
496 //=============================================================================
497 //function : DoubleLine
499 //=============================================================================
500 void MAT2d_Circuit::DoubleLine
501 ( TColGeom2d_SequenceOfGeometry& Line,
502 MAT2d_SequenceOfConnexion& ConnexionFrom,
503 const Handle(MAT2d_Connexion)& ConnexionFather,
504 const Standard_Real SideRef)
507 Handle(Standard_Type) Type;
508 Handle(Geom2d_TrimmedCurve) Curve;
509 Standard_Integer NbItems = Line.Length();
511 Standard_Real ProVec,DotProd;
512 Handle(MAT2d_Connexion) CC;
514 //--------------------------
515 // Completion de la ligne.
516 //--------------------------
519 for ( i = NbItems - 1; i > 1; i--){
520 Type = Line.Value(i)->DynamicType();
521 if ( Type == STANDARD_TYPE(Geom2d_CartesianPoint) ){
522 Line.Append(Line.Value(i));
525 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(i)->Copy());
532 //------------------------------------------
533 // Repartition des connexions sur la ligne
534 //------------------------------------------
535 Standard_Integer IAfter = ConnexionFrom.Length();
536 Standard_Integer NbConnexions = IAfter;
537 Standard_Integer IndCOF;
539 for (i = 1; i <= IAfter; i++) {
540 CC = ConnexionFrom.Value(i);
541 IndCOF = CC->IndexItemOnFirst();
542 Type = Line.Value(IndCOF)->DynamicType();
544 if ( Type == STANDARD_TYPE(Geom2d_CartesianPoint) ){
545 if (IndCOF!= NbItems && IndCOF!= 1) {
546 ProVec = CrossProd(Line.Value(IndCOF - 1),Line.Value(IndCOF + 1),DotProd);
547 if ((ProVec)*SideRef > 0){
548 CC->IndexItemOnFirst(2*NbItems - IndCOF);
549 ConnexionFrom.InsertAfter(IAfter,CC);
550 ConnexionFrom.Remove(i);
556 else if (Side(CC,Line) != SideRef){
557 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(IndCOF));
558 CC->IndexItemOnFirst(2*NbItems - IndCOF);
559 CC->ParameterOnFirst(Curve->ReversedParameter(CC->ParameterOnFirst()));
560 ConnexionFrom.InsertAfter(IAfter,CC);
561 ConnexionFrom.Remove(i);
567 //---------------------------
568 // Mise a jour connexion pere.
569 //---------------------------
570 if (!ConnexionFather.IsNull()) {
571 CC = ConnexionFather->Reverse();
572 IndCOF = CC->IndexItemOnFirst();
573 Type = Line.Value(IndCOF)->DynamicType();
575 if ( Type == STANDARD_TYPE(Geom2d_CartesianPoint) ){
576 if (IndCOF != NbItems && IndCOF != 1) {
577 ProVec = CrossProd(Line.Value(IndCOF - 1),Line.Value(IndCOF + 1),DotProd);
578 if ((ProVec)*SideRef > 0){
579 ConnexionFather->IndexItemOnSecond(2*NbItems - IndCOF);
583 else if (Side(CC,Line) != SideRef){
584 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(IndCOF));
585 ConnexionFather->IndexItemOnSecond(2*NbItems - IndCOF);
586 ConnexionFather->ParameterOnSecond
587 (Curve->ReversedParameter(ConnexionFather->ParameterOnSecond()));
591 //-------------------------------------
592 // Suppression des cassures rentrantes.
593 //-------------------------------------
594 Standard_Integer IndLine = 1;
595 Standard_Integer ICorres = 1;
596 TColStd_Array1OfInteger Corres(1,Line.Length());
598 while (Line.Value(IndLine) != Line.Last()){
599 Corres(ICorres) = IndLine;
600 Type = Line.Value(IndLine)->DynamicType();
602 if (Type == STANDARD_TYPE(Geom2d_CartesianPoint) &&
603 ICorres != 1 && ICorres != NbItems) {
605 if (!IsSharpCorner(Line.Value(IndLine - 1),
606 Line.Value(IndLine + 1),SideRef)){
607 Line.Remove(IndLine);
615 Corres(ICorres) = IndLine;
619 for (i = 1; i < 2*NbItems - 2; i++) {
621 Corres(i) = Corres(2*NbItems - i);
626 for (i = 1; i <= 2*NbItems - 2; i++) {
627 std::cout<< "Correspondance "<< i<<" -> "<<Corres(i)<<std::endl;
632 //----------------------------
633 // Mise a jour des Connexions.
634 //----------------------------
635 for ( i = 1; i <= NbConnexions; i++){
636 CC = ConnexionFrom.ChangeValue(i);
637 CC->IndexItemOnFirst(Corres(CC->IndexItemOnFirst()));
640 if (!ConnexionFather.IsNull()) {
642 ->IndexItemOnSecond(Corres(ConnexionFather->IndexItemOnSecond()));
648 //=============================================================================
649 //function : InsertCorner
651 //=============================================================================
652 void MAT2d_Circuit::InsertCorner (TColGeom2d_SequenceOfGeometry& Line) const
654 Standard_Integer i,isuiv;
655 Handle(Geom2d_TrimmedCurve) Curve;
656 Standard_Boolean Insert;
658 for ( i = 1; i <= Line.Length(); i++) {
659 isuiv = (i == Line.Length()) ? 1 : i + 1;
660 Insert = IsSharpCorner(Line.Value(i),Line.Value(isuiv),direction);
665 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(isuiv));
667 gp_Pnt2d P = Curve->StartPoint();
668 Handle(Draw_Marker2D) dr = new Draw_Marker2D(P,Draw_Plus,Draw_vert);
677 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(isuiv));
678 Line.InsertAfter(i,new Geom2d_CartesianPoint(Curve->StartPoint()));
684 //=============================================================================
685 //function : NumberOfItem
687 //=============================================================================
688 Standard_Integer MAT2d_Circuit::NumberOfItems()const
690 return geomElements.Length();
693 //=============================================================================
694 //function : LineLength
696 //=============================================================================
697 Standard_Integer MAT2d_Circuit::LineLength(const Standard_Integer I) const
699 return linesLength(I);
702 //=============================================================================
705 //=============================================================================
706 Handle(Geom2d_Geometry) MAT2d_Circuit::Value
707 (const Standard_Integer Index)const
709 return geomElements.Value(Index);
712 //=============================================================================
713 //function : RefToEqui
715 //=============================================================================
716 const TColStd_SequenceOfInteger& MAT2d_Circuit::RefToEqui
717 (const Standard_Integer IndLine,
718 const Standard_Integer IndCurve) const
720 MAT2d_BiInt Key(IndLine,IndCurve);
721 return linkRefEqui(Key);
724 //=============================================================================
725 //function : SortRefToEqui
727 //=============================================================================
728 void MAT2d_Circuit::SortRefToEqui (const MAT2d_BiInt& BiRef)
731 TColStd_SequenceOfInteger& S = linkRefEqui.ChangeFind(BiRef);
732 TColStd_SequenceOfInteger SFin;
734 for( i = 1; i <= S.Length(); i++){
735 if (!ConnexionOn(S.Value(i))) break;
737 if ( i > 1 && i <= S.Length()) {
744 //=============================================================================
745 //function : Connexion
747 //=============================================================================
748 Handle(MAT2d_Connexion) MAT2d_Circuit::Connexion(const Standard_Integer I)const
750 return connexionMap(I);
753 //=============================================================================
754 //function : ConnexionOn
756 //=============================================================================
757 Standard_Boolean MAT2d_Circuit::ConnexionOn(const Standard_Integer I)const
759 return connexionMap.IsBound(I);
762 //=============================================================================
765 //=============================================================================
766 Standard_Real MAT2d_Circuit::Side
767 (const Handle(MAT2d_Connexion)& C1,
768 const TColGeom2d_SequenceOfGeometry& Line)
771 Handle(Geom2d_TrimmedCurve) Curve;
773 gp_Vec2d Vect1(C1->PointOnSecond().X() - C1->PointOnFirst().X(),
774 C1->PointOnSecond().Y() - C1->PointOnFirst().Y());
775 Curve = Handle(Geom2d_TrimmedCurve)::DownCast
776 (Line.Value(C1->IndexItemOnFirst()));
777 gp_Vec2d Vect2 = Curve->DN(C1->ParameterOnFirst(),1);
778 if ( (Vect1^Vect2) > 0.) return - 1.; else return 1.;
781 //=============================================================================
782 //function : PassByLast
784 //=============================================================================
785 Standard_Boolean MAT2d_Circuit::PassByLast
786 (const Handle(MAT2d_Connexion)& C1,
787 const Handle(MAT2d_Connexion)& C2) const
789 if (C2->IndexFirstLine() == C1->IndexSecondLine()){
790 if (C2->IndexItemOnFirst() < C1->IndexItemOnSecond()) {
791 return Standard_True;
793 else if (C2->IndexItemOnFirst() == C1->IndexItemOnSecond()) {
794 if (C1->IndexFirstLine() == C2->IndexSecondLine()) {
795 return Standard_True;
797 if (C2->ParameterOnFirst() == C1->ParameterOnSecond()) {
798 gp_Vec2d Vect1(C1->PointOnSecond(),C1->PointOnFirst());
799 gp_Vec2d Vect2(C2->PointOnFirst(),C2->PointOnSecond());
800 if ((Vect1^Vect2)*direction > 0) {
801 return Standard_True;
804 else if (C2->ParameterOnFirst() < C1->ParameterOnSecond()) {
805 return Standard_True;
809 return Standard_False;
812 //=============================================================================
813 //function : UpDateLink
815 //=============================================================================
816 void MAT2d_Circuit::UpDateLink(const Standard_Integer IFirst,
817 const Standard_Integer ILine,
818 const Standard_Integer ICurveFirst,
819 const Standard_Integer ICurveLast)
821 Standard_Integer IEqui = IFirst;
824 for (i = ICurveFirst; i <= ICurveLast; i++) {
825 MAT2d_BiInt Key(ILine,i);
826 if (linkRefEqui.IsBound(Key)) {
827 linkRefEqui(Key).Append(IEqui);
830 TColStd_SequenceOfInteger L;
831 linkRefEqui.Bind(Key,L);
832 linkRefEqui(Key).Append(IEqui);
838 //==========================================================================
839 //function : CrossProd
840 //purpose : Calcul le produit vectoriel et scalaire entre les directions des
841 // tangentes a la fin de Geom1 et au debut de Geom2.
842 // Geom1 et Geom2 doivent etre des courbes.
843 //==========================================================================
844 static Standard_Real CrossProd(const Handle(Geom2d_Geometry)& Geom1,
845 const Handle(Geom2d_Geometry)& Geom2,
846 Standard_Real& DotProd)
848 Handle(Geom2d_TrimmedCurve) Curve;
850 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Geom1);
851 gp_Dir2d Dir1(Curve->DN(Curve->LastParameter(),1));
852 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Geom2);
853 gp_Dir2d Dir2(Curve->DN(Curve->FirstParameter(),1));
854 DotProd = Dir1.Dot(Dir2);
863 //==========================================================================
864 //function : MAT2d_DrawCurve
865 //purpose : Affichage d une courbe <aCurve> de Geom2d. dans une couleur
866 // definie par <Indice>.
871 //==========================================================================
872 void MAT2d_DrawCurve(const Handle(Geom2d_Curve)& aCurve,
873 const Standard_Integer /*Indice*/)
875 Handle(Standard_Type) type = aCurve->DynamicType();
876 Handle(Geom2d_Curve) curve,CurveDraw;
878 Handle(DrawTrSurf_Curve2d) dr;
882 if (type == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
883 curve = Handle(Geom2d_TrimmedCurve)::DownCast(aCurve)->BasisCurve();
884 type = curve->DynamicType();
885 // PB de representation des courbes semi_infinies.
886 gp_Parab2d gpParabola;
887 gp_Hypr2d gpHyperbola;
889 Standard_Real Limit = 50000.;
890 Standard_Real delta = 400;
892 // PB de representation des courbes semi_infinies.
893 if (aCurve->LastParameter() == Precision::Infinite()) {
895 if (type == STANDARD_TYPE(Geom2d_Parabola)) {
896 gpParabola = Handle(Geom2d_Parabola)::DownCast(curve)->Parab2d();
897 Focus = gpParabola.Focal();
898 Standard_Real Val1 = Sqrt(Limit*Focus);
899 Standard_Real Val2 = Sqrt(Limit*Limit);
900 delta= (Val1 <= Val2 ? Val1:Val2);
902 else if (type == STANDARD_TYPE(Geom2d_Hyperbola)) {
903 gpHyperbola = Handle(Geom2d_Hyperbola)::DownCast(curve)->Hypr2d();
904 Standard_Real Majr = gpHyperbola.MajorRadius();
905 Standard_Real Minr = gpHyperbola.MinorRadius();
906 Standard_Real Valu1 = Limit/Majr;
907 Standard_Real Valu2 = Limit/Minr;
908 Standard_Real Val1 = Log(Valu1+Sqrt(Valu1*Valu1-1));
909 Standard_Real Val2 = Log(Valu2+Sqrt(Valu2*Valu2+1));
910 delta = (Val1 <= Val2 ? Val1:Val2);
912 CurveDraw = new Geom2d_TrimmedCurve(aCurve,
913 aCurve->FirstParameter(),
914 aCurve->FirstParameter() + delta);
926 if (Indice == 1) Couleur = Draw_jaune;
927 else if (Indice == 2) Couleur = Draw_bleu;
928 else if (Indice == 3) Couleur = Draw_rouge;
929 else if (Indice == 4) Couleur = Draw_vert;
931 if (type == STANDARD_TYPE(Geom2d_Circle))
932 dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,30);
933 else if (type == STANDARD_TYPE(Geom2d_Line))
934 dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,2);
936 dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,500);