Loading files
f2929057eThis file is pinned to the selected release. Download the original to open it in your design tool.
// Created on: 1999-03-23
// Created by: Xuan PHAM PHU
// Copyright (c) 1999-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 <BRepAdaptor_Surface.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec.hxx>
#include <Precision.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <TopOpeBRepTool_GEOMETRY.hxx>
#include <TopOpeBRepTool_PROJECT.hxx>
#include <TopOpeBRepTool_TOPOLOGY.hxx>
#include <TopOpeBRepTool_mkTondgE.hxx>
#include <TopOpeBRepTool_TOOL.hxx>
#define M_FORWARD(sta) (sta == TopAbs_FORWARD)
#define M_REVERSED(sta) (sta == TopAbs_REVERSED)
#define M_INTERNAL(sta) (sta == TopAbs_INTERNAL)
#define M_EXTERNAL(sta) (sta == TopAbs_EXTERNAL)
#define FORWARD (1)
#define REVERSED (2)
#define INTERNAL (3)
#define EXTERNAL (4)
#define CLOSING (5)
#define NOI (0)
#define MKI1 (1)
#define MKI2 (2)
#define MKI12 (3)
static double FUN_tola()
{
double tola = Precision::Angular();
return tola;
}
//=================================================================================================
TopOpeBRepTool_mkTondgE::TopOpeBRepTool_mkTondgE() = default;
//=================================================================================================
bool TopOpeBRepTool_mkTondgE::Initialize(const TopoDS_Edge& dgE,
const TopoDS_Face& F,
const gp_Pnt2d& uvi,
const TopoDS_Face& Fi)
{
isT2d = false;
hasRest = false;
myclE.Nullify();
myEpari.Clear();
mydgE = dgE;
myF = F;
TopExp_Explorer exv(mydgE, TopAbs_VERTEX);
const TopoDS_Vertex& v = TopoDS::Vertex(exv.Current());
double par = BRep_Tool::Parameter(v, mydgE);
gp_Pnt2d uv;
bool ok = FUN_tool_paronEF(mydgE, par, myF, uv);
if (!ok)
{
return false;
}
gp_Vec tmp;
ok = TopOpeBRepTool_TOOL::NggeomF(uv, myF, tmp);
myngf = gp_Dir(tmp);
if (!ok)
{
return false;
}
myuvi = uvi;
myFi = Fi;
bool oki = TopOpeBRepTool_TOOL::NggeomF(myuvi, myFi, tmp);
myngfi = gp_Dir(tmp);
if (!oki)
{
return false;
}
double dot = myngf.Dot(myngfi);
isT2d = (std::abs(1 - std::abs(dot)) < FUN_tola());
return true;
}
//=================================================================================================
bool TopOpeBRepTool_mkTondgE::SetclE(const TopoDS_Edge& clE)
{
myclE = clE;
return true;
}
//=================================================================================================
bool TopOpeBRepTool_mkTondgE::IsT2d() const
{
return isT2d;
}
//=================================================================================================
bool TopOpeBRepTool_mkTondgE::SetRest(const double pari, const TopoDS_Edge& Ei)
{
hasRest = true;
bool clEi = TopOpeBRepTool_TOOL::IsClosingE(Ei, myFi);
if (clEi)
{
hasRest = false;
return false;
}
myEpari.Bind(Ei, pari);
return true;
}
//=================================================================================================
int TopOpeBRepTool_mkTondgE::GetAllRest(NCollection_List<TopoDS_Shape>& lEi)
{
lEi.Clear();
BRepAdaptor_Surface bs(myFi);
double tol3d = bs.Tolerance();
double tolu = bs.UResolution(tol3d);
double tolv = bs.VResolution(tol3d);
TopExp_Explorer ex(myFi, TopAbs_EDGE);
for (; ex.More(); ex.Next())
{
const TopoDS_Edge& ei = TopoDS::Edge(ex.Current());
bool cli = TopOpeBRepTool_TOOL::IsClosingE(ei, myFi);
if (cli)
{
continue;
}
bool isbi = myEpari.IsBound(ei);
if (isbi)
{
lEi.Append(ei);
continue;
}
bool isou, isov;
gp_Dir2d d2d;
gp_Pnt2d o2d;
bool uviso = TopOpeBRepTool_TOOL::UVISO(ei, myFi, isou, isov, d2d, o2d);
if (!uviso)
{
continue;
}
bool ok = false;
if (isou)
{
ok = std::abs(o2d.X() - myuvi.X()) < tolu;
}
if (isov)
{
ok = std::abs(o2d.Y() - myuvi.Y()) < tolv;
}
if (!ok)
{
continue;
}
double parei;
TopOpeBRepTool_TOOL::ParISO(myuvi, ei, myFi, parei);
myEpari.Bind(ei, parei);
lEi.Append(ei);
}
int nEi = lEi.Extent();
return nEi;
}
static bool FUN_getEc(const TopoDS_Face& f, const TopoDS_Vertex& v, TopoDS_Edge& cle)
{
TopExp_Explorer exe(f, TopAbs_EDGE);
for (; exe.More(); exe.Next())
{
const TopoDS_Edge& e = TopoDS::Edge(exe.Current());
bool closed = TopOpeBRepTool_TOOL::IsClosingE(e, f);
if (!closed)
{
continue;
}
TopExp_Explorer exv(e, TopAbs_VERTEX);
for (; exv.More(); exv.Next())
{
if (exv.Current().IsSame(v))
{
cle = e;
return true;
}
}
}
return false;
}
static bool FUN_MkTonE(const gp_Vec& faxis,
const gp_Vec& dirINcle,
const gp_Vec& xxi,
const gp_Vec& /*ngf*/,
double& par1,
double& par2,
bool& outin)
{
// tgi / (tgi,xxi,faxis) is direct :
gp_Vec tgi = xxi.Crossed(faxis);
// ******************** getting par1, par2
// at par1 : tr(dge, ei/fi) = forward
// at par2 : tr(dge, ei/fi) = forward
double tola = FUN_tola();
double dot1 = dirINcle.Dot(xxi);
bool isONi = (std::abs(dot1) < tola);
// par1 = ang -> inout
// par2 = Cang -> outin
double ang = 1.e7;
if (isONi)
{
double dot = dirINcle.Dot(tgi);
ang = (dot > 0) ? 0 : M_PI;
// outin = (ang > 0); -xpu190499
outin = true;
}
else
{
if (!isONi)
{
ang = TopOpeBRepTool_TOOL::Matter(dirINcle, tgi.Reversed(), faxis);
}
// double dot = isONi ? 0 : (dirINcle^tgi).Dot(ngf);
double dot = isONi ? 0 : (dirINcle ^ tgi).Dot(faxis);
if (dot1 < 0)
{
outin = (dot > 0);
}
else
{
outin = (dot < 0);
}
} //! isONi
double Cang = (ang > M_PI) ? ang - M_PI : ang + M_PI;
par1 = outin ? ang : Cang;
par2 = outin ? Cang : ang;
return true;
} // FUN_MkTonE
//=================================================================================================
bool TopOpeBRepTool_mkTondgE::MkTonE(int& mkT, double& par1, double& par2)
{
if (isT2d)
{
return false;
}
mkT = NOI;
par1 = par2 = 1.e7;
// v :
TopExp_Explorer exv(mydgE, TopAbs_VERTEX);
const TopoDS_Vertex& v = TopoDS::Vertex(exv.Current());
// myclE :
if (myclE.IsNull())
{
bool find = FUN_getEc(myF, v, myclE);
if (!find)
{
return false;
}
}
// dirINcle : tangent to cle at v oriented INSIDE 1d(cle)
int ovcle;
gp_Vec dirINcle;
bool ok = TopOpeBRepTool_TOOL::TgINSIDE(v, myclE, dirINcle, ovcle);
if (!ok)
{
return NOI;
}
// faxis : describes f's axis for parametrization of <dgE>
gp_Vec faxis = myngf;
if (ovcle == FORWARD)
{
faxis.Reverse();
}
// xxi : normal to fi oriented INSIDE 3d(fi)
gp_Vec xxi;
ok = TopOpeBRepTool_TOOL::NggeomF(myuvi, myFi, xxi);
if (!ok)
{
return false;
}
if (M_FORWARD(myFi.Orientation()))
{
xxi.Reverse();
}
// mkT, par1, par2 :
bool outin;
ok = FUN_MkTonE(faxis, dirINcle, xxi, myngf, par1, par2, outin);
if (ok)
{
mkT = MKI12;
}
return ok;
}
//=================================================================================================
bool TopOpeBRepTool_mkTondgE::MkTonE(const TopoDS_Edge& ei, int& mkT, double& par1, double& par2)
// isT2d = true :
// prequesitory : f,fi are tangent on v
// dge interfers on v with ei
// purpose : the compute of transition on dge / ei
// at par1 : Tr(dge,e)= ou/in,
// at par2 : Tr(dge,e)= in/ou
//
// isT2d = false :
// prequesitory : dge interfers on v with fi
// purpose : the compute of transition on dge / fi
// at par1 : Tr(dge,e)= ou/in,
// at par2 : Tr(dge,e)= in/ou
//
{
mkT = NOI;
par1 = par2 = 1.e7;
hasRest = myEpari.IsBound(ei);
if (!hasRest)
{
return false;
}
const double pari = myEpari.Find(ei);
double pfi, pli;
FUN_tool_bounds(ei, pfi, pli);
double tolpi = TopOpeBRepTool_TOOL::TolP(ei, myFi);
bool onfi = (std::abs(pari - pfi) < tolpi), onli = (std::abs(pari - pli) < tolpi);
gp_Vec tgin1di;
bool ok = TopOpeBRepTool_TOOL::TggeomE(pari, ei, tgin1di);
if (!ok)
{
return false;
}
if (onli)
{
tgin1di.Reverse();
}
// v :
TopExp_Explorer exv(mydgE, TopAbs_VERTEX);
const TopoDS_Vertex& v = TopoDS::Vertex(exv.Current());
// myclE :
if (myclE.IsNull())
{
bool find = FUN_getEc(myF, v, myclE);
if (!find)
{
return false;
}
}
// dirINcle : tangent to cle at v oriented INSIDE 1d(cle)
int ovcle;
gp_Vec dirINcle;
ok = TopOpeBRepTool_TOOL::TgINSIDE(v, myclE, dirINcle, ovcle);
if (!ok)
{
return NOI;
}
if (isT2d && !hasRest)
{
return false; // no transition to compute
}
// faxis : describes f's axis for parametrization of <dgE>
gp_Vec faxis = myngf;
if (ovcle == FORWARD)
{
faxis.Reverse();
}
gp_Dir xxi; // isT2d=true : normal to ei oriented INSIDE 2d(fi)
// normal to fi oriented INSIDE 3d(fi)
gp_Dir xxri; // isT2d=true : oriented inside 1d(ei)
// oriented inside 2d(fi)
TopoDS_Vertex vclo;
bool closedi = TopOpeBRepTool_TOOL::ClosedE(ei, vclo); //@190499
bool outin;
if (isT2d)
{
// xxi :
ok = TopOpeBRepTool_TOOL::XX(myuvi, myFi, pari, ei, xxi);
if (!ok)
{
return false;
}
// mkT,par1,par2
ok = FUN_MkTonE(faxis, dirINcle, xxi, myngf, par1, par2, outin);
if (!ok)
{
return false;
}
// clang-format off
if (!onfi && !onli) {mkT = MKI12; return true;}// => the same for all edges of lei @190499
// clang-format on
if (closedi)
{
mkT = MKI12;
return true;
} // onfi || onli @190499
// xxri :
xxri = tgin1di;
} // isT2d
else
{
// xxi :
gp_Vec tmp;
ok = TopOpeBRepTool_TOOL::NggeomF(myuvi, myFi, tmp);
xxi = gp_Dir(tmp);
if (!ok)
{
return false;
}
if (M_FORWARD(myFi.Orientation()))
{
xxi.Reverse();
}
// mkT,par1,par2
ok = FUN_MkTonE(faxis, dirINcle, xxi, myngf, par1, par2, outin);
if (!ok)
{
return false;
}
//// modified by jgv, 21.11.01 for BUC61053 ////
ok = TopOpeBRepTool_TOOL::XX(myuvi, myFi, pari, ei, xxri);
if (!ok)
{
return false;
}
mkT = MKI12; // without restrictions.
gp_Vec tgi = xxi.Crossed(faxis); // tgi /(tgi,xxi,faxis) is direct :
double dot = tgi.Dot(xxri);
if (std::abs(dot) < FUN_tola())
{
if ((!onfi && !onli) || closedi)
{
mkT = MKI12;
return true;
}
else
{
dot = tgi.Dot(tgin1di);
}
}
bool keepang = (dot > 0);
if (keepang)
{
mkT = outin ? MKI1 : MKI2;
}
else
{
mkT = outin ? MKI2 : MKI1;
}
return true;
////////////////////////////////////////////////
/*
// xxri :
double ddot = tgin1di.Dot(faxis);
// clang-format off
bool tgaxis = std::abs(1-(std::abs(ddot))) < FUN_tola(); //=true : edge is
tangent to sphere's axis
// clang-format on
if (tgaxis) {
ok = TopOpeBRepTool_TOOL::XX(myuvi,myFi, pari,ei, xxri);
if (!ok) return false;
}
else {
if ((!onfi) && (!onli)) {mkT = MKI12; return true;} // @190499
if (closedi) {mkT = MKI12; return true;}// onfi || onli @190499
xxri = tgin1di;
}*/
} //! isT2d
mkT = MKI12; // without restrictions.
gp_Vec tgi = xxi.Crossed(faxis); // tgi /(tgi,xxi,faxis) is direct :
double dot = tgi.Dot(xxri);
bool keepang = (dot > 0);
if (keepang)
{
mkT = outin ? MKI1 : MKI2;
}
else
{
mkT = outin ? MKI2 : MKI1;
}
return true;
}