// Created on: 1993-11-19 // Created by: Yves FRICAUD // Copyright (c) 1993-1999 Matra Datavision // Copyright (c) 1999-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include IMPLEMENT_STANDARD_RTTIEXT(MAT2d_Circuit,Standard_Transient) #ifdef OCCT_DEBUG #include #include #include #include #include #include #include #include #endif #ifdef DRAW #include #include #include static Handle(DrawTrSurf_Curve2d) draw; Standard_EXPORT Draw_Viewer dout; #endif #ifdef OCCT_DEBUG static void MAT2d_DrawCurve(const Handle(Geom2d_Curve)& aCurve, const Standard_Integer Indice); static Standard_Boolean AffichCircuit = 0; #endif // static functions: static Standard_Real CrossProd(const Handle(Geom2d_Geometry)& Geom1, const Handle(Geom2d_Geometry)& Geom2, Standard_Real& DotProd); //============================================================================= //function : Constructor //purpose : //============================================================================= MAT2d_Circuit::MAT2d_Circuit(const GeomAbs_JoinType aJoinType, const Standard_Boolean IsOpenResult) { myJoinType = aJoinType; myIsOpenResult = IsOpenResult; } //============================================================================= //function : Perform //purpose : //============================================================================= void MAT2d_Circuit::Perform ( MAT2d_SequenceOfSequenceOfGeometry& FigItem, const TColStd_SequenceOfBoolean & IsClosed, const Standard_Integer IndRefLine, const Standard_Boolean Trigo) { Standard_Integer NbLines = FigItem.Length(); Standard_Integer i; TColStd_Array1OfBoolean Open(1,NbLines); MAT2d_SequenceOfConnexion SVide; Handle(MAT2d_Connexion) ConnexionNul; if (Trigo) direction = 1.; else direction = -1.; //--------------------- // Reinitialisation SD. //--------------------- geomElements.Clear(); connexionMap.Clear(); linkRefEqui.Clear(); linesLength.Clear(); //---------------------------- // Detection Lignes ouvertes. //---------------------------- for ( i = 1; i <= NbLines; i++) { Handle(Geom2d_TrimmedCurve) Curve; Curve = Handle(Geom2d_TrimmedCurve)::DownCast(FigItem.Value(i).First()); gp_Pnt2d P1 = Curve->StartPoint(); Curve = Handle(Geom2d_TrimmedCurve)::DownCast(FigItem.Value(i).Last()); gp_Pnt2d P2 = Curve->EndPoint(); // Modified by Sergey KHROMOV - Wed Mar 6 16:59:01 2002 Begin // if ( P1.IsEqual(P2,Precision::Confusion())) Open(i) = Standard_False; // else Open(i) = Standard_True; if (IsClosed(i)) Open(i) = Standard_False; else if (P1.IsEqual(P2,Precision::Confusion())) Open(i) = Standard_False; else Open(i) = Standard_True; // Modified by Sergey KHROMOV - Wed Mar 6 16:59:04 2002 End } //--------------------------------------------------------------- // Insertion des cassures saillantes ou // ajout des extremites de chaque courbe si la ligne est ouverte. //--------------------------------------------------------------- for ( i = 1; i <= NbLines; i++) { if (Open(i)) { InitOpen(FigItem.ChangeValue(i)); linesLength.Append(FigItem.Value(i).Length()); } else { InsertCorner(FigItem.ChangeValue(i)); linesLength.Append(FigItem.Value(i).Length()); } } //--------------------------------- // Une seule ligne => Rien a faire. //--------------------------------- if (NbLines == 1) { if (Open(1)) { DoubleLine(FigItem.ChangeValue(1),SVide,ConnexionNul,direction); linesLength.SetValue(1,FigItem.Value(1).Length()); } geomElements = FigItem.Value(1); UpDateLink(1,1,1,geomElements.Length()); linesLength.Append(FigItem.Value(1).Length()); return; } //------------------ // Plusieurs lignes. //------------------ //--------------------------------------------------------- // Calcul de l ensemble des connexions realisant le chemin. //--------------------------------------------------------- MAT2d_MiniPath Road; Road.Perform(FigItem,IndRefLine,Trigo); //------------------------ // Fermeture ligne ouverte. //------------------------- for ( i = 1; i <= NbLines; i++) { if (Open(i)) { Handle(MAT2d_Connexion) CF; if (Road.IsRoot(i)) CF = ConnexionNul; else CF = Road.Father(i); if (Road.IsConnexionsFrom(i)) { DoubleLine(FigItem.ChangeValue(i),Road.ConnexionsFrom(i), CF,direction); } else { DoubleLine(FigItem.ChangeValue(i),SVide,CF,direction); } linesLength.SetValue(i,FigItem.Value(i).Length()); } } //------------------------ // Construction du chemin. //------------------------ Road.RunOnConnexions(); #ifdef OCCT_DEBUG if (AffichCircuit) { Standard_Integer NbConnexions = Road.Path().Length(); for (i = 1; i <= NbConnexions; i++) { Handle(Geom2d_TrimmedCurve) edge; edge = GCE2d_MakeSegment(Road.Path().Value(i)->PointOnFirst(), Road.Path().Value(i)->PointOnSecond()); MAT2d_DrawCurve(edge,2); } } #endif //------------------------- // Construction du Circuit. //------------------------- ConstructCircuit(FigItem,IndRefLine,Road); } //======================================================================= //function : IsSharpCorner //purpose : Return True Si le point commun entre et est // une cassure saillante par rapport //======================================================================= Standard_Boolean MAT2d_Circuit::IsSharpCorner(const Handle(Geom2d_Geometry)& Geom1, const Handle(Geom2d_Geometry)& Geom2, const Standard_Real Direction) const { Standard_Real DotProd; Standard_Real ProVec = CrossProd (Geom1,Geom2,DotProd); Standard_Integer NbTest = 1; Standard_Real DU = Precision::Confusion(); Handle(Geom2d_TrimmedCurve) C1,C2; C1= Handle(Geom2d_TrimmedCurve)::DownCast(Geom1); C2= Handle(Geom2d_TrimmedCurve)::DownCast(Geom2); // Modified by Sergey KHROMOV - Thu Oct 24 19:02:46 2002 Begin // Add the same criterion as it is in MAT2d_Circuit::InitOpen(..) // Standard_Real TolAng = 1.E-5; Standard_Real TolAng = 1.E-8; // Modified by Sergey KHROMOV - Thu Oct 24 19:02:47 2002 End if (myJoinType == GeomAbs_Arc) { while (NbTest <= 10) { if ((ProVec)*Direction < -TolAng) return Standard_True; // Saillant. if ((ProVec)*Direction > TolAng) return Standard_False; // Rentrant. else { if (DotProd > 0) { return Standard_False; // Plat. } TolAng = 1.E-8; Standard_Real U1 = C1->LastParameter() - NbTest*DU; Standard_Real U2 = C2->FirstParameter() + NbTest*DU; gp_Dir2d Dir1(C1->DN(U1,1)); gp_Dir2d Dir2(C2->DN(U2,1)); DotProd = Dir1.Dot(Dir2); ProVec = Dir1^Dir2; NbTest++; } } // Rebroussement. // on calculde des paralleles aux deux courbes du cote du domaine // de calcul // Si pas dintersection => saillant. // Sinon => rentrant. Standard_Real D ; Standard_Real Tol = Precision::Confusion(); Standard_Real MilC1 = (C1->LastParameter() + C1->FirstParameter())*0.5; Standard_Real MilC2 = (C2->LastParameter() + C2->FirstParameter())*0.5; gp_Pnt2d P = C1->Value(C1->LastParameter()); gp_Pnt2d P1 = C1->Value(MilC1); gp_Pnt2d P2 = C2->Value(MilC2); D = Min(P1.Distance(P),P2.Distance(P)); D /= 10; if (Direction > 0.) D = -D; Handle(Geom2dAdaptor_HCurve) HC1 = new Geom2dAdaptor_HCurve(C1); Handle(Geom2dAdaptor_HCurve) HC2 = new Geom2dAdaptor_HCurve(C2); Adaptor2d_OffsetCurve OC1(HC1,D,MilC1,C1->LastParameter()); Adaptor2d_OffsetCurve OC2(HC2,D,C2->FirstParameter(),MilC2); Geom2dInt_GInter Intersect; Intersect.Perform(OC1,OC2,Tol,Tol); #ifdef OCCT_DEBUG static Standard_Boolean Affich = 0; if (Affich) { #ifdef DRAW Standard_Real DU1 = (OC1.LastParameter() - OC1.FirstParameter())/9.; Standard_Real DU2 = (OC2.LastParameter() - OC2.FirstParameter())/9.; for (Standard_Integer ki = 0; ki <= 9; ki++) { gp_Pnt2d P1 = OC1.Value(OC1.FirstParameter()+ki*DU1); gp_Pnt2d P2 = OC2.Value(OC2.FirstParameter()+ki*DU2); Handle(Draw_Marker2D) dr1 = new Draw_Marker2D(P1,Draw_Plus,Draw_vert); Handle(Draw_Marker2D) dr2 = new Draw_Marker2D(P2,Draw_Plus,Draw_rouge); dout << dr1; dout << dr2; } dout.Flush(); #endif } #endif if (Intersect.IsDone() && !Intersect.IsEmpty()) { return Standard_False; } else { return Standard_True; } } //end of if (myJoinType == GeomAbs_Arc) else if (myJoinType == GeomAbs_Intersection) { if (Abs(ProVec) <= TolAng && DotProd < 0) { while (NbTest <= 10) { Standard_Real U1 = C1->LastParameter() - NbTest*DU; Standard_Real U2 = C2->FirstParameter() + NbTest*DU; gp_Dir2d Dir1(C1->DN(U1,1)); gp_Dir2d Dir2(C2->DN(U2,1)); DotProd = Dir1.Dot(Dir2); ProVec = Dir1^Dir2; if ((ProVec)*Direction < -TolAng) return Standard_True; // Saillant. if ((ProVec)*Direction > TolAng) return Standard_False; // Rentrant. NbTest++; } return Standard_False; } else return Standard_False; } return Standard_False; } //======================================================================= //function : SubSequence //purpose : //======================================================================= static void SubSequence(const TColGeom2d_SequenceOfGeometry& S1, Standard_Integer IF, Standard_Integer IL, TColGeom2d_SequenceOfGeometry& S2) { S2.Clear(); for (Standard_Integer i = IF; i<= IL; i++){ S2.Append(S1.Value(i)); } } //============================================================================= //function : ConstructCircuit //purpose : //============================================================================= void MAT2d_Circuit::ConstructCircuit (const MAT2d_SequenceOfSequenceOfGeometry& FigItem, const Standard_Integer IndRefLine, const MAT2d_MiniPath& Road) { Handle(MAT2d_Connexion) PrevC,CurC; TColGeom2d_SequenceOfGeometry SetOfItem; Standard_Integer NbConnexions; Standard_Integer ILastItem; Standard_Integer IndLast; Standard_Integer i; NbConnexions = Road.Path().Length(); //----------------------------------------------------- // Depart du premier element de la ligne de reference. //----------------------------------------------------- PrevC = Road.Path().Value(1); SubSequence(FigItem.Value(IndRefLine), 1, PrevC->IndexItemOnFirst(), geomElements); UpDateLink(1,IndRefLine,1,PrevC->IndexItemOnFirst()); connexionMap.Bind(geomElements.Length()+1,PrevC); ILastItem = geomElements.Length(); //----------------------------------------------------------------------- // Ajout des portion de lignes delimites par deux connexions successives. //----------------------------------------------------------------------- for ( i = 2; i <= NbConnexions; i++) { CurC = Road.Path().Value(i); if (PassByLast(PrevC,CurC)) { //------------------------------------------------------ // La portion passe par le dernier element de la ligne. // - ajout de la portion de PrevC au dernier element // de la ligne. // - Si la ligne contient plus d'un element ajout de la // portion du premier element de la ligne a CurC. //------------------------------------------------------ IndLast = FigItem.Value(CurC->IndexFirstLine()).Length(); SubSequence (FigItem.Value(CurC->IndexFirstLine()), PrevC->IndexItemOnSecond(), IndLast, SetOfItem); UpDateLink(ILastItem+1,CurC->IndexFirstLine(), PrevC->IndexItemOnSecond(),IndLast); geomElements.Append(SetOfItem); ILastItem = geomElements.Length(); if (FigItem.Value(CurC->IndexFirstLine()).Length() > 1) { SubSequence(FigItem.Value(CurC->IndexFirstLine()), 1, CurC->IndexItemOnFirst(), SetOfItem); UpDateLink(ILastItem+1,CurC->IndexFirstLine(), 1,CurC->IndexItemOnFirst()); geomElements.Append(SetOfItem); ILastItem = geomElements.Length(); } connexionMap.Bind(ILastItem+1,CurC); } else{ //------------------------------------------------------ // La portion ne passe par le dernier element de la ligne. //------------------------------------------------------ SubSequence(FigItem.Value(CurC->IndexFirstLine()), PrevC->IndexItemOnSecond(), CurC ->IndexItemOnFirst(), SetOfItem); UpDateLink(ILastItem+1,CurC->IndexFirstLine(), PrevC->IndexItemOnSecond(),CurC->IndexItemOnFirst()); geomElements.Append(SetOfItem); ILastItem = geomElements.Length(); connexionMap.Bind(ILastItem+1,CurC); } PrevC = CurC; } //------------------------------------------------------------- // Fermeture : de la derniere connexion au dernier element de la // ligne de reference. //------------------------------------------------------------- IndLast = FigItem.Value(IndRefLine).Length(); if (IndLast == 1) { connexionMap.Bind(1,CurC); connexionMap.UnBind(ILastItem+1); } else { SubSequence(FigItem.Value(IndRefLine), PrevC->IndexItemOnSecond(), IndLast, SetOfItem); UpDateLink(ILastItem+1,IndRefLine,PrevC->IndexItemOnSecond(),IndLast); geomElements.Append(SetOfItem); ILastItem = geomElements.Length(); } //-------------------------------------- // Tri des RefToEqui pour chaque element. //-------------------------------------- MAT2d_DataMapIteratorOfDataMapOfBiIntSequenceOfInteger Ite; for ( Ite.Initialize(linkRefEqui); Ite.More(); Ite.Next()) { if (Ite.Value().Length() > 1) { SortRefToEqui(Ite.Key()); } } #ifdef OCCT_DEBUG if (AffichCircuit) { ILastItem = geomElements.Length(); for (i = 1; i <= ILastItem; i++) { if (geomElements.Value(i)->DynamicType() != STANDARD_TYPE(Geom2d_CartesianPoint) ){ MAT2d_DrawCurve (Handle(Geom2d_Curve)::DownCast(geomElements.Value(i)),2); } } } #endif } //============================================================================= //function : InitOpen //purpose : //============================================================================= void MAT2d_Circuit::InitOpen (TColGeom2d_SequenceOfGeometry& Line) const { Handle(Geom2d_TrimmedCurve) Curve; Standard_Real DotProd; Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.First()); Line.InsertBefore(1,new Geom2d_CartesianPoint(Curve->StartPoint())); Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Last()); Line.Append(new Geom2d_CartesianPoint(Curve->EndPoint())); for ( Standard_Integer i = 2; i <= Line.Length() - 2; i++) { if ( Abs(CrossProd(Line.Value(i),Line.Value(i+1),DotProd)) > 1.E-8 || DotProd < 0. ) { Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(i)); Line.InsertAfter(i,new Geom2d_CartesianPoint(Curve->EndPoint())); i++; } } } //============================================================================= //function : DoubleLine //purpose : //============================================================================= void MAT2d_Circuit::DoubleLine ( TColGeom2d_SequenceOfGeometry& Line, MAT2d_SequenceOfConnexion& ConnexionFrom, const Handle(MAT2d_Connexion)& ConnexionFather, const Standard_Real SideRef) const { Handle(Standard_Type) Type; Handle(Geom2d_TrimmedCurve) Curve; Standard_Integer NbItems = Line.Length(); Standard_Integer i; Standard_Real ProVec,DotProd; Handle(MAT2d_Connexion) CC; //-------------------------- // Completion de la ligne. //-------------------------- if (!myIsOpenResult) { for ( i = NbItems - 1; i > 1; i--){ Type = Line.Value(i)->DynamicType(); if ( Type == STANDARD_TYPE(Geom2d_CartesianPoint) ){ Line.Append(Line.Value(i)); } else { Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(i)->Copy()); Curve->Reverse(); Line.Append(Curve); } } } //------------------------------------------ // Repartition des connexions sur la ligne //------------------------------------------ Standard_Integer IAfter = ConnexionFrom.Length(); Standard_Integer NbConnexions = IAfter; Standard_Integer IndCOF; for (i = 1; i <= IAfter; i++) { CC = ConnexionFrom.Value(i); IndCOF = CC->IndexItemOnFirst(); Type = Line.Value(IndCOF)->DynamicType(); if ( Type == STANDARD_TYPE(Geom2d_CartesianPoint) ){ if (IndCOF!= NbItems && IndCOF!= 1) { ProVec = CrossProd(Line.Value(IndCOF - 1),Line.Value(IndCOF + 1),DotProd); if ((ProVec)*SideRef > 0){ CC->IndexItemOnFirst(2*NbItems - IndCOF); ConnexionFrom.InsertAfter(IAfter,CC); ConnexionFrom.Remove(i); IAfter--; i--; } } } else if (Side(CC,Line) != SideRef){ Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(IndCOF)); CC->IndexItemOnFirst(2*NbItems - IndCOF); CC->ParameterOnFirst(Curve->ReversedParameter(CC->ParameterOnFirst())); ConnexionFrom.InsertAfter(IAfter,CC); ConnexionFrom.Remove(i); IAfter--; i--; } } //--------------------------- // Mise a jour connexion pere. //--------------------------- if (!ConnexionFather.IsNull()) { CC = ConnexionFather->Reverse(); IndCOF = CC->IndexItemOnFirst(); Type = Line.Value(IndCOF)->DynamicType(); if ( Type == STANDARD_TYPE(Geom2d_CartesianPoint) ){ if (IndCOF != NbItems && IndCOF != 1) { ProVec = CrossProd(Line.Value(IndCOF - 1),Line.Value(IndCOF + 1),DotProd); if ((ProVec)*SideRef > 0){ ConnexionFather->IndexItemOnSecond(2*NbItems - IndCOF); } } } else if (Side(CC,Line) != SideRef){ Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(IndCOF)); ConnexionFather->IndexItemOnSecond(2*NbItems - IndCOF); ConnexionFather->ParameterOnSecond (Curve->ReversedParameter(ConnexionFather->ParameterOnSecond())); } } //------------------------------------- // Suppression des cassures rentrantes. //------------------------------------- Standard_Integer IndLine = 1; Standard_Integer ICorres = 1; TColStd_Array1OfInteger Corres(1,Line.Length()); while (Line.Value(IndLine) != Line.Last()){ Corres(ICorres) = IndLine; Type = Line.Value(IndLine)->DynamicType(); if (Type == STANDARD_TYPE(Geom2d_CartesianPoint) && ICorres != 1 && ICorres != NbItems) { if (!IsSharpCorner(Line.Value(IndLine - 1), Line.Value(IndLine + 1),SideRef)){ Line.Remove(IndLine); IndLine--; Corres(ICorres) =0; } } IndLine++; ICorres++; } Corres(ICorres) = IndLine; if (!myIsOpenResult) { for (i = 1; i < 2*NbItems - 2; i++) { if (Corres(i) == 0) Corres(i) = Corres(2*NbItems - i); } #ifdef OCCT_DEBUG if (AffichCircuit) { for (i = 1; i <= 2*NbItems - 2; i++) { cout<< "Correspondance "<< i<<" -> "<IndexItemOnFirst(Corres(CC->IndexItemOnFirst())); } if (!ConnexionFather.IsNull()) { ConnexionFather ->IndexItemOnSecond(Corres(ConnexionFather->IndexItemOnSecond())); } } } //============================================================================= //function : InsertCorner //purpose : //============================================================================= void MAT2d_Circuit::InsertCorner (TColGeom2d_SequenceOfGeometry& Line) const { Standard_Integer i,isuiv; Handle(Geom2d_TrimmedCurve) Curve; Standard_Boolean Insert; for ( i = 1; i <= Line.Length(); i++) { isuiv = (i == Line.Length()) ? 1 : i + 1; Insert = IsSharpCorner(Line.Value(i),Line.Value(isuiv),direction); #ifdef OCCT_DEBUG if (AffichCircuit) { if (Insert) { Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(isuiv)); #ifdef DRAW gp_Pnt2d P = Curve->StartPoint(); Handle(Draw_Marker2D) dr = new Draw_Marker2D(P,Draw_Plus,Draw_vert); dout << dr; dout.Flush(); #endif } } #endif if (Insert) { Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(isuiv)); Line.InsertAfter(i,new Geom2d_CartesianPoint(Curve->StartPoint())); i++; } } } //============================================================================= //function : NumberOfItem //purpose : //============================================================================= Standard_Integer MAT2d_Circuit::NumberOfItems()const { return geomElements.Length(); } //============================================================================= //function : LineLength //purpose : //============================================================================= Standard_Integer MAT2d_Circuit::LineLength(const Standard_Integer I) const { return linesLength(I); } //============================================================================= //function : Value //purpose : //============================================================================= Handle(Geom2d_Geometry) MAT2d_Circuit::Value (const Standard_Integer Index)const { return geomElements.Value(Index); } //============================================================================= //function : RefToEqui //purpose : //============================================================================= const TColStd_SequenceOfInteger& MAT2d_Circuit::RefToEqui (const Standard_Integer IndLine, const Standard_Integer IndCurve) const { MAT2d_BiInt Key(IndLine,IndCurve); return linkRefEqui(Key); } //============================================================================= //function : SortRefToEqui //purpose : //============================================================================= void MAT2d_Circuit::SortRefToEqui (const MAT2d_BiInt& BiRef) { Standard_Integer i; TColStd_SequenceOfInteger& S = linkRefEqui.ChangeFind(BiRef); TColStd_SequenceOfInteger SFin; for( i = 1; i <= S.Length(); i++){ if (!ConnexionOn(S.Value(i))) break; } if ( i > 1 && i <= S.Length()) { SFin = S; SFin.Split(i,S); S.Append(SFin); } } //============================================================================= //function : Connexion //purpose : //============================================================================= Handle(MAT2d_Connexion) MAT2d_Circuit::Connexion(const Standard_Integer I)const { return connexionMap(I); } //============================================================================= //function : ConnexionOn //purpose : //============================================================================= Standard_Boolean MAT2d_Circuit::ConnexionOn(const Standard_Integer I)const { return connexionMap.IsBound(I); } //============================================================================= //function : Side //purpose : //============================================================================= Standard_Real MAT2d_Circuit::Side (const Handle(MAT2d_Connexion)& C1, const TColGeom2d_SequenceOfGeometry& Line) const { Handle(Geom2d_TrimmedCurve) Curve; gp_Vec2d Vect1(C1->PointOnSecond().X() - C1->PointOnFirst().X(), C1->PointOnSecond().Y() - C1->PointOnFirst().Y()); Curve = Handle(Geom2d_TrimmedCurve)::DownCast (Line.Value(C1->IndexItemOnFirst())); gp_Vec2d Vect2 = Curve->DN(C1->ParameterOnFirst(),1); if ( (Vect1^Vect2) > 0.) return - 1.; else return 1.; } //============================================================================= //function : PassByLast //purpose : //============================================================================= Standard_Boolean MAT2d_Circuit::PassByLast (const Handle(MAT2d_Connexion)& C1, const Handle(MAT2d_Connexion)& C2) const { if (C2->IndexFirstLine() == C1->IndexSecondLine()){ if (C2->IndexItemOnFirst() < C1->IndexItemOnSecond()) { return Standard_True; } else if (C2->IndexItemOnFirst() == C1->IndexItemOnSecond()) { if (C1->IndexFirstLine() == C2->IndexSecondLine()) { return Standard_True; } if (C2->ParameterOnFirst() == C1->ParameterOnSecond()) { gp_Vec2d Vect1(C1->PointOnSecond(),C1->PointOnFirst()); gp_Vec2d Vect2(C2->PointOnFirst(),C2->PointOnSecond()); if ((Vect1^Vect2)*direction > 0) { return Standard_True; } } else if (C2->ParameterOnFirst() < C1->ParameterOnSecond()) { return Standard_True; } } } return Standard_False; } //============================================================================= //function : UpDateLink //purpose : //============================================================================= void MAT2d_Circuit::UpDateLink(const Standard_Integer IFirst, const Standard_Integer ILine, const Standard_Integer ICurveFirst, const Standard_Integer ICurveLast) { Standard_Integer IEqui = IFirst; Standard_Integer i; for (i = ICurveFirst; i <= ICurveLast; i++) { MAT2d_BiInt Key(ILine,i); if (linkRefEqui.IsBound(Key)) { linkRefEqui(Key).Append(IEqui); } else { TColStd_SequenceOfInteger L; linkRefEqui.Bind(Key,L); linkRefEqui(Key).Append(IEqui); } IEqui++; } } //========================================================================== //function : CrossProd //purpose : Calcul le produit vectoriel et scalaire entre les directions des // tangentes a la fin de Geom1 et au debut de Geom2. // Geom1 et Geom2 doivent etre des courbes. //========================================================================== static Standard_Real CrossProd(const Handle(Geom2d_Geometry)& Geom1, const Handle(Geom2d_Geometry)& Geom2, Standard_Real& DotProd) { Handle(Geom2d_TrimmedCurve) Curve; Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Geom1); gp_Dir2d Dir1(Curve->DN(Curve->LastParameter(),1)); Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Geom2); gp_Dir2d Dir2(Curve->DN(Curve->FirstParameter(),1)); DotProd = Dir1.Dot(Dir2); return Dir1^Dir2; } #ifdef OCCT_DEBUG //========================================================================== //function : MAT2d_DrawCurve //purpose : Affichage d une courbe de Geom2d. dans une couleur // definie par . // Indice = 1 jaune, // Indice = 2 bleu, // Indice = 3 rouge, // Indice = 4 vert. //========================================================================== void MAT2d_DrawCurve(const Handle(Geom2d_Curve)& aCurve, const Standard_Integer /*Indice*/) { Handle(Standard_Type) type = aCurve->DynamicType(); Handle(Geom2d_Curve) curve,CurveDraw; #ifdef DRAW Handle(DrawTrSurf_Curve2d) dr; Draw_Color Couleur; #endif if (type == STANDARD_TYPE(Geom2d_TrimmedCurve)) { curve = Handle(Geom2d_TrimmedCurve)::DownCast(aCurve)->BasisCurve(); type = curve->DynamicType(); // PB de representation des courbes semi_infinies. gp_Parab2d gpParabola; gp_Hypr2d gpHyperbola; Standard_Real Focus; Standard_Real Limit = 50000.; Standard_Real delta = 400; // PB de representation des courbes semi_infinies. if (aCurve->LastParameter() == Precision::Infinite()) { if (type == STANDARD_TYPE(Geom2d_Parabola)) { gpParabola = Handle(Geom2d_Parabola)::DownCast(curve)->Parab2d(); Focus = gpParabola.Focal(); Standard_Real Val1 = Sqrt(Limit*Focus); Standard_Real Val2 = Sqrt(Limit*Limit); delta= (Val1 <= Val2 ? Val1:Val2); } else if (type == STANDARD_TYPE(Geom2d_Hyperbola)) { gpHyperbola = Handle(Geom2d_Hyperbola)::DownCast(curve)->Hypr2d(); Standard_Real Majr = gpHyperbola.MajorRadius(); Standard_Real Minr = gpHyperbola.MinorRadius(); Standard_Real Valu1 = Limit/Majr; Standard_Real Valu2 = Limit/Minr; Standard_Real Val1 = Log(Valu1+Sqrt(Valu1*Valu1-1)); Standard_Real Val2 = Log(Valu2+Sqrt(Valu2*Valu2+1)); delta = (Val1 <= Val2 ? Val1:Val2); } CurveDraw = new Geom2d_TrimmedCurve(aCurve, aCurve->FirstParameter(), aCurve->FirstParameter() + delta); } else { CurveDraw = aCurve; } // fin PB. } else { CurveDraw = aCurve; } #ifdef DRAW if (Indice == 1) Couleur = Draw_jaune; else if (Indice == 2) Couleur = Draw_bleu; else if (Indice == 3) Couleur = Draw_rouge; else if (Indice == 4) Couleur = Draw_vert; if (type == STANDARD_TYPE(Geom2d_Circle)) dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,30); else if (type == STANDARD_TYPE(Geom2d_Line)) dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,2); else dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,500); dout << dr; dout.Flush(); #endif } #endif