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
9 // under the terms of the GNU Lesser General Public 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.
18 #include <Draw_Appli.hxx>
19 #include <DrawTrSurf_Curve2d.hxx>
20 #include <Draw_Marker2D.hxx>
23 #include <GCE2d_MakeSegment.hxx>
24 #include <Geom2d_Curve.hxx>
25 #include <Geom2d_Parabola.hxx>
26 #include <Geom2d_Hyperbola.hxx>
27 #include <Geom2d_TrimmedCurve.hxx>
28 #include <Geom2d_CartesianPoint.hxx>
29 #include <Geom2d_Line.hxx>
30 #include <Geom2d_Circle.hxx>
33 #include <MAT2d_Circuit.ixx>
34 #include <Geom2d_TrimmedCurve.hxx>
35 #include <Geom2d_CartesianPoint.hxx>
36 #include <Geom2d_Geometry.hxx>
37 #include <TColStd_SequenceOfInteger.hxx>
38 #include <TColStd_Array1OfBoolean.hxx>
39 #include <TColStd_Array1OfInteger.hxx>
40 #include <MAT2d_BiInt.hxx>
41 #include <MAT2d_MiniPath.hxx>
42 #include <MAT2d_Connexion.hxx>
43 #include <MAT2d_SequenceOfConnexion.hxx>
44 #include <MAT2d_DataMapOfIntegerConnexion.hxx>
45 #include <MAT2d_SequenceOfSequenceOfGeometry.hxx>
46 #include <MAT2d_DataMapOfBiIntSequenceOfInteger.hxx>
47 #include <MAT2d_DataMapIteratorOfDataMapOfBiIntSequenceOfInteger.hxx>
48 #include <Precision.hxx>
49 #include <Adaptor3d_OffsetCurve.hxx>
50 #include <Geom2dInt_GInter.hxx>
51 #include <Geom2dAdaptor_HCurve.hxx>
52 #include <IntRes2d_IntersectionPoint.hxx>
55 static Handle(DrawTrSurf_Curve2d) draw;
56 Standard_EXPORT Draw_Viewer dout;
59 static void MAT2d_DrawCurve(const Handle(Geom2d_Curve)& aCurve,
60 const Standard_Integer Indice);
61 static Standard_Boolean AffichCircuit = 0;
66 static Standard_Real CrossProd(const Handle(Geom2d_Geometry)& Geom1,
67 const Handle(Geom2d_Geometry)& Geom2,
68 Standard_Real& DotProd);
70 static Standard_Boolean IsSharpCorner (const Handle(Geom2d_Geometry)& Geom1,
71 const Handle(Geom2d_Geometry)& Geom2,
72 const Standard_Real& Direction);
74 //=============================================================================
75 //function : Constructor
77 //=============================================================================
78 MAT2d_Circuit::MAT2d_Circuit()
82 //=============================================================================
85 //=============================================================================
86 void MAT2d_Circuit::Perform
87 ( MAT2d_SequenceOfSequenceOfGeometry& FigItem,
88 const TColStd_SequenceOfBoolean & IsClosed,
89 const Standard_Integer IndRefLine,
90 const Standard_Boolean Trigo)
92 Standard_Integer NbLines = FigItem.Length();
94 TColStd_Array1OfBoolean Open(1,NbLines);
95 MAT2d_SequenceOfConnexion SVide;
96 Handle(MAT2d_Connexion) ConnexionNul;
98 if (Trigo) direction = 1.; else direction = -1.;
100 //---------------------
101 // Reinitialisation SD.
102 //---------------------
103 geomElements.Clear();
104 connexionMap.Clear();
108 //----------------------------
109 // Detection Lignes ouvertes.
110 //----------------------------
111 for ( i = 1; i <= NbLines; i++) {
112 Handle_Geom2d_TrimmedCurve Curve;
113 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(FigItem.Value(i).First());
114 gp_Pnt2d P1 = Curve->StartPoint();
115 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(FigItem.Value(i).Last());
116 gp_Pnt2d P2 = Curve->EndPoint();
117 // Modified by Sergey KHROMOV - Wed Mar 6 16:59:01 2002 Begin
118 // if ( P1.IsEqual(P2,Precision::Confusion())) Open(i) = Standard_False;
119 // else Open(i) = Standard_True;
120 if (IsClosed(i)) Open(i) = Standard_False;
121 else if (P1.IsEqual(P2,Precision::Confusion())) Open(i) = Standard_False;
122 else Open(i) = Standard_True;
123 // Modified by Sergey KHROMOV - Wed Mar 6 16:59:04 2002 End
126 //---------------------------------------------------------------
127 // Insertion des cassures saillantes ou
128 // ajout des extremites de chaque courbe si la ligne est ouverte.
129 //---------------------------------------------------------------
130 for ( i = 1; i <= NbLines; i++) {
132 InitOpen(FigItem.ChangeValue(i));
133 linesLength.Append(FigItem.Value(i).Length());
136 InsertCorner(FigItem.ChangeValue(i));
137 linesLength.Append(FigItem.Value(i).Length());
141 //---------------------------------
142 // Une seule ligne => Rien a faire.
143 //---------------------------------
146 DoubleLine(FigItem.ChangeValue(1),SVide,ConnexionNul,direction);
147 linesLength.SetValue(1,FigItem.Value(1).Length());
149 geomElements = FigItem.Value(1);
150 UpDateLink(1,1,1,geomElements.Length());
151 linesLength.Append(FigItem.Value(1).Length());
159 //---------------------------------------------------------
160 // Calcul de l ensemble des connexions realisant le chemin.
161 //---------------------------------------------------------
163 Road.Perform(FigItem,IndRefLine,Trigo);
165 //------------------------
166 // Fermeture ligne ouverte.
167 //-------------------------
168 for ( i = 1; i <= NbLines; i++) {
170 Handle(MAT2d_Connexion) CF;
171 if (Road.IsRoot(i)) CF = ConnexionNul; else CF = Road.Father(i);
172 if (Road.IsConnexionsFrom(i)) {
173 DoubleLine(FigItem.ChangeValue(i),Road.ConnexionsFrom(i),
177 DoubleLine(FigItem.ChangeValue(i),SVide,CF,direction);
179 linesLength.SetValue(i,FigItem.Value(i).Length());
183 //------------------------
184 // Construction du chemin.
185 //------------------------
186 Road.RunOnConnexions();
190 Standard_Integer NbConnexions = Road.Path().Length();
191 for (i = 1; i <= NbConnexions; i++) {
192 Handle(Geom2d_TrimmedCurve) edge;
193 edge = GCE2d_MakeSegment(Road.Path().Value(i)->PointOnFirst(),
194 Road.Path().Value(i)->PointOnSecond());
195 MAT2d_DrawCurve(edge,2);
200 //-------------------------
201 // Construction du Circuit.
202 //-------------------------
203 ConstructCircuit(FigItem,IndRefLine,Road);
206 //=======================================================================
207 //function : SubSequence
209 //=======================================================================
210 static void SubSequence(const TColGeom2d_SequenceOfGeometry& S1,
213 TColGeom2d_SequenceOfGeometry& S2)
216 for (Standard_Integer i = IF; i<= IL; i++){
217 S2.Append(S1.Value(i));
222 //=============================================================================
223 //function : ConstructCircuit
225 //=============================================================================
226 void MAT2d_Circuit::ConstructCircuit
227 (const MAT2d_SequenceOfSequenceOfGeometry& FigItem,
228 const Standard_Integer IndRefLine,
229 const MAT2d_MiniPath& Road)
231 Handle(MAT2d_Connexion) PrevC,CurC;
232 TColGeom2d_SequenceOfGeometry SetOfItem;
233 Standard_Integer NbConnexions;
234 Standard_Integer ILastItem;
235 Standard_Integer IndLast;
238 NbConnexions = Road.Path().Length();
239 //-----------------------------------------------------
240 // Depart du premier element de la ligne de reference.
241 //-----------------------------------------------------
242 PrevC = Road.Path().Value(1);
243 SubSequence(FigItem.Value(IndRefLine),
245 PrevC->IndexItemOnFirst(),
247 UpDateLink(1,IndRefLine,1,PrevC->IndexItemOnFirst());
248 connexionMap.Bind(geomElements.Length()+1,PrevC);
249 ILastItem = geomElements.Length();
251 //-----------------------------------------------------------------------
252 // Ajout des portion de lignes delimites par deux connexions successives.
253 //-----------------------------------------------------------------------
254 for ( i = 2; i <= NbConnexions; i++) {
255 CurC = Road.Path().Value(i);
256 if (PassByLast(PrevC,CurC)) {
257 //------------------------------------------------------
258 // La portion passe par le dernier element de la ligne.
259 // - ajout de la portion de PrevC au dernier element
261 // - Si la ligne contient plus d'un element ajout de la
262 // portion du premier element de la ligne a CurC.
263 //------------------------------------------------------
264 IndLast = FigItem.Value(CurC->IndexFirstLine()).Length();
265 SubSequence (FigItem.Value(CurC->IndexFirstLine()),
266 PrevC->IndexItemOnSecond(),
269 UpDateLink(ILastItem+1,CurC->IndexFirstLine(),
270 PrevC->IndexItemOnSecond(),IndLast);
271 geomElements.Append(SetOfItem);
272 ILastItem = geomElements.Length();
274 if (FigItem.Value(CurC->IndexFirstLine()).Length() > 1) {
275 SubSequence(FigItem.Value(CurC->IndexFirstLine()),
277 CurC->IndexItemOnFirst(),
279 UpDateLink(ILastItem+1,CurC->IndexFirstLine(),
280 1,CurC->IndexItemOnFirst());
281 geomElements.Append(SetOfItem);
282 ILastItem = geomElements.Length();
284 connexionMap.Bind(ILastItem+1,CurC);
288 //------------------------------------------------------
289 // La portion ne passe par le dernier element de la ligne.
290 //------------------------------------------------------
291 SubSequence(FigItem.Value(CurC->IndexFirstLine()),
292 PrevC->IndexItemOnSecond(),
293 CurC ->IndexItemOnFirst(),
295 UpDateLink(ILastItem+1,CurC->IndexFirstLine(),
296 PrevC->IndexItemOnSecond(),CurC->IndexItemOnFirst());
297 geomElements.Append(SetOfItem);
298 ILastItem = geomElements.Length();
299 connexionMap.Bind(ILastItem+1,CurC);
304 //-------------------------------------------------------------
305 // Fermeture : de la derniere connexion au dernier element de la
306 // ligne de reference.
307 //-------------------------------------------------------------
308 IndLast = FigItem.Value(IndRefLine).Length();
310 connexionMap.Bind(1,CurC);
311 connexionMap.UnBind(ILastItem+1);
314 SubSequence(FigItem.Value(IndRefLine),
315 PrevC->IndexItemOnSecond(),
318 UpDateLink(ILastItem+1,IndRefLine,PrevC->IndexItemOnSecond(),IndLast);
319 geomElements.Append(SetOfItem);
320 ILastItem = geomElements.Length();
323 //--------------------------------------
324 // Tri des RefToEqui pour chaque element.
325 //--------------------------------------
326 MAT2d_DataMapIteratorOfDataMapOfBiIntSequenceOfInteger Ite;
328 for ( Ite.Initialize(linkRefEqui); Ite.More(); Ite.Next()) {
329 if (Ite.Value().Length() > 1) {
330 SortRefToEqui(Ite.Key());
336 ILastItem = geomElements.Length();
337 for (i = 1; i <= ILastItem; i++) {
338 if (geomElements.Value(i)->DynamicType() != STANDARD_TYPE(Geom2d_CartesianPoint) ){
340 (Handle(Geom2d_Curve)::DownCast(geomElements.Value(i)),2);
347 //=============================================================================
348 //function : InitOpen
350 //=============================================================================
351 void MAT2d_Circuit::InitOpen (TColGeom2d_SequenceOfGeometry& Line) const
353 Handle(Geom2d_TrimmedCurve) Curve;
354 Standard_Real DotProd;
356 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.First());
357 Line.InsertBefore(1,new Geom2d_CartesianPoint(Curve->StartPoint()));
358 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Last());
359 Line.Append(new Geom2d_CartesianPoint(Curve->EndPoint()));
361 for ( Standard_Integer i = 2; i <= Line.Length() - 2; i++) {
362 if ( Abs(CrossProd(Line.Value(i),Line.Value(i+1),DotProd)) > 1.E-8 ||
364 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(i));
365 Line.InsertAfter(i,new Geom2d_CartesianPoint(Curve->EndPoint()));
371 //=============================================================================
372 //function : DoubleLine
374 //=============================================================================
375 void MAT2d_Circuit::DoubleLine
376 ( TColGeom2d_SequenceOfGeometry& Line,
377 MAT2d_SequenceOfConnexion& ConnexionFrom,
378 const Handle(MAT2d_Connexion)& ConnexionFather,
379 const Standard_Real SideRef)
382 Handle(Standard_Type) Type;
383 Handle(Geom2d_TrimmedCurve) Curve;
384 Standard_Integer NbItems = Line.Length();
386 Standard_Real ProVec,DotProd;
387 Handle(MAT2d_Connexion) CC;
389 //--------------------------
390 // Completion de la ligne.
391 //--------------------------
392 for ( i = NbItems - 1; i > 1; i--){
393 Type = Line.Value(i)->DynamicType();
394 if ( Type == STANDARD_TYPE(Geom2d_CartesianPoint) ){
395 Line.Append(Line.Value(i));
398 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(i)->Copy());
404 //------------------------------------------
405 // Repartition des connexions sur la ligne
406 //------------------------------------------
407 Standard_Integer IAfter = ConnexionFrom.Length();
408 Standard_Integer NbConnexions = IAfter;
409 Standard_Integer IndCOF;
411 for (i = 1; i <= IAfter; i++) {
412 CC = ConnexionFrom.Value(i);
413 IndCOF = CC->IndexItemOnFirst();
414 Type = Line.Value(IndCOF)->DynamicType();
416 if ( Type == STANDARD_TYPE(Geom2d_CartesianPoint) ){
417 if (IndCOF!= NbItems && IndCOF!= 1) {
418 ProVec = CrossProd(Line.Value(IndCOF - 1),Line.Value(IndCOF + 1),DotProd);
419 if ((ProVec)*SideRef > 0){
420 CC->IndexItemOnFirst(2*NbItems - IndCOF);
421 ConnexionFrom.InsertAfter(IAfter,CC);
422 ConnexionFrom.Remove(i);
428 else if (Side(CC,Line) != SideRef){
429 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(IndCOF));
430 CC->IndexItemOnFirst(2*NbItems - IndCOF);
431 CC->ParameterOnFirst(Curve->ReversedParameter(CC->ParameterOnFirst()));
432 ConnexionFrom.InsertAfter(IAfter,CC);
433 ConnexionFrom.Remove(i);
439 //---------------------------
440 // Mise a jour connexion pere.
441 //---------------------------
442 if (!ConnexionFather.IsNull()) {
443 CC = ConnexionFather->Reverse();
444 IndCOF = CC->IndexItemOnFirst();
445 Type = Line.Value(IndCOF)->DynamicType();
447 if ( Type == STANDARD_TYPE(Geom2d_CartesianPoint) ){
448 if (IndCOF != NbItems && IndCOF != 1) {
449 ProVec = CrossProd(Line.Value(IndCOF - 1),Line.Value(IndCOF + 1),DotProd);
450 if ((ProVec)*SideRef > 0){
451 ConnexionFather->IndexItemOnSecond(2*NbItems - IndCOF);
455 else if (Side(CC,Line) != SideRef){
456 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(IndCOF));
457 ConnexionFather->IndexItemOnSecond(2*NbItems - IndCOF);
458 ConnexionFather->ParameterOnSecond
459 (Curve->ReversedParameter(ConnexionFather->ParameterOnSecond()));
463 //-------------------------------------
464 // Suppression des cassures rentrantes.
465 //-------------------------------------
466 Standard_Integer IndLine = 1;
467 Standard_Integer ICorres = 1;
468 TColStd_Array1OfInteger Corres(1,Line.Length());
470 while (Line.Value(IndLine) != Line.Last()){
471 Corres(ICorres) = IndLine;
472 Type = Line.Value(IndLine)->DynamicType();
474 if (Type == STANDARD_TYPE(Geom2d_CartesianPoint) &&
475 ICorres != 1 && ICorres != NbItems) {
477 if (!IsSharpCorner(Line.Value(IndLine - 1),
478 Line.Value(IndLine + 1),SideRef)){
479 Line.Remove(IndLine);
487 Corres(ICorres) = IndLine;
489 for (i = 1; i < 2*NbItems - 2; i++) {
490 if (Corres(i) == 0) Corres(i) = Corres(2*NbItems - i);
495 for (i = 1; i <= 2*NbItems - 2; i++) {
496 cout<< "Correspondance "<< i<<" -> "<<Corres(i)<<endl;
501 //----------------------------
502 // Mise a jour des Connexions.
503 //----------------------------
504 for ( i = 1; i <= NbConnexions; i++){
505 CC = ConnexionFrom.ChangeValue(i);
506 CC->IndexItemOnFirst(Corres(CC->IndexItemOnFirst()));
509 if (!ConnexionFather.IsNull()) {
511 ->IndexItemOnSecond(Corres(ConnexionFather->IndexItemOnSecond()));
516 //=============================================================================
517 //function : InsertCorner
519 //=============================================================================
520 void MAT2d_Circuit::InsertCorner (TColGeom2d_SequenceOfGeometry& Line) const
522 Standard_Integer i,isuiv;
523 Handle(Geom2d_TrimmedCurve) Curve;
524 Standard_Boolean Insert;
526 for ( i = 1; i <= Line.Length(); i++) {
527 isuiv = (i == Line.Length()) ? 1 : i + 1;
528 Insert = IsSharpCorner(Line.Value(i),Line.Value(isuiv),direction);
533 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(isuiv));
534 gp_Pnt2d P = Curve->StartPoint();
536 Handle(Draw_Marker2D) dr = new Draw_Marker2D(P,Draw_Plus,Draw_vert);
545 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(isuiv));
546 Line.InsertAfter(i,new Geom2d_CartesianPoint(Curve->StartPoint()));
552 //=============================================================================
553 //function : NumberOfItem
555 //=============================================================================
556 Standard_Integer MAT2d_Circuit::NumberOfItems()const
558 return geomElements.Length();
561 //=============================================================================
562 //function : LineLength
564 //=============================================================================
565 Standard_Integer MAT2d_Circuit::LineLength(const Standard_Integer I) const
567 return linesLength(I);
570 //=============================================================================
573 //=============================================================================
574 Handle(Geom2d_Geometry) MAT2d_Circuit::Value
575 (const Standard_Integer Index)const
577 return geomElements.Value(Index);
580 //=============================================================================
581 //function : RefToEqui
583 //=============================================================================
584 const TColStd_SequenceOfInteger& MAT2d_Circuit::RefToEqui
585 (const Standard_Integer IndLine,
586 const Standard_Integer IndCurve) const
588 MAT2d_BiInt Key(IndLine,IndCurve);
589 return linkRefEqui(Key);
592 //=============================================================================
593 //function : SortRefToEqui
595 //=============================================================================
596 void MAT2d_Circuit::SortRefToEqui (const MAT2d_BiInt& BiRef)
599 TColStd_SequenceOfInteger& S = linkRefEqui.ChangeFind(BiRef);
600 TColStd_SequenceOfInteger SFin;
602 for( i = 1; i <= S.Length(); i++){
603 if (!ConnexionOn(S.Value(i))) break;
605 if ( i > 1 && i <= S.Length()) {
612 //=============================================================================
613 //function : Connexion
615 //=============================================================================
616 Handle(MAT2d_Connexion) MAT2d_Circuit::Connexion(const Standard_Integer I)const
618 return connexionMap(I);
621 //=============================================================================
622 //function : ConnexionOn
624 //=============================================================================
625 Standard_Boolean MAT2d_Circuit::ConnexionOn(const Standard_Integer I)const
627 return connexionMap.IsBound(I);
630 //=============================================================================
633 //=============================================================================
634 Standard_Real MAT2d_Circuit::Side
635 (const Handle(MAT2d_Connexion)& C1,
636 const TColGeom2d_SequenceOfGeometry& Line)
639 Handle(Geom2d_TrimmedCurve) Curve;
641 gp_Vec2d Vect1(C1->PointOnSecond().X() - C1->PointOnFirst().X(),
642 C1->PointOnSecond().Y() - C1->PointOnFirst().Y());
643 Curve = Handle(Geom2d_TrimmedCurve)::DownCast
644 (Line.Value(C1->IndexItemOnFirst()));
645 gp_Vec2d Vect2 = Curve->DN(C1->ParameterOnFirst(),1);
646 if ( (Vect1^Vect2) > 0.) return - 1.; else return 1.;
649 //=============================================================================
650 //function : PassByLast
652 //=============================================================================
653 Standard_Boolean MAT2d_Circuit::PassByLast
654 (const Handle(MAT2d_Connexion)& C1,
655 const Handle(MAT2d_Connexion)& C2) const
657 if (C2->IndexFirstLine() == C1->IndexSecondLine()){
658 if (C2->IndexItemOnFirst() < C1->IndexItemOnSecond()) {
659 return Standard_True;
661 else if (C2->IndexItemOnFirst() == C1->IndexItemOnSecond()) {
662 if (C1->IndexFirstLine() == C2->IndexSecondLine()) {
663 return Standard_True;
665 if (C2->ParameterOnFirst() == C1->ParameterOnSecond()) {
666 gp_Vec2d Vect1(C1->PointOnSecond(),C1->PointOnFirst());
667 gp_Vec2d Vect2(C2->PointOnFirst(),C2->PointOnSecond());
668 if ((Vect1^Vect2)*direction > 0) {
669 return Standard_True;
672 else if (C2->ParameterOnFirst() < C1->ParameterOnSecond()) {
673 return Standard_True;
677 return Standard_False;
680 //=============================================================================
681 //function : UpDateLink
683 //=============================================================================
684 void MAT2d_Circuit::UpDateLink(const Standard_Integer IFirst,
685 const Standard_Integer ILine,
686 const Standard_Integer ICurveFirst,
687 const Standard_Integer ICurveLast)
689 Standard_Integer IEqui = IFirst;
692 for (i = ICurveFirst; i <= ICurveLast; i++) {
693 MAT2d_BiInt Key(ILine,i);
694 if (linkRefEqui.IsBound(Key)) {
695 linkRefEqui(Key).Append(IEqui);
698 TColStd_SequenceOfInteger L;
699 linkRefEqui.Bind(Key,L);
700 linkRefEqui(Key).Append(IEqui);
706 //==========================================================================
707 //function : CrossProd
708 //purpose : Calcul le produit vectoriel et scalaire entre les directions des
709 // tangentes a la fin de Geom1 et au debut de Geom2.
710 // Geom1 et Geom2 doivent etre des courbes.
711 //==========================================================================
712 static Standard_Real CrossProd(const Handle(Geom2d_Geometry)& Geom1,
713 const Handle(Geom2d_Geometry)& Geom2,
714 Standard_Real& DotProd)
716 Handle(Geom2d_TrimmedCurve) Curve;
718 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Geom1);
719 gp_Dir2d Dir1(Curve->DN(Curve->LastParameter(),1));
720 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Geom2);
721 gp_Dir2d Dir2(Curve->DN(Curve->FirstParameter(),1));
722 DotProd = Dir1.Dot(Dir2);
727 //=======================================================================
728 //function : IsSharpCorner
729 //purpose : Return True Si le point commun entre <Geom1> et <Geom2> est
730 // une cassure saillante par rapport <Direction>
731 //=======================================================================
733 static Standard_Boolean IsSharpCorner (const Handle(Geom2d_Geometry)& Geom1,
734 const Handle(Geom2d_Geometry)& Geom2,
735 const Standard_Real& Direction)
737 Standard_Real DotProd;
738 Standard_Real ProVec = CrossProd (Geom1,Geom2,DotProd);
739 Standard_Integer NbTest = 1;
740 Standard_Real DU = Precision::Confusion();
741 Handle(Geom2d_TrimmedCurve) C1,C2;
743 C1= Handle(Geom2d_TrimmedCurve)::DownCast(Geom1);
744 C2= Handle(Geom2d_TrimmedCurve)::DownCast(Geom2);
745 // Modified by Sergey KHROMOV - Thu Oct 24 19:02:46 2002 Begin
746 // Add the same criterion as it is in MAT2d_Circuit::InitOpen(..)
747 // Standard_Real TolAng = 1.E-5;
748 Standard_Real TolAng = 1.E-8;
749 // Modified by Sergey KHROMOV - Thu Oct 24 19:02:47 2002 End
751 while (NbTest <= 10) {
752 if ((ProVec)*Direction < -TolAng)
753 return Standard_True; // Saillant.
754 if ((ProVec)*Direction > TolAng)
755 return Standard_False; // Rentrant.
758 return Standard_False; // Plat.
761 Standard_Real U1 = C1->LastParameter() - NbTest*DU;
762 Standard_Real U2 = C2->FirstParameter() + NbTest*DU;
763 gp_Dir2d Dir1(C1->DN(U1,1));
764 gp_Dir2d Dir2(C2->DN(U2,1));
765 DotProd = Dir1.Dot(Dir2);
774 // on calculde des paralleles aux deux courbes du cote du domaine
776 // Si pas dintersection => saillant.
777 // Sinon => rentrant.
779 Standard_Real Tol = Precision::Confusion();
780 Standard_Real MilC1 = (C1->LastParameter() + C1->FirstParameter())*0.5;
781 Standard_Real MilC2 = (C2->LastParameter() + C2->FirstParameter())*0.5;
782 gp_Pnt2d P = C1->Value(C1->LastParameter());
783 gp_Pnt2d P1 = C1->Value(MilC1);
784 gp_Pnt2d P2 = C2->Value(MilC2);
786 D = Min(P1.Distance(P),P2.Distance(P));
789 if (Direction > 0.) D = -D;
791 Handle(Geom2dAdaptor_HCurve) HC1 = new Geom2dAdaptor_HCurve(C1);
792 Handle(Geom2dAdaptor_HCurve) HC2 = new Geom2dAdaptor_HCurve(C2);
793 Adaptor3d_OffsetCurve OC1(HC1,D,MilC1,C1->LastParameter());
794 Adaptor3d_OffsetCurve OC2(HC2,D,C2->FirstParameter(),MilC2);
795 Geom2dInt_GInter Intersect;
796 Intersect.Perform(OC1,OC2,Tol,Tol);
799 static Standard_Boolean Affich = 0;
801 Standard_Real DU1 = (OC1.LastParameter() - OC1.FirstParameter())/9.;
802 Standard_Real DU2 = (OC2.LastParameter() - OC2.FirstParameter())/9.;
803 for (Standard_Integer ki = 0; ki <= 9; ki++) {
804 gp_Pnt2d P1 = OC1.Value(OC1.FirstParameter()+ki*DU1);
805 gp_Pnt2d P2 = OC2.Value(OC2.FirstParameter()+ki*DU2);
807 Handle(Draw_Marker2D) dr1 = new Draw_Marker2D(P1,Draw_Plus,Draw_vert);
808 Handle(Draw_Marker2D) dr2 = new Draw_Marker2D(P2,Draw_Plus,Draw_rouge);
820 if (Intersect.IsDone() && !Intersect.IsEmpty()) {
821 return Standard_False;
824 return Standard_True;
831 //==========================================================================
832 //function : MAT2d_DrawCurve
833 //purpose : Affichage d une courbe <aCurve> de Geom2d. dans une couleur
834 // definie par <Indice>.
839 //==========================================================================
840 void MAT2d_DrawCurve(const Handle(Geom2d_Curve)& aCurve,
841 const Standard_Integer /*Indice*/)
843 Handle(Standard_Type) type = aCurve->DynamicType();
844 Handle(Geom2d_Curve) curve,CurveDraw;
846 Handle(DrawTrSurf_Curve2d) dr;
850 if (type == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
851 curve = Handle(Geom2d_TrimmedCurve)::DownCast(aCurve)->BasisCurve();
852 type = curve->DynamicType();
853 // PB de representation des courbes semi_infinies.
854 gp_Parab2d gpParabola;
855 gp_Hypr2d gpHyperbola;
857 Standard_Real Limit = 50000.;
858 Standard_Real delta = 400;
860 // PB de representation des courbes semi_infinies.
861 if (aCurve->LastParameter() == Precision::Infinite()) {
863 if (type == STANDARD_TYPE(Geom2d_Parabola)) {
864 gpParabola = Handle(Geom2d_Parabola)::DownCast(curve)->Parab2d();
865 Focus = gpParabola.Focal();
866 Standard_Real Val1 = Sqrt(Limit*Focus);
867 Standard_Real Val2 = Sqrt(Limit*Limit);
868 delta= (Val1 <= Val2 ? Val1:Val2);
870 else if (type == STANDARD_TYPE(Geom2d_Hyperbola)) {
871 gpHyperbola = Handle(Geom2d_Hyperbola)::DownCast(curve)->Hypr2d();
872 Standard_Real Majr = gpHyperbola.MajorRadius();
873 Standard_Real Minr = gpHyperbola.MinorRadius();
874 Standard_Real Valu1 = Limit/Majr;
875 Standard_Real Valu2 = Limit/Minr;
876 Standard_Real Val1 = Log(Valu1+Sqrt(Valu1*Valu1-1));
877 Standard_Real Val2 = Log(Valu2+Sqrt(Valu2*Valu2+1));
878 delta = (Val1 <= Val2 ? Val1:Val2);
880 CurveDraw = new Geom2d_TrimmedCurve(aCurve,
881 aCurve->FirstParameter(),
882 aCurve->FirstParameter() + delta);
894 if (Indice == 1) Couleur = Draw_jaune;
895 else if (Indice == 2) Couleur = Draw_bleu;
896 else if (Indice == 3) Couleur = Draw_rouge;
897 else if (Indice == 4) Couleur = Draw_vert;
899 if (type == STANDARD_TYPE(Geom2d_Circle))
900 dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,30);
901 else if (type == STANDARD_TYPE(Geom2d_Line))
902 dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,2);
904 dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,500);