mirror of
https://github.com/Open-Cascade-SAS/OCCT.git
synced 2026-08-10 08:19:37 +08:00
6c24544fe1
- Refactor boolean expressions and improve code readability across multiple files - Simplified boolean expressions by removing unnecessary comparisons to true/false. - Replaced explicit boolean checks with direct variable usage Used flags: readability-static-accessed-through-instance readability-simplify-boolean-expr performance-for-range-copy performance-move-const-arg misc-unused-parameters misc-redundant-expression
1855 lines
55 KiB
C++
1855 lines
55 KiB
C++
// Created on: 1998-11-26
|
|
// Created by: Xuan PHAM PHU
|
|
// Copyright (c) 1998-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 <Bnd_Box.hxx>
|
|
#include <BRep_Builder.hxx>
|
|
#include <BRep_Tool.hxx>
|
|
#include <BRepAdaptor_Surface.hxx>
|
|
#include <BRepBndLib.hxx>
|
|
#include <BRepLProp_CLProps.hxx>
|
|
#include <ElCLib.hxx>
|
|
#include <Geom2d_Curve.hxx>
|
|
#include <Geom2d_Line.hxx>
|
|
#include <Geom2dAPI_ProjectPointOnCurve.hxx>
|
|
#include <GeomLProp_SLProps.hxx>
|
|
#include <gp_Circ.hxx>
|
|
#include <gp_Cone.hxx>
|
|
#include <gp_Cylinder.hxx>
|
|
#include <gp_Dir.hxx>
|
|
#include <gp_Dir2d.hxx>
|
|
#include <gp_Elips.hxx>
|
|
#include <gp_Hypr.hxx>
|
|
#include <gp_Lin.hxx>
|
|
#include <gp_Parab.hxx>
|
|
#include <gp_Pnt.hxx>
|
|
#include <gp_Pnt2d.hxx>
|
|
#include <gp_Sphere.hxx>
|
|
#include <gp_Torus.hxx>
|
|
#include <gp_Vec.hxx>
|
|
#include <gp_Vec2d.hxx>
|
|
#include <NCollection_Array1.hxx>
|
|
#include <Precision.hxx>
|
|
#include <NCollection_IndexedMap.hxx>
|
|
#include <TopExp.hxx>
|
|
#include <TopExp_Explorer.hxx>
|
|
#include <TopoDS.hxx>
|
|
#include <TopoDS_Edge.hxx>
|
|
#include <TopoDS_Face.hxx>
|
|
#include <TopoDS_Iterator.hxx>
|
|
#include <TopoDS_Shape.hxx>
|
|
#include <TopoDS_Vertex.hxx>
|
|
#include <TopOpeBRepTool.hxx>
|
|
#include <TopOpeBRepTool_2d.hxx>
|
|
#include <TopOpeBRepTool_C2DF.hxx>
|
|
#include <TopAbs_ShapeEnum.hxx>
|
|
#include <TopAbs_Orientation.hxx>
|
|
#include <TopAbs_State.hxx>
|
|
#include <TopTools_ShapeMapHasher.hxx>
|
|
#include <NCollection_Map.hxx>
|
|
#include <NCollection_List.hxx>
|
|
#include <NCollection_DataMap.hxx>
|
|
#include <Standard_Integer.hxx>
|
|
#include <NCollection_IndexedDataMap.hxx>
|
|
#include <TCollection_AsciiString.hxx>
|
|
#include <TopOpeBRepTool_GEOMETRY.hxx>
|
|
#include <TopOpeBRepTool_PROJECT.hxx>
|
|
#include <TopOpeBRepTool_TOPOLOGY.hxx>
|
|
#include <TopOpeBRepTool_ShapeTool.hxx>
|
|
#include <TopOpeBRepTool_TOOL.hxx>
|
|
|
|
#include <algorithm>
|
|
#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)
|
|
|
|
static bool FUN_nullprodv(const double prodv)
|
|
{
|
|
// double tola = Precision::Angular()*1.e+1; // NYI
|
|
double tola = 1.e-6; // NYI NYI NYI : for case cto 012 I2
|
|
return (std::abs(prodv) < tola);
|
|
}
|
|
|
|
// modified by NIZNHY-PKV Fri Aug 4 11:22:57 2000 from
|
|
|
|
//=================================================================================================
|
|
|
|
static bool CheckEdgeLength(const TopoDS_Edge& E)
|
|
{
|
|
BRepAdaptor_Curve BC(E);
|
|
|
|
NCollection_IndexedMap<TopoDS_Shape, TopTools_ShapeMapHasher> aM;
|
|
TopExp::MapShapes(E, TopAbs_VERTEX, aM);
|
|
int i, anExtent, aN = 10;
|
|
double ln = 0., d, t, f, l, dt;
|
|
anExtent = aM.Extent();
|
|
|
|
if (anExtent != 1)
|
|
return true;
|
|
|
|
gp_Pnt p1, p2;
|
|
f = BC.FirstParameter();
|
|
l = BC.LastParameter();
|
|
dt = (l - f) / aN;
|
|
|
|
BC.D0(f, p1);
|
|
for (i = 1; i <= aN; i++)
|
|
{
|
|
t = f + i * dt;
|
|
|
|
if (i == aN)
|
|
BC.D0(l, p2);
|
|
else
|
|
BC.D0(t, p2);
|
|
|
|
d = p1.Distance(p2);
|
|
ln += d;
|
|
p1 = p2;
|
|
}
|
|
|
|
return (ln > Precision::Confusion());
|
|
}
|
|
|
|
// modified by NIZNHY-PKV Fri Aug 4 11:23:07 2000 to
|
|
|
|
//=================================================================================================
|
|
|
|
int TopOpeBRepTool_TOOL::OriinSor(const TopoDS_Shape& sub,
|
|
const TopoDS_Shape& S,
|
|
const bool checkclo)
|
|
{
|
|
if (checkclo)
|
|
{
|
|
bool Sclosed = false;
|
|
if (S.ShapeType() == TopAbs_EDGE)
|
|
{
|
|
if (sub.ShapeType() != TopAbs_VERTEX)
|
|
return 0;
|
|
|
|
TopoDS_Vertex vclo;
|
|
Sclosed = TopOpeBRepTool_TOOL::ClosedE(TopoDS::Edge(S), vclo);
|
|
if (Sclosed)
|
|
if (sub.IsSame(vclo))
|
|
return CLOSING;
|
|
}
|
|
else if (S.ShapeType() == TopAbs_FACE)
|
|
{
|
|
if (sub.ShapeType() != TopAbs_EDGE)
|
|
return 0;
|
|
|
|
Sclosed = ClosedS(TopoDS::Face(S));
|
|
if (Sclosed)
|
|
if (IsClosingE(TopoDS::Edge(sub), TopoDS::Face(S)))
|
|
return CLOSING;
|
|
}
|
|
}
|
|
|
|
TopExp_Explorer ex(S, sub.ShapeType());
|
|
for (; ex.More(); ex.Next())
|
|
{
|
|
const TopoDS_Shape& ssub = ex.Current();
|
|
bool same = ssub.IsSame(sub);
|
|
if (!same)
|
|
continue;
|
|
TopAbs_Orientation osub = ssub.Orientation();
|
|
if (M_FORWARD(osub))
|
|
return FORWARD;
|
|
else if (M_REVERSED(osub))
|
|
return REVERSED;
|
|
else if (M_INTERNAL(osub))
|
|
return INTERNAL;
|
|
else if (M_EXTERNAL(osub))
|
|
return EXTERNAL;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
int TopOpeBRepTool_TOOL::OriinSorclosed(const TopoDS_Shape& sub, const TopoDS_Shape& S)
|
|
{
|
|
if (S.ShapeType() == TopAbs_EDGE)
|
|
{
|
|
if (sub.ShapeType() != TopAbs_VERTEX)
|
|
return 0;
|
|
}
|
|
else if (S.ShapeType() == TopAbs_FACE)
|
|
{
|
|
if (sub.ShapeType() != TopAbs_EDGE)
|
|
return 0;
|
|
}
|
|
TopoDS_Iterator it(S);
|
|
for (; it.More(); it.Next())
|
|
{
|
|
const TopoDS_Shape& ssub = it.Value();
|
|
bool equal = ssub.IsEqual(sub);
|
|
if (!equal)
|
|
continue;
|
|
TopAbs_Orientation osub = ssub.Orientation();
|
|
if (M_FORWARD(osub))
|
|
return FORWARD;
|
|
else if (M_REVERSED(osub))
|
|
return REVERSED;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::ClosedE(const TopoDS_Edge& E, TopoDS_Vertex& vclo)
|
|
{
|
|
// returns true if <E> has a closing vertex <vclosing>
|
|
// return E.IsClosed();
|
|
bool isdgE = BRep_Tool::Degenerated(E);
|
|
if (isdgE)
|
|
return false;
|
|
|
|
TopoDS_Shape vv;
|
|
vclo.Nullify();
|
|
TopExp_Explorer ex(E, TopAbs_VERTEX);
|
|
for (; ex.More(); ex.Next())
|
|
{
|
|
const TopoDS_Shape& v = ex.Current();
|
|
if (M_INTERNAL(v.Orientation()))
|
|
continue;
|
|
if (vv.IsNull())
|
|
vv = v;
|
|
else if (v.IsSame(vv))
|
|
{
|
|
vclo = TopoDS::Vertex(vv);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::ClosedS(const TopoDS_Face& F)
|
|
{
|
|
occ::handle<Geom_Surface> S = TopOpeBRepTool_ShapeTool::BASISSURFACE(TopoDS::Face(F));
|
|
if (S.IsNull())
|
|
return false;
|
|
bool uclosed = S->IsUClosed();
|
|
if (uclosed)
|
|
uclosed = S->IsUPeriodic();
|
|
bool vclosed = S->IsVClosed();
|
|
if (vclosed)
|
|
vclosed = S->IsVPeriodic();
|
|
return (uclosed || vclosed);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::IsClosingE(const TopoDS_Edge& E, const TopoDS_Face& F)
|
|
{
|
|
int nbocc = 0;
|
|
TopExp_Explorer exp(F, TopAbs_EDGE);
|
|
for (; exp.More(); exp.Next())
|
|
if (exp.Current().IsSame(E))
|
|
nbocc++;
|
|
if (nbocc != 2)
|
|
return false;
|
|
return BRep_Tool::IsClosed(E, F);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::IsClosingE(const TopoDS_Edge& E,
|
|
const TopoDS_Shape& W,
|
|
const TopoDS_Face& F)
|
|
{
|
|
int nbocc = 0;
|
|
TopExp_Explorer exp(W, TopAbs_EDGE);
|
|
for (; exp.More(); exp.Next())
|
|
if (exp.Current().IsSame(E))
|
|
nbocc++;
|
|
if (nbocc != 2)
|
|
return false;
|
|
return BRep_Tool::IsClosed(E, F);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
void TopOpeBRepTool_TOOL::Vertices(const TopoDS_Edge& E, NCollection_Array1<TopoDS_Shape>& Vces)
|
|
{
|
|
// Returns vertices (F,R) if E is FORWARD
|
|
// (R,V) if E is REVERSED
|
|
TopAbs_Orientation oriE = E.Orientation();
|
|
TopoDS_Vertex v1, v2;
|
|
TopExp::Vertices(E, v1, v2);
|
|
|
|
if (M_INTERNAL(oriE) || M_EXTERNAL(oriE))
|
|
{
|
|
Vces.ChangeValue(1) = v1;
|
|
Vces.ChangeValue(2) = v2;
|
|
}
|
|
|
|
double par1 = BRep_Tool::Parameter(v1, E);
|
|
double par2 = BRep_Tool::Parameter(v2, E);
|
|
#ifdef OCCT_DEBUG
|
|
// if (par1>par2) std::cout<<"TopOpeBRepTool_TOOL::Vertices ERROR"<<std::endl;
|
|
#endif
|
|
int ivparSMA = (par1 < par2) ? FORWARD : REVERSED;
|
|
int ivparSUP = (par1 < par2) ? REVERSED : FORWARD;
|
|
if (M_REVERSED(oriE))
|
|
{
|
|
ivparSMA = (ivparSMA == FORWARD) ? REVERSED : FORWARD;
|
|
ivparSUP = (ivparSUP == REVERSED) ? FORWARD : REVERSED;
|
|
}
|
|
Vces.ChangeValue(ivparSMA) = v1;
|
|
Vces.ChangeValue(ivparSUP) = v2;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
TopoDS_Vertex TopOpeBRepTool_TOOL::Vertex(const int Iv, const TopoDS_Edge& E)
|
|
{
|
|
NCollection_Array1<TopoDS_Shape> Vces(1, 2);
|
|
Vertices(E, Vces);
|
|
TopoDS_Vertex V = TopoDS::Vertex(Vces(Iv));
|
|
return V;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
double TopOpeBRepTool_TOOL::ParE(const int Iv, const TopoDS_Edge& E)
|
|
{
|
|
const TopoDS_Vertex& v = Vertex(Iv, E);
|
|
return (BRep_Tool::Parameter(v, E));
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
int TopOpeBRepTool_TOOL::OnBoundary(const double par, const TopoDS_Edge& e)
|
|
{
|
|
BRepAdaptor_Curve bc(e);
|
|
bool closed = bc.IsClosed();
|
|
double first = bc.FirstParameter();
|
|
double last = bc.LastParameter();
|
|
double tole = bc.Tolerance();
|
|
double tolp = bc.Resolution(tole);
|
|
|
|
bool onf = std::abs(par - first) < tolp;
|
|
bool onl = std::abs(par - last) < tolp;
|
|
bool onfl = (onf || onl);
|
|
if (onfl && closed)
|
|
return CLOSING;
|
|
if (onf)
|
|
return FORWARD;
|
|
if (onl)
|
|
return REVERSED;
|
|
if ((first < par) && (par < last))
|
|
return INTERNAL;
|
|
return EXTERNAL;
|
|
}
|
|
|
|
static void FUN_tool_sortVonE(NCollection_List<TopoDS_Shape>& lov, const TopoDS_Edge& E)
|
|
{
|
|
NCollection_DataMap<int, TopoDS_Shape> mapiv; // mapiv.Find(iV) = V
|
|
NCollection_IndexedMap<double> mappar; // mappar.FindIndex(parV) = iV
|
|
|
|
for (NCollection_List<TopoDS_Shape>::Iterator itlove(lov); itlove.More(); itlove.Next())
|
|
{
|
|
const TopoDS_Vertex& v = TopoDS::Vertex(itlove.Value());
|
|
double par = BRep_Tool::Parameter(v, E);
|
|
int iv = mappar.Add(par);
|
|
mapiv.Bind(iv, v);
|
|
}
|
|
int nv = mapiv.Extent();
|
|
NCollection_Array1<double> tabpar(1, nv);
|
|
// for (int i = 1; i <= nv; i++) {
|
|
int i;
|
|
for (i = 1; i <= nv; i++)
|
|
{
|
|
double p = mappar.FindKey(i);
|
|
tabpar.SetValue(i, p);
|
|
}
|
|
|
|
NCollection_List<TopoDS_Shape> newlov;
|
|
std::sort(tabpar.begin(), tabpar.end());
|
|
for (i = 1; i <= nv; i++)
|
|
{
|
|
double par = tabpar.Value(i);
|
|
int iv = mappar.FindIndex(par);
|
|
const TopoDS_Shape& v = mapiv.Find(iv);
|
|
newlov.Append(v);
|
|
}
|
|
lov.Clear();
|
|
lov.Append(newlov);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::SplitE(const TopoDS_Edge& Eanc, NCollection_List<TopoDS_Shape>& Splits)
|
|
{
|
|
// prequesitory : <Eanc> is a valid edge.
|
|
TopAbs_Orientation oEanc = Eanc.Orientation();
|
|
TopoDS_Shape aLocalShape = Eanc.Oriented(TopAbs_FORWARD);
|
|
TopoDS_Edge EFOR = TopoDS::Edge(aLocalShape);
|
|
// TopoDS_Edge EFOR = TopoDS::Edge(Eanc.Oriented(TopAbs_FORWARD));
|
|
NCollection_List<TopoDS_Shape> lov;
|
|
TopExp_Explorer exv(EFOR, TopAbs_VERTEX);
|
|
for (; exv.More(); exv.Next())
|
|
{
|
|
const TopoDS_Shape& v = exv.Current();
|
|
lov.Append(v);
|
|
}
|
|
int nv = lov.Extent();
|
|
if (nv <= 2)
|
|
return false;
|
|
|
|
::FUN_tool_sortVonE(lov, EFOR);
|
|
|
|
TopoDS_Vertex v0;
|
|
NCollection_List<TopoDS_Shape>::Iterator itlov(lov);
|
|
if (itlov.More())
|
|
{
|
|
v0 = TopoDS::Vertex(itlov.Value());
|
|
itlov.Next();
|
|
}
|
|
else
|
|
return false;
|
|
|
|
for (; itlov.More(); itlov.Next())
|
|
{
|
|
TopoDS_Vertex v = TopoDS::Vertex(itlov.Value());
|
|
|
|
// prequesitory: par0 < par
|
|
double par0 = BRep_Tool::Parameter(v0, EFOR);
|
|
double par = BRep_Tool::Parameter(v, EFOR);
|
|
|
|
// here, ed has the same geometries than Ein, but with no subshapes.
|
|
TopoDS_Edge ed;
|
|
FUN_ds_CopyEdge(EFOR, ed);
|
|
BRep_Builder BB;
|
|
v0.Orientation(TopAbs_FORWARD);
|
|
BB.Add(ed, v0);
|
|
FUN_ds_Parameter(ed, v0, par0);
|
|
v.Orientation(TopAbs_REVERSED);
|
|
BB.Add(ed, v);
|
|
FUN_ds_Parameter(ed, v, par);
|
|
Splits.Append(ed.Oriented(oEanc));
|
|
v0 = v;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
gp_Pnt2d TopOpeBRepTool_TOOL::UVF(const double par, const TopOpeBRepTool_C2DF& C2DF)
|
|
{
|
|
double f, l, tol;
|
|
const occ::handle<Geom2d_Curve>& PC = C2DF.PC(f, l, tol);
|
|
gp_Pnt2d UV;
|
|
PC->D0(par, UV);
|
|
return UV;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::ParISO(const gp_Pnt2d& uv,
|
|
const TopoDS_Edge& E,
|
|
const TopoDS_Face& F,
|
|
double& par)
|
|
{
|
|
par = 1.e7;
|
|
bool isou, isov;
|
|
gp_Dir2d d2d;
|
|
gp_Pnt2d o2d;
|
|
bool uviso = TopOpeBRepTool_TOOL::UVISO(E, F, isou, isov, d2d, o2d);
|
|
if (!uviso)
|
|
return false;
|
|
if (isou)
|
|
{
|
|
par = (uv.Y() - o2d.Y());
|
|
if (d2d.Y() < 0)
|
|
par = -par;
|
|
}
|
|
if (isov)
|
|
{
|
|
par = (uv.X() - o2d.X());
|
|
if (d2d.X() < 0)
|
|
par = -par;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::ParE2d(const gp_Pnt2d& p2d,
|
|
const TopoDS_Edge& E,
|
|
const TopoDS_Face& F,
|
|
double& par,
|
|
double& dist)
|
|
{
|
|
// Avoid projections if possible :
|
|
BRepAdaptor_Curve2d BC2d(E, F);
|
|
GeomAbs_CurveType CT = BC2d.GetType();
|
|
const occ::handle<Geom2d_Curve>& C2d = BC2d.Curve();
|
|
if (CT == GeomAbs_Line)
|
|
{
|
|
bool isoU, isoV;
|
|
gp_Pnt2d Loc;
|
|
gp_Dir2d dir2d;
|
|
TopOpeBRepTool_TOOL::UVISO(C2d, isoU, isoV, dir2d, Loc);
|
|
if (isoU)
|
|
{
|
|
par = p2d.Y() - Loc.Y();
|
|
dist = std::abs(p2d.X() - Loc.X());
|
|
}
|
|
if (isoV)
|
|
{
|
|
par = p2d.X() - Loc.X();
|
|
dist = std::abs(p2d.Y() - Loc.Y());
|
|
}
|
|
if (isoU || isoV)
|
|
return true;
|
|
}
|
|
|
|
Geom2dAPI_ProjectPointOnCurve proj(p2d, C2d);
|
|
dist = p2d.Distance(proj.NearestPoint());
|
|
par = proj.LowerDistanceParameter();
|
|
return true;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::TgINSIDE(const TopoDS_Vertex& v,
|
|
const TopoDS_Edge& E,
|
|
gp_Vec& Tg,
|
|
int& OvinE)
|
|
{
|
|
TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD);
|
|
TopoDS_Edge EFOR = TopoDS::Edge(aLocalShape);
|
|
// TopoDS_Edge EFOR = TopoDS::Edge(E.Oriented(TopAbs_FORWARD));
|
|
int ovE = TopOpeBRepTool_TOOL::OriinSor(v, EFOR, true);
|
|
if (ovE == 0)
|
|
return false;
|
|
OvinE = ovE;
|
|
int iv = 0;
|
|
if (ovE == CLOSING)
|
|
iv = FORWARD;
|
|
else if ((ovE == FORWARD) || (ovE == REVERSED))
|
|
iv = ovE;
|
|
double parE;
|
|
if (iv == 0)
|
|
parE = BRep_Tool::Parameter(v, E);
|
|
else
|
|
parE = TopOpeBRepTool_TOOL::ParE(iv, EFOR);
|
|
bool ok = TopOpeBRepTool_TOOL::TggeomE(parE, EFOR, Tg);
|
|
if (!ok)
|
|
return false;
|
|
if (ovE == REVERSED)
|
|
Tg.Reverse();
|
|
return true;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::TggeomE(const double par, const BRepAdaptor_Curve& BC, gp_Vec& Tg)
|
|
{
|
|
// #ifdef OCCT_DEBUG
|
|
// GeomAbs_CurveType ct =
|
|
// #endif
|
|
// BC.GetType();
|
|
// #ifdef OCCT_DEBUG
|
|
// bool apoles = (ct == GeomAbs_BezierCurve)||(ct == GeomAbs_BSplineCurve);
|
|
// #endif
|
|
|
|
double f = BC.FirstParameter(), l = BC.LastParameter();
|
|
double tolE = BC.Tolerance();
|
|
double tolp = BC.Resolution(tolE);
|
|
|
|
bool onf = std::abs(f - par) < tolp;
|
|
bool onl = std::abs(l - par) < tolp;
|
|
bool inbounds = (f < par) && (par < l);
|
|
|
|
if ((!inbounds) && (!onf) && (!onl))
|
|
return false;
|
|
double thepar = par;
|
|
|
|
gp_Pnt thepnt;
|
|
BC.D1(thepar, thepnt, Tg);
|
|
Tg.Normalize();
|
|
return true;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::TggeomE(const double par, const TopoDS_Edge& E, gp_Vec& Tg)
|
|
{
|
|
bool isdgE = BRep_Tool::Degenerated(E);
|
|
if (isdgE)
|
|
return false;
|
|
|
|
BRepAdaptor_Curve BC(E);
|
|
// modified by NIZNHY-PKV Fri Aug 4 09:49:31 2000 f
|
|
if (!CheckEdgeLength(E))
|
|
{
|
|
return false;
|
|
}
|
|
// modified by NIZNHY-PKV Fri Aug 4 09:49:36 2000 t
|
|
|
|
return (TopOpeBRepTool_TOOL::TggeomE(par, BC, Tg));
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
gp_Vec2d TopOpeBRepTool_TOOL::Tg2d(const int iv,
|
|
const TopoDS_Edge& E,
|
|
const TopOpeBRepTool_C2DF& C2DF)
|
|
{
|
|
double f, l, tol;
|
|
const occ::handle<Geom2d_Curve>& PC = C2DF.PC(f, l, tol);
|
|
double par = TopOpeBRepTool_TOOL::ParE(iv, E);
|
|
gp_Pnt2d UV;
|
|
gp_Vec2d tg2d;
|
|
PC->D1(par, UV, tg2d);
|
|
gp_Dir2d d2d(tg2d);
|
|
return d2d;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
gp_Vec2d TopOpeBRepTool_TOOL::Tg2dApp(const int iv,
|
|
const TopoDS_Edge& E,
|
|
const TopOpeBRepTool_C2DF& C2DF,
|
|
const double factor)
|
|
{
|
|
double f, l, tol;
|
|
const occ::handle<Geom2d_Curve>& PC = C2DF.PC(f, l, tol);
|
|
|
|
int iOOv = (iv == 1) ? 2 : 1;
|
|
double par = TopOpeBRepTool_TOOL::ParE(iv, E);
|
|
double OOpar = TopOpeBRepTool_TOOL::ParE(iOOv, E);
|
|
double parE = (1 - factor) * par + factor * OOpar;
|
|
|
|
gp_Pnt2d UV;
|
|
gp_Vec2d tg2d;
|
|
PC->D1(parE, UV, tg2d);
|
|
gp_Dir2d d2d(tg2d);
|
|
|
|
// modified by NIZHNY-MZV Wed May 24 12:52:18 2000
|
|
// TopAbs_Orientation oE = E.Orientation();
|
|
// if (M_REVERSED(oE)) d2d.Reverse();
|
|
// we remove this line because we want to know original tangent
|
|
return d2d;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
gp_Vec2d TopOpeBRepTool_TOOL::tryTg2dApp(const int iv,
|
|
const TopoDS_Edge& E,
|
|
const TopOpeBRepTool_C2DF& C2DF,
|
|
const double factor)
|
|
{
|
|
double f, l, tol;
|
|
const occ::handle<Geom2d_Curve>& PC = C2DF.PC(f, l, tol);
|
|
bool isquad = FUN_tool_quad(PC);
|
|
bool line = FUN_tool_line(PC);
|
|
if (!isquad || line)
|
|
return TopOpeBRepTool_TOOL::Tg2d(iv, E, C2DF);
|
|
return TopOpeBRepTool_TOOL::Tg2dApp(iv, E, C2DF, factor);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
int TopOpeBRepTool_TOOL::tryOriEinF(const double par, const TopoDS_Edge& e, const TopoDS_Face& f)
|
|
{
|
|
// ------------------------------------------------------------
|
|
// 1) <e> is a subshape of <f>
|
|
// 2) else, compute oriEinF, using <e>'s 2d rep on <f>
|
|
// PREQUESITORY : <e> must have a pcurve on <f>.
|
|
// ------------------------------------------------------------
|
|
bool checkclo = true;
|
|
int oeinf = TopOpeBRepTool_TOOL::OriinSor(e, f, checkclo);
|
|
if (oeinf != 0)
|
|
return oeinf;
|
|
|
|
occ::handle<Geom2d_Curve> pc;
|
|
double pf, pl, tol;
|
|
bool hasold = FC2D_HasOldCurveOnSurface(e, f, pc);
|
|
if (!hasold)
|
|
return 0;
|
|
pc = FC2D_EditableCurveOnSurface(e, f, pf, pl, tol);
|
|
|
|
// n2d is such that (p2d,oop2d) is oriented INSIDE F
|
|
gp_Pnt2d uv;
|
|
gp_Vec2d tg2d;
|
|
pc->D1(par, uv, tg2d);
|
|
gp_Vec2d n2d(gp_Dir2d(-tg2d.Y(), tg2d.X()));
|
|
|
|
double delta = TopOpeBRepTool_TOOL::minDUV(f);
|
|
delta *= 1.e-1;
|
|
gp_Pnt2d ouv = uv.Translated(delta * n2d);
|
|
bool outuvbounds = TopOpeBRepTool_TOOL::outUVbounds(ouv, f);
|
|
oeinf = (outuvbounds) ? 2 : 1;
|
|
return oeinf;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::NgApp(const double par,
|
|
const TopoDS_Edge& e,
|
|
const TopoDS_Face& f,
|
|
const double tola,
|
|
gp_Dir& ngApp)
|
|
{
|
|
// Give us an edge <e>, a face <f>, <e> has its geometry on <f>.
|
|
//
|
|
// P is the point of <par> on <e>
|
|
// purpose : the compute of <neinsidef>, at a point P' on <F>, near P
|
|
// direction pp' is normal to <e>.
|
|
// return false if the compute fails, or <neinsidef> is closed to <newneinsidef>
|
|
//
|
|
// PREQUESITORY : <e> must have a pcurve on <f>.
|
|
// --------------
|
|
|
|
occ::handle<Geom_Surface> S = TopOpeBRepTool_ShapeTool::BASISSURFACE(f);
|
|
if (S.IsNull())
|
|
return false;
|
|
|
|
bool fplane = FUN_tool_plane(f);
|
|
if (fplane)
|
|
return false;
|
|
|
|
// NYI : for bspline surfaces, use a evolutive parameter
|
|
// on curve to find out "significant" tangents
|
|
bool fquad = FUN_tool_quad(f);
|
|
if (!fquad)
|
|
return false;
|
|
// <pc> :
|
|
occ::handle<Geom2d_Curve> pc;
|
|
double pf, pl, tol;
|
|
bool hasold = FC2D_HasOldCurveOnSurface(e, f, pc);
|
|
if (!hasold)
|
|
return false;
|
|
pc = FC2D_EditableCurveOnSurface(e, f, pf, pl, tol);
|
|
// <orieinf> :
|
|
TopoDS_Shape aLocalShape = f.Oriented(TopAbs_FORWARD);
|
|
int orieinf = TopOpeBRepTool_TOOL::tryOriEinF(par, e, TopoDS::Face(aLocalShape));
|
|
// int orieinf =
|
|
// TopOpeBRepTool_TOOL::tryOriEinF(par,e,TopoDS::Face(f.Oriented(TopAbs_FORWARD)));
|
|
if (orieinf == 0)
|
|
return false;
|
|
// <uv> :
|
|
gp_Pnt2d uv;
|
|
bool ok = FUN_tool_paronEF(e, par, f, uv);
|
|
if (!ok)
|
|
return false;
|
|
// <ng> :
|
|
gp_Dir ng = FUN_tool_ngS(uv, S);
|
|
if (!ok)
|
|
return false;
|
|
|
|
// <n2dinsideS> :
|
|
gp_Vec2d tg2d;
|
|
pc->D1(par, uv, tg2d);
|
|
gp_Dir2d n2dinsideS = FUN_tool_nC2dINSIDES(gp_Dir2d(tg2d));
|
|
if (orieinf == 2)
|
|
n2dinsideS.Reverse();
|
|
//<duv> : '
|
|
double eps = 0.45678;
|
|
gp_Vec2d duv = gp_Vec2d(n2dinsideS).Multiplied(eps);
|
|
|
|
// cto009S4 : we need an iterative process to get other normal vector
|
|
int nmax = 5;
|
|
bool same = false;
|
|
double delta = 0.45678;
|
|
for (int i = 1; i <= nmax; i++)
|
|
{
|
|
|
|
gp_Pnt2d newuv = uv.Translated(duv);
|
|
gp_Vec newng = FUN_tool_ngS(newuv, S);
|
|
same = ng.IsEqual(newng, tola);
|
|
bool okk = (newng.Magnitude() > tola);
|
|
if (!same && okk)
|
|
{
|
|
ngApp = gp_Dir(newng);
|
|
break;
|
|
}
|
|
delta *= 1.25; // NYI
|
|
duv = gp_Vec2d(n2dinsideS).Multiplied(delta);
|
|
|
|
} // i=1..nmax
|
|
return !same;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::tryNgApp(const double par,
|
|
const TopoDS_Edge& e,
|
|
const TopoDS_Face& f,
|
|
const double tola,
|
|
gp_Dir& Ng)
|
|
{
|
|
gp_Pnt2d uv;
|
|
bool ok = FUN_tool_paronEF(e, par, f, uv);
|
|
if (!ok)
|
|
return false;
|
|
gp_Dir ng(FUN_tool_nggeomF(uv, f));
|
|
#ifdef OCCT_DEBUG
|
|
gp_Dir ngApp;
|
|
#endif
|
|
ok = TopOpeBRepTool_TOOL::NgApp(par, e, f, tola, Ng);
|
|
if (!ok)
|
|
Ng = ng;
|
|
return true;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::IsQuad(const TopoDS_Edge& E)
|
|
{
|
|
BRepAdaptor_Curve bc(E);
|
|
return (FUN_quadCT(bc.GetType()));
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::IsQuad(const TopoDS_Face& F)
|
|
{
|
|
occ::handle<Geom_Surface> S = TopOpeBRepTool_ShapeTool::BASISSURFACE(F);
|
|
return (FUN_tool_quad(S));
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::CurvE(const TopoDS_Edge& E,
|
|
const double par,
|
|
const gp_Dir& tg0,
|
|
double& curv)
|
|
{
|
|
curv = 0.;
|
|
BRepAdaptor_Curve BAC(E);
|
|
GeomAbs_CurveType CT = BAC.GetType();
|
|
bool line = (CT == GeomAbs_Line);
|
|
double tola = Precision::Angular() * 1.e3; // NYITOLXPU
|
|
if (line)
|
|
{
|
|
gp_Dir dir = BAC.Line().Direction();
|
|
double dot = dir.Dot(tg0);
|
|
return std::abs(1 - dot) >= tola;
|
|
}
|
|
|
|
BRepLProp_CLProps clprops(BAC, par, 2, Precision::Confusion());
|
|
bool tgdef = clprops.IsTangentDefined();
|
|
if (!tgdef)
|
|
return false;
|
|
curv = std::abs(clprops.Curvature());
|
|
|
|
double tol = Precision::Confusion() * 1.e+2; // NYITOLXPU
|
|
bool nullcurv = (curv < tol);
|
|
if (nullcurv)
|
|
{
|
|
curv = 0.;
|
|
return true;
|
|
}
|
|
|
|
gp_Dir N;
|
|
clprops.Normal(N);
|
|
gp_Dir T;
|
|
clprops.Tangent(T);
|
|
gp_Dir axis = N ^ T;
|
|
double dot = std::abs(axis.Dot(tg0));
|
|
nullcurv = dot < tola;
|
|
bool maxcurv = std::abs(1 - dot) < tola;
|
|
if (nullcurv)
|
|
{
|
|
curv = 0.;
|
|
return true;
|
|
}
|
|
if (maxcurv)
|
|
{
|
|
return true;
|
|
}
|
|
return false; // nyi general case
|
|
}
|
|
|
|
// ================================================================================
|
|
// In 3d space, give us a curve <C> and a surface <S>,
|
|
// <C> is tangent to <S> at point P0 = <uv0> on <S> ,
|
|
// <tgC> = C's tangent at P0,
|
|
// <ngS> = <S>'s normal at P0.
|
|
|
|
// These define a plane thePlane = (O = P0, XY = (<ngS>,<tgC>)),
|
|
// the projection of <S> in thePlane describes an apparent contour theContour.
|
|
|
|
// In thePlane :
|
|
// P0 -> p2d0
|
|
// <ngS> -> 2d axis x
|
|
// <tgC> -> 2d axis y
|
|
|
|
// <C> -> C2d (same curvature)
|
|
// <S>'s contour -> theContour
|
|
// - the half3dspace described by (<S>,<ngS>) -> the half2dspace described by (theContour,x)
|
|
|
|
// if (<tgC>.<ngS> = 0.) : (X,Y) are normal vectors
|
|
// (x,y) are normal vectors
|
|
// ================================================================================
|
|
static bool FUN_analyticcS(const gp_Pnt2d& uv0,
|
|
const occ::handle<Geom_Surface>& S,
|
|
const gp_Dir& ngS,
|
|
const gp_Dir& tg0,
|
|
double& curv,
|
|
bool& direct) // dummy if !analyticcontour
|
|
{
|
|
curv = 0.;
|
|
direct = true;
|
|
// purpose : Returns true if theContour is analytic, and
|
|
// then computes its curvature <curv>.
|
|
occ::handle<Geom_Surface> su = TopOpeBRepTool_ShapeTool::BASISSURFACE(S);
|
|
if (S.IsNull())
|
|
return true;
|
|
GeomAdaptor_Surface GS(su);
|
|
GeomAbs_SurfaceType ST = GS.GetType();
|
|
bool plane = (ST == GeomAbs_Plane);
|
|
bool cyl = (ST == GeomAbs_Cylinder);
|
|
bool cone = (ST == GeomAbs_Cone);
|
|
bool sphe = (ST == GeomAbs_Sphere);
|
|
bool torus = (ST == GeomAbs_Torus);
|
|
|
|
bool curvdone = false;
|
|
if (plane)
|
|
{
|
|
curv = 0.;
|
|
curvdone = true;
|
|
}
|
|
if (cyl || cone || torus)
|
|
{
|
|
gp_Dir axis;
|
|
if (cyl)
|
|
{
|
|
const gp_Cylinder& cycy = GS.Cylinder();
|
|
axis = cycy.Axis().Direction();
|
|
direct = cycy.Direct();
|
|
}
|
|
if (cone)
|
|
{
|
|
const gp_Cone& coco = GS.Cone();
|
|
axis = coco.Axis().Direction();
|
|
direct = coco.Direct();
|
|
}
|
|
if (torus)
|
|
{
|
|
const gp_Torus& toto = GS.Torus();
|
|
axis = toto.Axis().Direction();
|
|
direct = toto.Direct();
|
|
}
|
|
double prod = axis.Dot(tg0);
|
|
bool isMaxAcurv = FUN_nullprodv(1 - std::abs(prod));
|
|
bool nullcurv = FUN_nullprodv(prod);
|
|
|
|
double prod2 = ngS.Dot(tg0);
|
|
if (cyl || cone)
|
|
nullcurv = nullcurv || FUN_nullprodv(1 - std::abs(prod2));
|
|
|
|
if (nullcurv)
|
|
{
|
|
curv = 0.;
|
|
curvdone = true;
|
|
}
|
|
if (isMaxAcurv)
|
|
{
|
|
GeomLProp_SLProps slprops(S, uv0.X(), uv0.Y(), 2, Precision::Confusion());
|
|
bool curdef = slprops.IsCurvatureDefined();
|
|
if (curdef)
|
|
{
|
|
double minAcurv = std::abs(slprops.MinCurvature());
|
|
double maxAcurv = std::abs(slprops.MaxCurvature());
|
|
bool isAmax = (maxAcurv > minAcurv);
|
|
curv = isAmax ? maxAcurv : minAcurv;
|
|
}
|
|
curvdone = true;
|
|
}
|
|
}
|
|
if (sphe)
|
|
{
|
|
const gp_Sphere& spsp = GS.Sphere();
|
|
curv = 1. / spsp.Radius();
|
|
curvdone = true;
|
|
direct = spsp.Direct();
|
|
}
|
|
|
|
return curvdone;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::CurvF(const TopoDS_Face& F,
|
|
const gp_Pnt2d& uv,
|
|
const gp_Dir& tg0,
|
|
double& curv,
|
|
bool& direct)
|
|
{
|
|
curv = 0.;
|
|
gp_Dir ngS = FUN_tool_nggeomF(uv, F);
|
|
occ::handle<Geom_Surface> S = TopOpeBRepTool_ShapeTool::BASISSURFACE(F);
|
|
if (S.IsNull())
|
|
return false;
|
|
// purpose : Computes theContour's curvature,
|
|
// returns false if the compute fails.
|
|
|
|
double tola = 1.e-6; // NYITOLXPU
|
|
|
|
bool analyticcontour = FUN_analyticcS(uv, S, ngS, tg0, curv, direct);
|
|
if (analyticcontour)
|
|
return true;
|
|
|
|
GeomLProp_SLProps slprops(S, uv.X(), uv.Y(), 2, Precision::Confusion());
|
|
bool curdef = slprops.IsCurvatureDefined();
|
|
if (curdef)
|
|
{
|
|
gp_Dir npl = tg0;
|
|
|
|
gp_Dir MaxD, MinD;
|
|
slprops.CurvatureDirections(MaxD, MinD);
|
|
double mincurv = slprops.MinCurvature();
|
|
double maxcurv = slprops.MaxCurvature();
|
|
|
|
gp_Vec Dmax = ngS ^ MaxD, Dmin = ngS ^ MinD; // xpu180898 : cto015G2
|
|
double dotmax = Dmax.Dot(npl); // MaxD.Dot(npl); -xpu180898
|
|
bool iscurmax = std::abs(1 - dotmax) < tola;
|
|
if (iscurmax)
|
|
{
|
|
direct = (maxcurv < 0.);
|
|
curv = std::abs(maxcurv);
|
|
}
|
|
double dotmin = Dmin.Dot(npl); // MinD.Dot(npl); -xpu180898
|
|
bool iscurmin = std::abs(1 - dotmin) < tola;
|
|
if (iscurmin)
|
|
{
|
|
direct = (mincurv < 0.);
|
|
curv = std::abs(mincurv);
|
|
}
|
|
curdef = iscurmax || iscurmin;
|
|
// -------------
|
|
// NYI : !curdef
|
|
// -------------
|
|
}
|
|
return curdef;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::UVISO(const occ::handle<Geom2d_Curve>& PC,
|
|
bool& isoU,
|
|
bool& isoV,
|
|
gp_Dir2d& d2d,
|
|
gp_Pnt2d& o2d)
|
|
{
|
|
isoU = isoV = false;
|
|
if (PC.IsNull())
|
|
return false;
|
|
occ::handle<Geom2d_Curve> LLL = BASISCURVE2D(PC);
|
|
occ::handle<Standard_Type> T2 = LLL->DynamicType();
|
|
bool isline2d = (T2 == STANDARD_TYPE(Geom2d_Line));
|
|
if (!isline2d)
|
|
return false;
|
|
|
|
occ::handle<Geom2d_Line> L = occ::down_cast<Geom2d_Line>(LLL);
|
|
d2d = L->Direction();
|
|
isoU = (std::abs(d2d.X()) < Precision::Parametric(Precision::Confusion()));
|
|
isoV = (std::abs(d2d.Y()) < Precision::Parametric(Precision::Confusion()));
|
|
bool isoUV = isoU || isoV;
|
|
if (!isoUV)
|
|
return false;
|
|
|
|
o2d = L->Location();
|
|
return true;
|
|
}
|
|
|
|
bool TopOpeBRepTool_TOOL::UVISO(const TopoDS_Edge& E,
|
|
const TopoDS_Face& F,
|
|
bool& isoU,
|
|
bool& isoV,
|
|
gp_Dir2d& d2d,
|
|
gp_Pnt2d& o2d)
|
|
{
|
|
// double f,l,tol; occ::handle<Geom2d_Curve> PC = FC2D_CurveOnSurface(E,F,f,l,tol);
|
|
occ::handle<Geom2d_Curve> PC;
|
|
double f, l, tol;
|
|
bool hasold = FC2D_HasOldCurveOnSurface(E, F, PC);
|
|
PC = FC2D_EditableCurveOnSurface(E, F, f, l, tol);
|
|
if (!hasold)
|
|
FC2D_AddNewCurveOnSurface(PC, E, F, f, l, tol);
|
|
|
|
bool iso = UVISO(PC, isoU, isoV, d2d, o2d);
|
|
return iso;
|
|
}
|
|
|
|
bool TopOpeBRepTool_TOOL::UVISO(const TopOpeBRepTool_C2DF& C2DF,
|
|
bool& isoU,
|
|
bool& isoV,
|
|
gp_Dir2d& d2d,
|
|
gp_Pnt2d& o2d)
|
|
{
|
|
double f, l, tol;
|
|
const occ::handle<Geom2d_Curve>& PC = C2DF.PC(f, l, tol);
|
|
// #ifdef OCCT_DEBUG
|
|
// const iso = UVISO(PC,isoU,isoV,d2d,o2d);
|
|
// #else
|
|
const bool iso = UVISO(PC, isoU, isoV, d2d, o2d);
|
|
// #endif
|
|
return iso;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::IsonCLO(const occ::handle<Geom2d_Curve>& PC,
|
|
const bool onU,
|
|
const double xfirst,
|
|
const double xperiod,
|
|
const double xtol)
|
|
{
|
|
bool isou, isov;
|
|
gp_Pnt2d o2d;
|
|
gp_Dir2d d2d;
|
|
bool isouv = UVISO(PC, isou, isov, d2d, o2d);
|
|
if (!isouv)
|
|
return false;
|
|
bool onX = (onU && isou) || ((!onU) && isov);
|
|
if (!onX)
|
|
return false;
|
|
double dxx = 0;
|
|
if (onU)
|
|
dxx = std::abs(o2d.X() - xfirst);
|
|
else
|
|
dxx = std::abs(o2d.Y() - xfirst);
|
|
|
|
bool onclo = (dxx < xtol);
|
|
onclo = onclo || (std::abs(xperiod - dxx) < xtol);
|
|
return onclo;
|
|
}
|
|
|
|
bool TopOpeBRepTool_TOOL::IsonCLO(const TopOpeBRepTool_C2DF& C2DF,
|
|
const bool onU,
|
|
const double xfirst,
|
|
const double xperiod,
|
|
const double xtol)
|
|
{
|
|
double f, l, tol;
|
|
const occ::handle<Geom2d_Curve>& PC = C2DF.PC(f, l, tol);
|
|
bool onclo = IsonCLO(PC, onU, xfirst, xperiod, xtol);
|
|
return onclo;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
void TopOpeBRepTool_TOOL::TrslUV(const gp_Vec2d& t2d, TopOpeBRepTool_C2DF& C2DF)
|
|
{
|
|
double f, l, tol;
|
|
occ::handle<Geom2d_Curve> PC = C2DF.PC(f, l, tol);
|
|
PC->Translate(t2d);
|
|
C2DF.SetPC(PC, f, l, tol);
|
|
}
|
|
|
|
bool TopOpeBRepTool_TOOL::TrslUVModifE(const gp_Vec2d& t2d, const TopoDS_Face& F, TopoDS_Edge& E)
|
|
{
|
|
double f, l, tol;
|
|
occ::handle<Geom2d_Curve> PC = FC2D_CurveOnSurface(E, F, f, l, tol);
|
|
// occ::handle<Geom2d_Curve> PC; double f,l,tol;
|
|
|
|
if (PC.IsNull())
|
|
return false;
|
|
PC->Translate(t2d);
|
|
// occ::handle<Geom2d_Curve> toclear; BB.UpdateEdge(E,toclear,F,tole);
|
|
BRep_Builder BB;
|
|
BB.UpdateEdge(E, PC, F, tol);
|
|
return true;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
double TopOpeBRepTool_TOOL::Matter(const gp_Vec& d1, const gp_Vec& dR2, const gp_Vec& Ref)
|
|
{
|
|
gp_Vec d2 = dR2.Reversed();
|
|
|
|
double tola = Precision::Angular();
|
|
double ang = d1.Angle(d2);
|
|
bool equal = (ang < tola);
|
|
if (equal)
|
|
return 0.;
|
|
bool oppo = ((M_PI - ang) < tola);
|
|
if (oppo)
|
|
return M_PI;
|
|
|
|
ang = d1.AngleWithRef(d2, Ref);
|
|
if (ang < 0)
|
|
ang = 2. * M_PI + ang;
|
|
return ang;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
double TopOpeBRepTool_TOOL::Matter(const gp_Vec2d& d1, const gp_Vec2d& dR2)
|
|
{
|
|
gp_Vec v1 = gp_Vec(d1.X(), d1.Y(), 0.);
|
|
gp_Vec vR2 = gp_Vec(dR2.X(), dR2.Y(), 0.);
|
|
gp_Vec Ref(0., 0., 1.);
|
|
|
|
double ang = TopOpeBRepTool_TOOL::Matter(v1, vR2, Ref);
|
|
return ang;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::Matter(const gp_Dir& xx1,
|
|
const gp_Dir& nt1,
|
|
const gp_Dir& xx2,
|
|
const gp_Dir& nt2,
|
|
const double tola,
|
|
double& ang)
|
|
// purpose : the compute of MatterAng(f1,f2)
|
|
{
|
|
// --------------------------------------------------
|
|
// Give us a face f1 and one edge e of f1, pone=pnt(e,pare)
|
|
// We project the problem in a plane normal to e, at point pone
|
|
// ie we see the problem in space (x,y), with RONd (x,y,z), z tangent to e at pone.
|
|
// RONd (x,y,z) = (xx1,nt1,x^y)
|
|
//
|
|
// Make the analogy :
|
|
// f <-> Ef, e <-> Ve,
|
|
// In view (x,y), f1 is seen as an edge Ef, e is seen as a vertex Ve,
|
|
// the matter delimited by f can be seen as the one delimited by Ef.
|
|
// --------------------------------------------------
|
|
|
|
// Sign( (v1^nt1).z ) describes Ve's orientation in Ef1
|
|
// (v1^nt1).z > 0. => Ve is oriented REVERSED in Ef1.
|
|
// - ori(Ve,Ef1) == REVERSED : the matter delimited by <f1>
|
|
// is (y<=0) in (x,y) 2d space -
|
|
|
|
gp_Dir z1 = xx1 ^ nt1;
|
|
gp_Dir z2 = xx2 ^ nt2;
|
|
double dot = z2.Dot(z1);
|
|
bool oppo = (dot < 0.);
|
|
if (!oppo)
|
|
return false;
|
|
|
|
// -nti points towards 3dmatter(fi)
|
|
// => zi = xxi^nti gives the opposite sense for the compute of the matter angle
|
|
z1.Reverse();
|
|
ang = xx1.AngleWithRef(xx2, z1);
|
|
if (std::abs(ang) < tola)
|
|
{
|
|
ang = 0.;
|
|
return true;
|
|
}
|
|
if (ang < 0)
|
|
ang = 2. * M_PI + ang;
|
|
|
|
return true;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::Getduv(const TopoDS_Face& f,
|
|
const gp_Pnt2d& uv,
|
|
const gp_Vec& dir,
|
|
const double factor,
|
|
gp_Dir2d& duv)
|
|
{
|
|
bool quad = TopOpeBRepTool_TOOL::IsQuad(f);
|
|
if (!quad)
|
|
return false;
|
|
Bnd_Box bndf;
|
|
BRepBndLib::AddClose(f, bndf);
|
|
double f1, f2, f3, l1, l2, l3;
|
|
bndf.Get(f1, f2, f3, l1, l2, l3);
|
|
gp_Vec d123(f1 - l1, f2 - l2, f3 - l3);
|
|
|
|
gp_Pnt p;
|
|
FUN_tool_value(uv, f, p);
|
|
p.Translate(dir.Multiplied(factor));
|
|
double d;
|
|
gp_Pnt2d uvtr;
|
|
FUN_tool_projPonF(p, f, uvtr, d);
|
|
double tolf = BRep_Tool::Tolerance(f);
|
|
tolf *= 1.e2; // NYIXPUTOL
|
|
if (d > tolf)
|
|
return false;
|
|
|
|
gp_Vec2d DUV(uv, uvtr);
|
|
occ::handle<Geom_Surface> S = TopOpeBRepTool_ShapeTool::BASISSURFACE(f);
|
|
if ((S->IsUPeriodic()) && (std::abs(DUV.X()) > S->UPeriod() / 2.))
|
|
{
|
|
double U1 = uv.X(), U2 = uvtr.X(), period = S->UPeriod();
|
|
ElCLib::AdjustPeriodic(0., period, Precision::PConfusion(), U1, U2);
|
|
double dx = U2 - U1;
|
|
if (dx > period / 2.)
|
|
dx -= period;
|
|
DUV.SetX(dx);
|
|
}
|
|
if ((S->IsVPeriodic()) && (std::abs(DUV.Y()) > S->VPeriod() / 2.))
|
|
{
|
|
double V1 = uv.Y(), V2 = uvtr.Y(), period = S->VPeriod();
|
|
ElCLib::AdjustPeriodic(0., period, Precision::PConfusion(), V1, V2);
|
|
double dy = V2 - V1;
|
|
if (dy > period / 2.)
|
|
dy -= period;
|
|
DUV.SetY(dy);
|
|
}
|
|
duv = gp_Dir2d(DUV);
|
|
|
|
return true;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::uvApp(const TopoDS_Face& f,
|
|
const TopoDS_Edge& e,
|
|
const double pare,
|
|
const double eps,
|
|
gp_Pnt2d& uvapp)
|
|
{
|
|
// uv :
|
|
bool ok = FUN_tool_paronEF(e, pare, f, uvapp);
|
|
if (!ok)
|
|
return false;
|
|
gp_Vec2d dxx;
|
|
ok = FUN_tool_getdxx(f, e, pare, dxx);
|
|
if (!ok)
|
|
return false;
|
|
uvapp.Translate(dxx.Multiplied(eps));
|
|
return true;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::XX(const gp_Pnt2d& uv,
|
|
const TopoDS_Face& f,
|
|
const double par,
|
|
const TopoDS_Edge& e,
|
|
gp_Dir& XX)
|
|
{
|
|
// ng(uv):
|
|
gp_Vec ng = FUN_tool_nggeomF(uv, f);
|
|
gp_Vec geomxx = FUN_tool_getgeomxx(f, e, par, ng);
|
|
|
|
double tol = Precision::Confusion() * 1.e2; // NYITOL
|
|
bool nullng = (geomxx.Magnitude() < tol);
|
|
if (nullng)
|
|
return false;
|
|
|
|
TopAbs_Orientation oef;
|
|
bool ok = FUN_tool_orientEinFFORWARD(e, f, oef);
|
|
if (!ok)
|
|
return false;
|
|
XX = gp_Dir(geomxx);
|
|
if (M_REVERSED(oef))
|
|
XX.Reverse();
|
|
return true;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::Nt(const gp_Pnt2d& uv, const TopoDS_Face& f, gp_Dir& normt)
|
|
{
|
|
gp_Vec nggeom;
|
|
bool ok = TopOpeBRepTool_TOOL::NggeomF(uv, f, nggeom);
|
|
if (!ok)
|
|
return false;
|
|
normt = gp_Dir(nggeom);
|
|
if (M_REVERSED(f.Orientation()))
|
|
normt.Reverse();
|
|
return true;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
static bool FUN_ngF(const gp_Pnt2d& uv, const TopoDS_Face& F, gp_Vec& ngF)
|
|
{
|
|
BRepAdaptor_Surface bs(F);
|
|
double tol3d = bs.Tolerance();
|
|
double tolu = bs.UResolution(tol3d);
|
|
double tolv = bs.VResolution(tol3d);
|
|
|
|
// ###############################
|
|
// nyi : all geometries are direct
|
|
// ###############################
|
|
gp_Pnt p;
|
|
gp_Vec d1u, d1v;
|
|
bs.D1(uv.X(), uv.Y(), p, d1u, d1v);
|
|
|
|
double delta = TopOpeBRepTool_TOOL::minDUV(F);
|
|
delta *= 1.e-1;
|
|
|
|
double du = d1u.Magnitude();
|
|
double dv = d1v.Magnitude();
|
|
bool kpart = (du < tolu) || (dv < tolv);
|
|
if (kpart)
|
|
{
|
|
GeomAbs_SurfaceType ST = bs.GetType();
|
|
if (ST == GeomAbs_Cone)
|
|
{
|
|
bool nullx = (std::abs(uv.X()) < tolu);
|
|
bool apex = nullx && (std::abs(uv.Y()) < tolv);
|
|
if (apex)
|
|
{
|
|
const gp_Dir axis = bs.Cone().Axis().Direction();
|
|
gp_Vec ng(axis);
|
|
ng.Reverse();
|
|
ngF = ng;
|
|
return true;
|
|
}
|
|
else if (du < tolu)
|
|
{
|
|
double x = uv.X();
|
|
|
|
double y = uv.Y();
|
|
double vf = bs.FirstVParameter();
|
|
|
|
if (std::abs(vf - y) < tolu)
|
|
vf += delta;
|
|
else
|
|
vf -= delta;
|
|
|
|
// modified by NIZHNY-MZV Fri Nov 26 12:38:55 1999
|
|
y = vf;
|
|
bs.D1(x, y, p, d1u, d1v);
|
|
gp_Vec ng = d1u ^ d1v;
|
|
|
|
ngF = ng;
|
|
return true;
|
|
}
|
|
}
|
|
if (ST == GeomAbs_Sphere)
|
|
{
|
|
double pisur2 = M_PI * .5;
|
|
double u = uv.X(), v = uv.Y();
|
|
bool vpisur2 = (std::abs(v - pisur2) < tolv);
|
|
bool vmoinspisur2 = (std::abs(v + pisur2) < tolv);
|
|
bool apex = vpisur2 || vmoinspisur2;
|
|
if (apex)
|
|
{
|
|
gp_Pnt center = bs.Sphere().Location();
|
|
gp_Pnt value = bs.Value(u, v);
|
|
gp_Vec ng(center, value);
|
|
ngF = ng;
|
|
return true;
|
|
}
|
|
}
|
|
#ifdef OCCT_DEBUG
|
|
std::cout << "FUN_tool_nggeomF NYI" << std::endl;
|
|
#endif
|
|
return false;
|
|
} // kpart
|
|
|
|
gp_Dir udir(d1u);
|
|
gp_Dir vdir(d1v);
|
|
ngF = gp_Vec(gp_Dir(udir ^ vdir));
|
|
return true;
|
|
}
|
|
|
|
bool TopOpeBRepTool_TOOL::NggeomF(const gp_Pnt2d& uv, const TopoDS_Face& f, gp_Vec& ng)
|
|
{
|
|
return FUN_ngF(uv, f, ng);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::Matter(const TopoDS_Face& f1,
|
|
const TopoDS_Face& f2,
|
|
const TopoDS_Edge& e,
|
|
const double par,
|
|
const double tola,
|
|
double& ang)
|
|
{
|
|
gp_Dir xx1, xx2;
|
|
gp_Dir nt1, nt2;
|
|
|
|
double tolf1 = BRep_Tool::Tolerance(f1) * 1.e2; // nyitolxpu
|
|
gp_Pnt2d uv1;
|
|
bool ok1 = FUN_tool_paronEF(e, par, f1, uv1, tolf1);
|
|
if (!ok1)
|
|
return false;
|
|
ok1 = TopOpeBRepTool_TOOL::Nt(uv1, f1, nt1);
|
|
if (!ok1)
|
|
return false;
|
|
ok1 = TopOpeBRepTool_TOOL::XX(uv1, f1, par, e, xx1);
|
|
if (!ok1)
|
|
return false;
|
|
|
|
double tolf2 = BRep_Tool::Tolerance(f2) * 2.e2; // nyitolxpu
|
|
gp_Pnt2d uv2;
|
|
bool ok2 = FUN_tool_paronEF(e, par, f2, uv2, tolf2);
|
|
if (!ok2)
|
|
return false;
|
|
ok2 = TopOpeBRepTool_TOOL::Nt(uv2, f2, nt2);
|
|
if (!ok2)
|
|
return false;
|
|
ok2 = TopOpeBRepTool_TOOL::XX(uv2, f2, par, e, xx2);
|
|
if (!ok2)
|
|
return false;
|
|
|
|
return (TopOpeBRepTool_TOOL::Matter(xx1, nt1, xx2, nt2, tola, ang));
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::MatterKPtg(const TopoDS_Face& f1,
|
|
const TopoDS_Face& f2,
|
|
const TopoDS_Edge& e,
|
|
double& ang)
|
|
{
|
|
double f, l;
|
|
FUN_tool_bounds(e, f, l);
|
|
double x = 0.45678;
|
|
double pare = (1 - x) * f + x * l;
|
|
|
|
double eps = 0.123; // NYIXPU190199
|
|
|
|
// double tola = Precision::Angular()*1.e3;
|
|
|
|
gp_Pnt2d uv1;
|
|
FUN_tool_paronEF(e, pare, f1, uv1);
|
|
gp_Dir nt1;
|
|
bool ok1 = TopOpeBRepTool_TOOL::Nt(uv1, f1, nt1);
|
|
if (!ok1)
|
|
return false;
|
|
gp_Pnt2d uvapp1;
|
|
ok1 = TopOpeBRepTool_TOOL::uvApp(f1, e, pare, eps, uvapp1);
|
|
if (!ok1)
|
|
return false;
|
|
gp_Pnt pf1;
|
|
FUN_tool_value(uvapp1, f1, pf1);
|
|
|
|
gp_Pnt2d uv2;
|
|
double d;
|
|
bool ok2 = FUN_tool_projPonF(pf1, f2, uv2, d);
|
|
gp_Pnt pf2;
|
|
FUN_tool_value(uv2, f2, pf2);
|
|
if (!ok2)
|
|
return false;
|
|
|
|
gp_Dir v12(gp_Vec(pf1, pf2));
|
|
double dot = v12.Dot(nt1);
|
|
ang = (dot < 0.) ? 0. : 2. * M_PI;
|
|
|
|
// gp_Dir nt1; ok1 = TopOpeBRepTool_TOOL::Nt(uv1,f1,nt1);
|
|
// if (!ok1) return false;
|
|
// gp_Dir xx1; ok1 = TopOpeBRepTool_TOOL::XX(uv1,f1,pare,e,xx1);
|
|
// if (!ok1) return false;
|
|
// gp_Pnt2d uv2; bool ok2 = TopOpeBRepTool_TOOL::uvApp(f2,e,pare,eps,uv2);
|
|
// if (!ok2) return false;
|
|
// gp_Dir nt2; ok2 = TopOpeBRepTool_TOOL::Nt(uv2,f2,nt2);
|
|
// if (!ok2) return false;
|
|
// gp_Dir xx2; ok2 = TopOpeBRepTool_TOOL::XX(uv2,f2,pare,e,xx2);
|
|
// if (!ok2) return false;
|
|
// double angapp; bool ok = TopOpeBRepTool_TOOL::Matter(xx1,nt1,
|
|
// xx2,nt2,tola,angapp); if (!ok) return false; bool is0 = (std::abs(angapp)
|
|
// < std::abs(2.*M_PI-angapp)); ang = is0 ? 0. : 2.*M_PI;
|
|
return true;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::Getstp3dF(const gp_Pnt& p,
|
|
const TopoDS_Face& f,
|
|
gp_Pnt2d& uv,
|
|
TopAbs_State& st)
|
|
// classification solide de <P> / <F>
|
|
{
|
|
st = TopAbs_UNKNOWN;
|
|
double tol3d = BRep_Tool::Tolerance(f);
|
|
// EXPENSIVE : calls an extrema
|
|
double d;
|
|
bool ok = FUN_tool_projPonF(p, f, uv, d);
|
|
if (!ok)
|
|
return false;
|
|
if (d < tol3d)
|
|
{
|
|
st = TopAbs_ON;
|
|
return true;
|
|
}
|
|
|
|
gp_Pnt ppr;
|
|
ok = FUN_tool_value(uv, f, ppr);
|
|
if (!ok)
|
|
return false;
|
|
|
|
gp_Dir ntf;
|
|
ok = TopOpeBRepTool_TOOL::Nt(uv, f, ntf);
|
|
if (!ok)
|
|
return false;
|
|
|
|
gp_Dir dppr(gp_Vec(p, ppr));
|
|
double dot = dppr.Dot(ntf);
|
|
bool isOUT = (dot < 0.);
|
|
st = (isOUT ? TopAbs_OUT : TopAbs_IN);
|
|
return true;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
void TopOpeBRepTool_TOOL::MkShell(const NCollection_List<TopoDS_Shape>& lF, TopoDS_Shape& She)
|
|
{
|
|
BRep_Builder BB;
|
|
BB.MakeShell(TopoDS::Shell(She));
|
|
for (NCollection_List<TopoDS_Shape>::Iterator li(lF); li.More(); li.Next())
|
|
BB.Add(She, li.Value());
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::Remove(NCollection_List<TopoDS_Shape>& loS, const TopoDS_Shape& toremove)
|
|
{
|
|
NCollection_List<TopoDS_Shape>::Iterator it(loS);
|
|
bool found = false;
|
|
while (it.More())
|
|
{
|
|
if (it.Value().IsEqual(toremove))
|
|
{
|
|
loS.Remove(it);
|
|
found = true;
|
|
}
|
|
else
|
|
it.Next();
|
|
}
|
|
return found;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
double TopOpeBRepTool_TOOL::minDUV(const TopoDS_Face& F)
|
|
{
|
|
BRepAdaptor_Surface BS(F);
|
|
double delta = BS.LastUParameter() - BS.FirstUParameter();
|
|
double tmp = BS.LastVParameter() - BS.FirstVParameter();
|
|
delta = (tmp < delta) ? tmp : delta;
|
|
return delta;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
#define INFFIRST (-1)
|
|
#define SUPLAST (-2)
|
|
#define ONFIRST (1)
|
|
#define ONLAST (2)
|
|
|
|
void TopOpeBRepTool_TOOL::stuvF(const gp_Pnt2d& uv, const TopoDS_Face& f, int& onU, int& onV)
|
|
{
|
|
BRepAdaptor_Surface bs(f);
|
|
onU = onV = 0;
|
|
double tolf = bs.Tolerance();
|
|
double tolu = bs.UResolution(tolf), tolv = bs.VResolution(tolf);
|
|
double u = uv.X(), v = uv.Y();
|
|
double uf = bs.FirstUParameter(), ul = bs.LastUParameter(), vf = bs.FirstVParameter(),
|
|
vl = bs.LastVParameter();
|
|
bool onuf = (std::abs(uf - u) < tolu), onul = (std::abs(ul - u) < tolu);
|
|
bool onvf = (std::abs(vf - v) < tolv), onvl = (std::abs(vl - v) < tolv);
|
|
if (onuf)
|
|
onU = ONFIRST;
|
|
if (onul)
|
|
onU = ONLAST;
|
|
if (onvf)
|
|
onV = ONFIRST;
|
|
if (onvl)
|
|
onV = ONLAST;
|
|
if (u < (uf - tolu))
|
|
onU = INFFIRST;
|
|
if (u > (ul + tolu))
|
|
onU = SUPLAST;
|
|
if (v < (vf - tolv))
|
|
onV = INFFIRST;
|
|
if (v > (vl + tolv))
|
|
onV = SUPLAST;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::outUVbounds(const gp_Pnt2d& uv, const TopoDS_Face& F)
|
|
{
|
|
BRepAdaptor_Surface BS(F);
|
|
bool outofboundU = (uv.X() > BS.LastUParameter()) || (uv.X() < BS.FirstUParameter());
|
|
bool outofboundV = (uv.Y() > BS.LastVParameter()) || (uv.Y() < BS.FirstVParameter());
|
|
return outofboundU || outofboundV;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
double TopOpeBRepTool_TOOL::TolUV(const TopoDS_Face& F, const double tol3d)
|
|
{
|
|
BRepAdaptor_Surface bs(F);
|
|
double tol2d = bs.UResolution(tol3d);
|
|
tol2d = std::max(tol2d, bs.VResolution(tol3d));
|
|
return tol2d;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
double TopOpeBRepTool_TOOL::TolP(const TopoDS_Edge& E, const TopoDS_Face& F)
|
|
{
|
|
BRepAdaptor_Curve2d BC2d(E, F);
|
|
return (BC2d.Resolution(BRep_Tool::Tolerance(E)));
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::WireToFace(
|
|
const TopoDS_Face& Fref,
|
|
const NCollection_DataMap<TopoDS_Shape, NCollection_List<TopoDS_Shape>, TopTools_ShapeMapHasher>&
|
|
mapWlow,
|
|
NCollection_List<TopoDS_Shape>& lFs)
|
|
{
|
|
BRep_Builder BB;
|
|
TopoDS_Shape aLocalShape = Fref.Oriented(TopAbs_FORWARD);
|
|
TopoDS_Face F = TopoDS::Face(aLocalShape);
|
|
// TopoDS_Face F = TopoDS::Face(Fref.Oriented(TopAbs_FORWARD));
|
|
bool toreverse = M_REVERSED(Fref.Orientation());
|
|
NCollection_DataMap<TopoDS_Shape, NCollection_List<TopoDS_Shape>, TopTools_ShapeMapHasher>::
|
|
Iterator itm(mapWlow);
|
|
for (; itm.More(); itm.Next())
|
|
{
|
|
TopoDS_Shape FF = F.EmptyCopied();
|
|
const TopoDS_Wire& wi = TopoDS::Wire(itm.Key());
|
|
BB.Add(FF, wi);
|
|
NCollection_List<TopoDS_Shape>::Iterator itw(itm.Value());
|
|
for (; itw.More(); itw.Next())
|
|
{
|
|
const TopoDS_Wire& wwi = TopoDS::Wire(itw.Value());
|
|
BB.Add(FF, wwi);
|
|
}
|
|
if (toreverse)
|
|
FF.Orientation(TopAbs_REVERSED);
|
|
lFs.Append(FF);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
bool TopOpeBRepTool_TOOL::EdgeONFace(const double par,
|
|
const TopoDS_Edge& ed,
|
|
const gp_Pnt2d& uv,
|
|
const TopoDS_Face& fa,
|
|
bool& isonfa)
|
|
{
|
|
isonfa = false;
|
|
// prequesitory : pnt(par,ed) = pnt(uv,f)
|
|
bool dge = BRep_Tool::Degenerated(ed);
|
|
if (dge)
|
|
{
|
|
isonfa = true;
|
|
return true;
|
|
}
|
|
|
|
double tola = Precision::Angular() * 1.e2; // NYITOLXPU
|
|
gp_Vec tge;
|
|
bool ok = TopOpeBRepTool_TOOL::TggeomE(par, ed, tge);
|
|
if (!ok)
|
|
return false;
|
|
gp_Vec ngf = FUN_tool_nggeomF(uv, fa);
|
|
double aProdDot = tge.Dot(ngf);
|
|
bool etgf = std::abs(aProdDot) < tola;
|
|
if (!etgf)
|
|
return true;
|
|
|
|
BRepAdaptor_Surface bs(fa);
|
|
GeomAbs_SurfaceType st = bs.GetType();
|
|
bool plane = (st == GeomAbs_Plane);
|
|
bool cylinder = (st == GeomAbs_Cylinder);
|
|
|
|
BRepAdaptor_Curve bc(ed);
|
|
GeomAbs_CurveType ct = bc.GetType();
|
|
bool line = (ct == GeomAbs_Line);
|
|
bool circle = (ct == GeomAbs_Circle);
|
|
|
|
double tole = bc.Tolerance();
|
|
double tol1de = bc.Resolution(tole);
|
|
double tolf = bs.Tolerance();
|
|
double tol3d = std::max(tole, tolf) * 1.e2; // NYITOLXPU
|
|
|
|
// NYIxpu100299 : for other analytic geometries
|
|
if (plane && line)
|
|
{
|
|
isonfa = true;
|
|
return true;
|
|
}
|
|
if (plane)
|
|
{
|
|
gp_Dir ne;
|
|
bool det = true;
|
|
if (circle)
|
|
ne = bc.Circle().Axis().Direction();
|
|
else if (ct == GeomAbs_Ellipse)
|
|
ne = bc.Ellipse().Axis().Direction();
|
|
else if (ct == GeomAbs_Hyperbola)
|
|
ne = bc.Hyperbola().Axis().Direction();
|
|
else if (ct == GeomAbs_Parabola)
|
|
ne = bc.Parabola().Axis().Direction();
|
|
else
|
|
det = false;
|
|
if (det)
|
|
{
|
|
double prod = ne.Dot(ngf);
|
|
isonfa = (std::abs(1 - std::abs(prod)) < tola);
|
|
return true;
|
|
}
|
|
} // plane
|
|
else if (cylinder)
|
|
{
|
|
gp_Dir ne;
|
|
bool det = true;
|
|
if (line)
|
|
ne = tge;
|
|
else if (circle)
|
|
ne = bc.Circle().Axis().Direction();
|
|
else
|
|
det = false;
|
|
gp_Dir axicy = bs.Cylinder().Axis().Direction();
|
|
|
|
if (det)
|
|
{
|
|
double prod = ne.Dot(axicy);
|
|
isonfa = (std::abs(1 - std::abs(prod)) < tola);
|
|
if (isonfa && circle)
|
|
{
|
|
double radci = bc.Circle().Radius();
|
|
double radcy = bs.Cylinder().Radius();
|
|
isonfa = (std::abs(radci - radcy) < tol3d);
|
|
}
|
|
return true;
|
|
}
|
|
} // cylinder
|
|
|
|
// !!!!!!!!!!!!!!!! NOT STILL OK !!!!!!!!!!!!!!
|
|
// projecting point of <ed> on <fa>
|
|
double x = 0.12345;
|
|
double f, l;
|
|
FUN_tool_bounds(ed, f, l);
|
|
bool onf = (std::abs(par - f) < tol1de);
|
|
double opar = onf ? ((1 - x) * f + x * l) : ((1 - x) * f + x * par);
|
|
gp_Pnt opc = bc.Value(opar);
|
|
|
|
gp_Pnt2d ouv;
|
|
ok = FUN_tool_parF(ed, opar, fa, ouv, tolf);
|
|
if (!ok)
|
|
return false;
|
|
gp_Pnt ops = bs.Value(ouv.X(), ouv.Y());
|
|
|
|
double dd = opc.Distance(ops);
|
|
isonfa = (dd < tol3d);
|
|
return true;
|
|
}
|