1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-03 17:56:21 +03:00
occt/src/TopTrans/TopTrans_CurveTransition.cxx
2021-05-10 14:29:42 +03:00

371 lines
10 KiB
C++

// Created on: 1992-01-23
// Created by: Didier PIFFAULT
// Copyright (c) 1992-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 <gp_Dir.hxx>
#include <TopAbs.hxx>
#include <TopTrans_CurveTransition.hxx>
#define GREATER 1
#define SAME 0
#define LOWER -1
//=======================================================================
//function : TopTrans_CurveTransition
//purpose : Empty Constructor.
//=======================================================================
TopTrans_CurveTransition::TopTrans_CurveTransition ()
: myCurv(0.0),
Init(Standard_False),
CurvFirst(0.0),
CurvLast(0.0)
{
}
//=======================================================================
//function : Reset
//purpose : Initializer for a complex curve transition with the elements
// of the intersecting curve.
//=======================================================================
void TopTrans_CurveTransition::Reset (const gp_Dir& Tgt,
const gp_Dir& Norm,
const Standard_Real Curv)
{
myTgt=Tgt; myNorm=Norm; myCurv=Curv; Init=Standard_True;
}
//=======================================================================
//function : Reset
//purpose : Initializer for a complex curve transition with the elements
// of the intersecting straight line.
//=======================================================================
void TopTrans_CurveTransition::Reset (const gp_Dir& Tgt)
{
myTgt=Tgt; myCurv=0.; Init=Standard_True;
}
//=======================================================================
//function : Compare
//purpose : Compare the elements of an interference on an intersected
// curve with the interference stored in the complex Transition.
//=======================================================================
void TopTrans_CurveTransition::Compare (const Standard_Real Tole,
const gp_Dir& T,
const gp_Dir& N,
const Standard_Real C,
const TopAbs_Orientation St,
const TopAbs_Orientation Or)
{
// S is the transition, how the curve cross the boundary
// O is the orientation, how the intersection is set on the boundary
TopAbs_Orientation S = St;
TopAbs_Orientation O = Or;
// adjustment for INTERNAL transition
if (S == TopAbs_INTERNAL) {
if (T * myTgt < 0)
S = TopAbs::Reverse(O);
else
S = O;
}
// It is the first comparison for this complex transition
if (Init) {
Init=Standard_False;
TgtFirst =T;
NormFirst=N;
CurvFirst=C;
TranFirst=S;
TgtLast =T;
NormLast =N;
CurvLast =C;
TranLast =S;
switch (O) {
// Interference en fin d'arete il faut inverser la tangente
case TopAbs_REVERSED :
TgtFirst.Reverse();
TgtLast.Reverse();
break;
case TopAbs_INTERNAL :
// Interference en milieu d'arete il faut inverser en fonction de la
// position de la tangente de reference
if (myTgt*T>0) TgtFirst.Reverse();
else TgtLast.Reverse();
break;
case TopAbs_FORWARD :
case TopAbs_EXTERNAL :
break;
}
}
// Compare with the existent first and last transition :
else {
Standard_Boolean FirstSet=Standard_False;
Standard_Real cosAngWithT=myTgt*T;
switch (O) {
case TopAbs_REVERSED :
cosAngWithT= -cosAngWithT;
break;
case TopAbs_INTERNAL :
if (cosAngWithT>0) cosAngWithT=-cosAngWithT;
break;
case TopAbs_FORWARD :
case TopAbs_EXTERNAL :
break;
}
Standard_Real cosAngWith1=myTgt*TgtFirst;
switch (Compare(cosAngWithT, cosAngWith1, Tole)) {
case LOWER :
// If the angle is greater than the first the new become the first
FirstSet=Standard_True;
TgtFirst =T;
switch (O) {
case TopAbs_REVERSED :
TgtFirst.Reverse();
break;
case TopAbs_INTERNAL :
if (myTgt*T>0) TgtFirst.Reverse();
break;
case TopAbs_FORWARD :
case TopAbs_EXTERNAL :
break;
}
NormFirst=N;
CurvFirst=C;
TranFirst=S;
break;
case SAME :
// If same angles we look at the Curvature
if (IsBefore(Tole, cosAngWithT, N, C, NormFirst, CurvFirst)) {
FirstSet=Standard_True;
TgtFirst =T;
switch (O) {
case TopAbs_REVERSED :
TgtFirst.Reverse();
break;
case TopAbs_INTERNAL :
if (myTgt*T>0) TgtFirst.Reverse();
break;
case TopAbs_FORWARD :
case TopAbs_EXTERNAL :
break;
}
NormFirst=N;
CurvFirst=C;
TranFirst=S;
}
break;
case GREATER:
break;
}
if (!FirstSet || O==TopAbs_INTERNAL) {
// Dans les cas de tangence le premier peut etre aussi le dernier
if (O==TopAbs_INTERNAL) cosAngWithT=-cosAngWithT;
Standard_Real cosAngWith2=myTgt*TgtLast;
switch (Compare(cosAngWithT, cosAngWith2, Tole)) {
case GREATER:
// If the angle is lower than the last the new become the last
TgtLast =T;
switch (O) {
case TopAbs_REVERSED :
TgtLast.Reverse();
break;
case TopAbs_INTERNAL :
if (myTgt*T<0) TgtLast.Reverse();
break;
case TopAbs_FORWARD :
case TopAbs_EXTERNAL :
break;
}
NormLast =N;
CurvLast =C;
TranLast =S;
break;
case SAME:
// If the angle is the same we look at the curvature
if (IsBefore(Tole, cosAngWithT, NormLast, CurvLast, N, C)) {
TgtLast =T;
switch (O) {
case TopAbs_REVERSED :
TgtLast.Reverse();
break;
case TopAbs_INTERNAL :
if (myTgt*T<0) TgtLast.Reverse();
break;
case TopAbs_FORWARD :
case TopAbs_EXTERNAL :
break;
}
NormLast=N;
CurvLast=C;
TranLast=S;
}
}
}
}
}
//=======================================================================
//function : StateBefore
//purpose : Give the state of the curv before the interference.
//=======================================================================
TopAbs_State TopTrans_CurveTransition::StateBefore () const
{
if (Init) return TopAbs_UNKNOWN;
switch (TranFirst)
{
case TopAbs_FORWARD :
case TopAbs_EXTERNAL :
return TopAbs_OUT;
case TopAbs_REVERSED :
case TopAbs_INTERNAL :
return TopAbs_IN;
}
return TopAbs_OUT;
}
//=======================================================================
//function : StateAfter
//purpose : give the state of the curve after the interference.
//=======================================================================
TopAbs_State TopTrans_CurveTransition::StateAfter () const
{
if (Init) return TopAbs_UNKNOWN;
switch (TranLast)
{
case TopAbs_FORWARD :
case TopAbs_INTERNAL :
return TopAbs_IN;
case TopAbs_REVERSED :
case TopAbs_EXTERNAL :
return TopAbs_OUT;
}
return TopAbs_OUT;
}
//=======================================================================
//function : IsBefore
//purpose : Compare the curvature of the two transition and return true
// if T1 is before T2
//=======================================================================
Standard_Boolean TopTrans_CurveTransition::IsBefore
(const Standard_Real Tole,
const Standard_Real CosAngl,
const gp_Dir& N1,
const Standard_Real C1,
const gp_Dir& N2,
const Standard_Real C2) const
{
Standard_Real TN1=myTgt*N1;
Standard_Real TN2=myTgt*N2;
Standard_Boolean OneBefore=Standard_False;
if (Abs(TN1)<=Tole || Abs(TN2)<=Tole) {
// Tangent : The first is the interference which have the nearest curvature
// from the reference.
if (myCurv==0) {
// The reference is straight
// The first is the interference which have the lowest curvature.
if (C1<C2) OneBefore=Standard_True;
// Modified by Sergey KHROMOV - Wed Dec 27 17:08:49 2000 Begin
if (CosAngl>0)
OneBefore=!OneBefore;
// Modified by Sergey KHROMOV - Wed Dec 27 17:08:50 2000 End
}
else {
// The reference is curv
// The first is the interference which have the nearest curvature
// in the direction
Standard_Real deltaC1, deltaC2;
if (C1==0. || myCurv==0.) {
deltaC1=C1-myCurv;
}
else {
deltaC1=(C1-myCurv)*(N1*myNorm);
}
if (C2==0. || myCurv==0.) {
deltaC2=C2-myCurv;
}
else {
deltaC2=(C2-myCurv)*(N2*myNorm);
}
if (deltaC1 < deltaC2) OneBefore=Standard_True;
if (CosAngl>0) OneBefore=!OneBefore;
}
}
else if (TN1<0) {
// Before the first interference we are in the curvature
if (TN2>0) {
// Before the second interference we are out the curvature
// The first interference is before /* ->)( */
OneBefore=Standard_True;
}
else {
// Before the second interference we are in the curvature
if (C1>C2) {
// We choice the greater curvature
// The first interference is before /* ->)) */
OneBefore=Standard_True;
}
}
}
else if (TN1>0) {
// Before the first interference we are out the curvature
if (TN2>0) {
// Before the second interference we are out the curvature /* ->(( */
if (C1<C2) {
// We choice the lower curvature
// The first interference is before
OneBefore=Standard_True;
}
}
}
return OneBefore;
}
//=======================================================================
//function : Compare
//purpose : Compare two angles
//=======================================================================
Standard_Integer TopTrans_CurveTransition::Compare(const Standard_Real Ang1,
const Standard_Real Ang2,
const Standard_Real Tole) const
{
Standard_Integer res=SAME;
if (Ang1 - Ang2 > Tole) res=GREATER;
else if (Ang2 - Ang1 > Tole) res=LOWER;
return res;
}