Loading files
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.
// Created on: 1994-10-27
// Created by: Jean Yves LEBEY
// Copyright (c) 1994-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 <BRep_Tool.hxx>
#include <Geom_Curve.hxx>
#include <Geom_Surface.hxx>
#include <GeomAPI_ProjectPointOnCurve.hxx>
#include <gp_Vec.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Shape.hxx>
#include <TopOpeBRep_FFTransitionTool.hxx>
#include <TopOpeBRep_LineInter.hxx>
#include <TopOpeBRep_VPointInter.hxx>
#include <TopOpeBRepDS_Transition.hxx>
//=================================================================================================
static bool TransitionToOrientation(const IntSurf_Transition& T, TopAbs_Orientation& O)
{
bool Odefined = true;
TopAbs_Orientation result = TopAbs_FORWARD;
IntSurf_TypeTrans trans;
IntSurf_Situation situa;
trans = T.TransitionType();
switch (trans)
{
case IntSurf_In:
result = TopAbs_FORWARD;
break;
case IntSurf_Out:
result = TopAbs_REVERSED;
break;
case IntSurf_Touch:
situa = T.Situation();
switch (situa)
{
case IntSurf_Inside:
result = TopAbs_INTERNAL;
break;
case IntSurf_Outside:
result = TopAbs_EXTERNAL;
break;
case IntSurf_Unknown:
Odefined = false;
break;
}
break;
case IntSurf_Undecided:
Odefined = false;
break;
}
O = result;
return Odefined;
}
//=======================================================================
// function : ProcessLineTransition
// purpose : compute the transition of the intersection
// : point <P> on the intersected shape of index <Index> (1 or 2)
// : for a line crossing an edge
//=======================================================================
TopOpeBRepDS_Transition TopOpeBRep_FFTransitionTool::ProcessLineTransition(
const TopOpeBRep_VPointInter& P,
const int Index,
const TopAbs_Orientation EdgeOrientation)
{
TopOpeBRepDS_Transition TT;
if ((EdgeOrientation == TopAbs_INTERNAL) || (EdgeOrientation == TopAbs_EXTERNAL))
{
TT.Set(EdgeOrientation);
}
else
{
TopAbs_Orientation O;
IntSurf_Transition T;
{
switch (Index)
{
case 1:
T = P.TransitionLineArc1();
break;
case 2:
T = P.TransitionLineArc2();
break;
}
bool Odefined = ::TransitionToOrientation(T, O);
if (Odefined)
{
if (EdgeOrientation == TopAbs_REVERSED)
{
O = TopAbs::Complement(O);
}
TT.Set(O);
}
else
{
TT.Set(TopAbs_UNKNOWN, TopAbs_UNKNOWN);
}
}
}
return TT;
}
//=======================================================================
// function : ProcessLineTransition
// purpose : compute the transition of point P on line L, P lying on
// neither of the intersecting shapes
//=======================================================================
TopOpeBRepDS_Transition TopOpeBRep_FFTransitionTool::ProcessLineTransition(
const TopOpeBRep_VPointInter& P,
const TopOpeBRep_LineInter& LI)
{
TopOpeBRepDS_Transition TT;
TopAbs_Orientation result;
// P.IsOnDomS1() and P.IsOnDomS2() are both false
int nbv = LI.NbVPoint();
const TopOpeBRep_VPointInter& P1 = LI.VPoint(1);
double par1 = P1.ParameterOnLine();
const TopOpeBRep_VPointInter& Pn = LI.VPoint(nbv);
double parn = Pn.ParameterOnLine();
double par = P.ParameterOnLine();
if (par == par1)
{
result = TopAbs_FORWARD;
}
else if (par == parn)
{
result = TopAbs_REVERSED;
}
else
{
result = TopAbs_INTERNAL;
}
TT.Set(result);
return TT;
}
//=======================================================================
// function : ProcessEdgeTransition
// purpose : compute the transition from the transition of the intersection
// : point <P> on the intersected shape of index <Index> (1 or 2)
// : for an edge on a line on a Face
//=======================================================================
TopOpeBRepDS_Transition TopOpeBRep_FFTransitionTool::ProcessEdgeTransition(
const TopOpeBRep_VPointInter& P,
const int Index,
const TopAbs_Orientation FaceTransition)
{
TopOpeBRepDS_Transition TT;
if ((FaceTransition == TopAbs_INTERNAL) || (FaceTransition == TopAbs_EXTERNAL))
{
TT.Set(FaceTransition);
}
else
{
IntSurf_Transition T;
if (Index == 1)
{
T = P.TransitionOnS1();
}
else if (Index == 2)
{
T = P.TransitionOnS2();
}
TopAbs_Orientation O;
bool defined = ::TransitionToOrientation(T, O);
if (defined)
{
if (FaceTransition == TopAbs_REVERSED)
{
O = TopAbs::Complement(O);
}
TT.Set(O);
}
else
{
TT.Set(TopAbs_UNKNOWN, TopAbs_UNKNOWN);
}
}
return TT;
}
//=======================================================================
// function : ProcessFaceTransition
// purpose : compute the transition from a Line
//=======================================================================
TopOpeBRepDS_Transition TopOpeBRep_FFTransitionTool::ProcessFaceTransition(
const TopOpeBRep_LineInter& L,
const int Index,
const TopAbs_Orientation FaceOrientation)
{
// If Index == 1, on first shape
// If Index == 2, on second shape
TopOpeBRepDS_Transition TT;
if ((FaceOrientation == TopAbs_INTERNAL) || (FaceOrientation == TopAbs_EXTERNAL))
{
TT.Set(FaceOrientation);
}
else
{
bool Odefined = true;
TopAbs_Orientation O = TopAbs_FORWARD;
IntSurf_TypeTrans trans;
trans = (Index == 1) ? L.TransitionOnS1() : L.TransitionOnS2();
switch (trans)
{
case IntSurf_In:
O = TopAbs_FORWARD;
break;
case IntSurf_Out:
O = TopAbs_REVERSED;
break;
case IntSurf_Touch: {
IntSurf_Situation situa;
situa = (Index == 1) ? L.SituationS1() : L.SituationS2();
switch (situa)
{
case IntSurf_Inside:
O = TopAbs_INTERNAL;
break;
case IntSurf_Outside:
O = TopAbs_EXTERNAL;
break;
case IntSurf_Unknown:
Odefined = false;
break;
}
break;
} // case Touch
case IntSurf_Undecided:
Odefined = false;
break;
} // trans
if (Odefined)
{
if (FaceOrientation == TopAbs_REVERSED)
{
O = TopAbs::Complement(O);
}
TT.Set(O);
}
else
{
TT.Set(TopAbs_UNKNOWN, TopAbs_UNKNOWN);
}
}
return TT;
}
// -------------------------------------------------
// input : P1 : point
// input : C2 : courbe, FC2,LC2 : bornes de C2
// output : T2 = parametre de P1 sur C2
// -------------------------------------------------
static bool FUN_ProjectPoint(const gp_Pnt& P1,
const occ::handle<Geom_Curve>& C2,
const double FC2,
const double LC2,
double& T2)
{
if (C2.IsNull())
{
return false;
}
GeomAPI_ProjectPointOnCurve mydist(P1, C2, FC2, LC2);
if (mydist.Extrema().IsDone())
{
if (mydist.NbPoints())
{
T2 = mydist.LowerDistanceParameter();
return true;
}
}
return false;
}
// -------------------------------------------------
// input : S1,U1,V1,C1,T1 avec D0(S1(U1,V1)) = D0(C1(T1))
// input : C2,FC2,LC2 : courbe, bornes de C2
// output : Trans : transition sur C1 en T1 en croisant C2
// -------------------------------------------------
static bool FUN_GeomTrans(const occ::handle<Geom_Surface>& S1,
const double U1,
const double V1,
const occ::handle<Geom_Curve>& C1,
const double T1,
const occ::handle<Geom_Curve>& C2,
const double FC2,
const double LC2,
TopOpeBRepDS_Transition& Trans)
{
if (C1.IsNull() || C2.IsNull())
{
return false;
}
// P1 : D0(C1(T1), D1_C1 : D1(C1(T1))
gp_Pnt P1;
gp_Vec D1_C1;
C1->D1(T1, P1, D1_C1);
// D1_C2 : D1(C2(P1))
double T2 = 0.0;
bool projok = ::FUN_ProjectPoint(P1, C2, FC2, LC2, T2);
if (!projok)
{
return false;
}
gp_Pnt P2;
gp_Vec D1_C2;
C2->D1(T2, P2, D1_C2);
// N1 : D1(S1(U1,V1))
gp_Vec N1, D1U, D1V;
gp_Pnt PS;
S1->D1(U1, V1, PS, D1U, D1V);
D1U.Normalize();
D1V.Normalize();
N1 = D1U.Crossed(D1V);
N1.Normalize();
gp_Vec N1D1_C1 = N1.Crossed(D1_C1);
double dot = N1D1_C1.Dot(D1_C2);
if (dot > 0)
{
Trans.Before(TopAbs_OUT);
Trans.After(TopAbs_IN);
}
else
{
Trans.Before(TopAbs_IN);
Trans.After(TopAbs_OUT);
}
return true;
}
//=================================================================================================
TopOpeBRepDS_Transition TopOpeBRep_FFTransitionTool::ProcessEdgeONTransition(
const TopOpeBRep_VPointInter& VP,
const int ShapeIndex,
const TopoDS_Shape& RR,
const TopoDS_Shape& EE,
const TopoDS_Shape& FF)
{
const TopoDS_Edge& R = TopoDS::Edge(RR);
const TopoDS_Edge& E = TopoDS::Edge(EE);
const TopoDS_Face& F = TopoDS::Face(FF);
TopAbs_Orientation oriE = E.Orientation();
const occ::handle<Geom_Surface>& S = BRep_Tool::Surface(F);
double U = 0., V = 0.;
if (ShapeIndex == 1)
{
VP.ParametersOnS1(U, V);
}
else if (ShapeIndex == 2)
{
VP.ParametersOnS2(U, V);
}
double fE, lE;
const occ::handle<Geom_Curve>& CE = BRep_Tool::Curve(E, fE, lE);
double TE = VP.EdgeParameter(ShapeIndex);
double fR, lR;
const occ::handle<Geom_Curve>& CR = BRep_Tool::Curve(R, fR, lR);
TopOpeBRepDS_Transition Trans;
bool transok = ::FUN_GeomTrans(S, U, V, CE, TE, CR, fR, lR, Trans);
if (transok)
{
// Trans : transition sur R en croisant l'arete E orientee dans la face F
if (oriE == TopAbs_REVERSED)
{
Trans = Trans.Complement();
}
}
return Trans;
}