Loading files
f2929057eThis file is pinned to the selected release. Download the original to open it in your design tool.
// Created on: 1993-06-17
// Created by: Jean Yves LEBEY
// 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 <BRepAdaptor_Curve.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <Geom2d_Line.hxx>
#include <Geom_Curve.hxx>
#include <Geom_Surface.hxx>
#include <GeomAbs_CurveType.hxx>
#include <GeomAPI_ProjectPointOnSurf.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec.hxx>
#include <gp_Vec2d.hxx>
#include <Precision.hxx>
#include <Standard_ProgramError.hxx>
#include <TCollection_AsciiString.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
#include <TopOpeBRepBuild_define.hxx>
#include <TopOpeBRepBuild_WireEdgeSet.hxx>
#include <TopOpeBRepTool_2d.hxx>
//=================================================================================================
TopOpeBRepBuild_WireEdgeSet::TopOpeBRepBuild_WireEdgeSet(const TopoDS_Shape& F, void* const /*A*/)
: TopOpeBRepBuild_ShapeSet(TopAbs_VERTEX)
{
myFace = TopoDS::Face(F);
}
//=================================================================================================
void TopOpeBRepBuild_WireEdgeSet::AddShape(const TopoDS_Shape& S)
{
bool tocheck = true;
bool iswire = (S.ShapeType() == TopAbs_WIRE);
if (iswire)
{
BRepAdaptor_Surface bas(myFace, false);
bool uc = bas.IsUClosed();
bool vc = bas.IsVClosed();
if (uc || vc)
{
tocheck = false;
}
}
bool chk = true;
if (tocheck)
{
chk = CheckShape(S);
}
if (!chk)
{
return;
}
ProcessAddShape(S);
}
//=================================================================================================
void TopOpeBRepBuild_WireEdgeSet::AddStartElement(const TopoDS_Shape& S)
{
bool tocheck = true;
bool isedge = (S.ShapeType() == TopAbs_EDGE);
if (isedge)
{
BRepAdaptor_Curve cac(TopoDS::Edge(S));
GeomAbs_CurveType t = cac.GetType();
bool b = (t == GeomAbs_BSplineCurve || t == GeomAbs_BezierCurve);
tocheck = !b;
}
bool chk = true;
if (tocheck)
{
chk = CheckShape(S);
}
if (!chk)
{
return;
}
ProcessAddStartElement(S);
}
//=================================================================================================
void TopOpeBRepBuild_WireEdgeSet::AddElement(const TopoDS_Shape& S)
{
TopOpeBRepBuild_ShapeSet::AddElement(S);
}
//=================================================================================================
const TopoDS_Face& TopOpeBRepBuild_WireEdgeSet::Face() const
{
return myFace;
}
//=================================================================================================
void TopOpeBRepBuild_WireEdgeSet::InitNeighbours(const TopoDS_Shape& E)
{
mySubShapeExplorer.Init(E, mySubShapeType);
myCurrentShape = E;
FindNeighbours();
}
//=================================================================================================
void TopOpeBRepBuild_WireEdgeSet::FindNeighbours()
{
while (mySubShapeExplorer.More())
{
// l = list of edges neighbour of edge myCurrentShape through
// the vertex mySubShapeExplorer.Current(), which is a vertex of the
// edge myCurrentShape.
const TopoDS_Shape& V = mySubShapeExplorer.Current();
const NCollection_List<TopoDS_Shape>& l = MakeNeighboursList(myCurrentShape, V);
// myIncidentShapesIter iterates on the neighbour edges of the edge
// given as InitNeighbours() argument (this edge has been stored
// in the field myCurrentShape).
myIncidentShapesIter.Initialize(l);
if (myIncidentShapesIter.More())
{
break;
}
else
{
mySubShapeExplorer.Next();
}
}
}
//=======================================================================
// function : MakeNeighboursList
// purpose : recherche des edges connexes a Earg par Varg
//=======================================================================
const NCollection_List<TopoDS_Shape>& TopOpeBRepBuild_WireEdgeSet::MakeNeighboursList(
const TopoDS_Shape& Earg,
const TopoDS_Shape& Varg)
{
const TopoDS_Edge& E = TopoDS::Edge(Earg);
const TopoDS_Vertex& V = TopoDS::Vertex(Varg);
const NCollection_List<TopoDS_Shape>& l = mySubShapeMap.FindFromKey(V);
int nclosing = NbClosingShapes(l);
if (nclosing)
{
// build myCurrentShapeNeighbours =
// edge list made of connected shapes to Earg through Varg
myCurrentShapeNeighbours.Clear();
for (NCollection_List<TopoDS_Shape>::Iterator it(l); it.More(); it.Next())
{
const TopoDS_Shape& curn = it.Value(); // current neighbour
bool k = VertexConnectsEdgesClosing(V, E, curn);
if (k)
{
myCurrentShapeNeighbours.Append(curn);
}
}
int newn = NbClosingShapes(myCurrentShapeNeighbours);
if (newn >= 2)
{
const TopoDS_Face& F = myFace;
// plusieurs aretes de couture connexes a E par V et telles que :
// orientation de V dans E # orientation de V dans ces aretes.
// on ne garde,parmi les aretes de couture connexes,
// que l'arete A qui verifie tg(E) ^ tg(A) > 0
gp_Vec2d d1E;
gp_Pnt2d pE;
double parE = BRep_Tool::Parameter(V, E);
double fiE, laE, tolpc;
bool trim3d = true;
occ::handle<Geom2d_Curve> PCE = FC2D_CurveOnSurface(E, F, fiE, laE, tolpc, trim3d);
if (!PCE.IsNull())
{
PCE->D1(parE, pE, d1E);
}
else
{
LocalD1(F, E, V, pE, d1E);
}
TopAbs_Orientation Eori = E.Orientation();
if (Eori == TopAbs_REVERSED)
{
d1E.Reverse();
}
NCollection_List<TopoDS_Shape>::Iterator lclo(myCurrentShapeNeighbours);
while (lclo.More())
{
if (!IsClosed(lclo.Value()))
{
lclo.Next();
continue;
}
const TopoDS_Edge& EE = TopoDS::Edge(lclo.Value());
gp_Vec2d d1EE;
gp_Pnt2d pEE;
double parEE = BRep_Tool::Parameter(V, EE);
double fiEE, laEE, tolpc1;
occ::handle<Geom2d_Curve> PCEE = FC2D_CurveOnSurface(EE, F, fiEE, laEE, tolpc1, trim3d);
if (!PCEE.IsNull())
{
PCEE->D1(parEE, pEE, d1EE);
}
else
{
LocalD1(F, EE, V, pEE, d1EE);
}
TopAbs_Orientation EEori = EE.Orientation();
if (EEori == TopAbs_REVERSED)
{
d1EE.Reverse();
}
double cross = d1E.Crossed(d1EE);
TopAbs_Orientation oVE, oVEE;
VertexConnectsEdges(V, E, EE, oVE, oVEE);
bool t2 = ((cross > 0) && oVE == TopAbs_REVERSED) || ((cross < 0) && oVE == TopAbs_FORWARD);
if (t2)
{ //-- t1
// c'est la bonne IsClosed,on ne garde qu'elle parmi les IsClosed
lclo.Next();
}
else
{
// on vire l'arete IsClosed
myCurrentShapeNeighbours.Remove(lclo);
}
}
}
return myCurrentShapeNeighbours;
}
else
{
return l;
}
} // MakeNeighoursList
//=================================================================================================
bool TopOpeBRepBuild_WireEdgeSet::VertexConnectsEdges(const TopoDS_Shape& V,
const TopoDS_Shape& E1,
const TopoDS_Shape& E2,
TopAbs_Orientation& o1,
TopAbs_Orientation& o2) const
{
TopOpeBRepTool_ShapeExplorer ex1, ex2;
for (ex1.Init(E1, TopAbs_VERTEX); ex1.More(); ex1.Next())
{
if (V.IsSame(ex1.Current()))
{
for (ex2.Init(E2, TopAbs_VERTEX); ex2.More(); ex2.Next())
{
if (V.IsSame(ex2.Current()))
{
o1 = ex1.Current().Orientation();
o2 = ex2.Current().Orientation();
if (o1 != o2)
{
return true;
}
}
}
}
}
return false;
}
//=================================================================================================
bool TopOpeBRepBuild_WireEdgeSet::VertexConnectsEdgesClosing(const TopoDS_Shape& V,
const TopoDS_Shape& E1,
const TopoDS_Shape& E2) const
{
//-----------------------------------------------------------------------
// bool VertexConnectsEdgesClosing :
// Let S the set of incident edges on vertex V.
// S contains at least one closed edge on the periodic face to build.
// (the face implied in closing test of edge is myFace)
// E1,E2 are S shapes (sharing V).
//
// if E1 and E2 are not closed : edges are NOT connected
// if E1 or E2 is/are closed :
// if V changes of relative orientation between E1,E2 : edges are connected
// else : edges are NOT connected
//
// example with E1 NOT closed, E2 closed :
//
// E1 FORWARD, V REVERSED on E1
// E2 FORWARD, V FORWARD on E2 --> edges are connected
//
// E1 FORWARD, V REVERSED on E1
// E2 REVERSED, V FORWARD on E2 --> edges are NOT connected
//-----------------------------------------------------------------------
bool c1 = IsClosed(E1);
bool c2 = IsClosed(E2);
bool testconnect = c1 || c2;
bool resu = false;
TopAbs_Orientation o1, o2;
// SSCONNEX = False ==> on selectionne E2 de facon a creer ulterieurement
// (defaut) autant de faces que de composantes connexes en UV.
// SSCONNEX = True ==> on prend toute arete E2 qui partage V avec E1
// et telle que orientation(V/E1) # orientation(V/E2)
// ==> face de part et d'autre des coutures
if ((c1 && c2))
{
bool u1 = c1 ? IsUClosed(E1) : false;
bool v1 = c1 ? IsVClosed(E1) : false;
bool u2 = c2 ? IsUClosed(E2) : false;
bool v2 = c2 ? IsVClosed(E2) : false;
bool uvdiff = (u1 && v2) || (u2 && v1);
testconnect = uvdiff;
}
if (testconnect)
{
resu = VertexConnectsEdges(V, E1, E2, o1, o2);
}
else
{
// cto 012 O2 arete de couture de face cylindrique
// chainage des composantes splitees ON et OUT de meme orientation
TopAbs_Orientation oe1 = E1.Orientation();
TopAbs_Orientation oe2 = E2.Orientation();
bool iseq = E1.IsEqual(E2);
if ((c1 && c2) && (oe1 == oe2) && (!iseq))
{
resu = VertexConnectsEdges(V, E1, E2, o1, o2);
}
}
return resu;
}
//=================================================================================================
int TopOpeBRepBuild_WireEdgeSet::NbClosingShapes(const NCollection_List<TopoDS_Shape>& L) const
{
int n = 0;
for (NCollection_List<TopoDS_Shape>::Iterator it(L); it.More(); it.Next())
{
const TopoDS_Shape& S = it.Value();
if (IsClosed(S))
{
n++;
}
}
return n;
}
//=================================================================================================
void TopOpeBRepBuild_WireEdgeSet::LocalD1(const TopoDS_Shape& SF,
const TopoDS_Shape& SE,
const TopoDS_Shape& SV,
gp_Pnt2d& pE,
gp_Vec2d& d1E) const
{
const TopoDS_Face& F = TopoDS::Face(SF);
const TopoDS_Edge& E = TopoDS::Edge(SE);
const TopoDS_Vertex& V = TopoDS::Vertex(SV);
double parE = BRep_Tool::Parameter(V, E);
TopLoc_Location Loc;
double fiE, laE;
occ::handle<Geom_Curve> CE = BRep_Tool::Curve(E, Loc, fiE, laE);
CE = occ::down_cast<Geom_Curve>(CE->Transformed(Loc.Transformation()));
gp_Pnt p3dE;
gp_Vec d3dE;
CE->D1(parE, p3dE, d3dE);
occ::handle<Geom_Surface> S = BRep_Tool::Surface(F);
GeomAPI_ProjectPointOnSurf proj(p3dE, S);
double u, v;
proj.LowerDistanceParameters(u, v);
pE.SetCoord(u, v);
gp_Pnt bid;
gp_Vec d1u, d1v;
S->D1(u, v, bid, d1u, d1v);
u = d3dE.Dot(d1u);
v = d3dE.Dot(d1v);
d1E.SetCoord(u, v);
}
//=================================================================================================
bool TopOpeBRepBuild_WireEdgeSet::IsClosed(const TopoDS_Shape& E) const
{
const TopoDS_Edge& EE = TopoDS::Edge(E);
bool closed = BRep_Tool::IsClosed(EE, myFace);
return closed;
}
//=================================================================================================
void TopOpeBRepBuild_WireEdgeSet::IsUVISO(const TopoDS_Edge& E,
const TopoDS_Face& F,
bool& uiso,
bool& viso)
{
uiso = viso = false;
double fE, lE, tolpc;
occ::handle<Geom2d_Curve> PC;
bool trim3d = true;
PC = FC2D_CurveOnSurface(E, F, fE, lE, tolpc, trim3d);
if (PC.IsNull())
{
throw Standard_ProgramError("TopOpeBRepBuild_WireEdgeSet::IsUVISO");
}
occ::handle<Standard_Type> TheType = PC->DynamicType();
if (TheType == STANDARD_TYPE(Geom2d_Line))
{
occ::handle<Geom2d_Line> HL(occ::down_cast<Geom2d_Line>(PC));
const gp_Dir2d& D = HL->Direction();
double tol = Precision::Angular();
if (D.IsParallel(gp_Dir2d(gp_Dir2d::D::Y), tol))
{
uiso = true;
}
else if (D.IsParallel(gp_Dir2d(gp_Dir2d::D::X), tol))
{
viso = true;
}
}
}
//=================================================================================================
bool TopOpeBRepBuild_WireEdgeSet::IsUClosed(const TopoDS_Shape& E) const
{
const TopoDS_Edge& EE = TopoDS::Edge(E);
bool bid, closed;
IsUVISO(EE, myFace, closed, bid);
return closed;
}
//=================================================================================================
bool TopOpeBRepBuild_WireEdgeSet::IsVClosed(const TopoDS_Shape& E) const
{
const TopoDS_Edge& EE = TopoDS::Edge(E);
bool bid, closed;
IsUVISO(EE, myFace, bid, closed);
return closed;
}
//=================================================================================================
TCollection_AsciiString TopOpeBRepBuild_WireEdgeSet::SNameVEE(const TopoDS_Shape&,
const TopoDS_Shape&,
const TopoDS_Shape&) const
{
TCollection_AsciiString str;
return str;
}
//=================================================================================================
TCollection_AsciiString TopOpeBRepBuild_WireEdgeSet::SNameVEL(
const TopoDS_Shape&,
const TopoDS_Shape&,
const NCollection_List<TopoDS_Shape>&) const
{
TCollection_AsciiString str;
return str;
}
//=================================================================================================
void TopOpeBRepBuild_WireEdgeSet::DumpSS() {}
//=================================================================================================
TCollection_AsciiString TopOpeBRepBuild_WireEdgeSet::SName(const TopoDS_Shape&,
const TCollection_AsciiString& sb,
const TCollection_AsciiString&) const
{
TCollection_AsciiString str = sb;
return str;
}
//=================================================================================================
TCollection_AsciiString TopOpeBRepBuild_WireEdgeSet::SNameori(const TopoDS_Shape&,
const TCollection_AsciiString& sb,
const TCollection_AsciiString&) const
{
TCollection_AsciiString str = sb;
return str;
}
//=================================================================================================
TCollection_AsciiString TopOpeBRepBuild_WireEdgeSet::SName(const NCollection_List<TopoDS_Shape>&,
const TCollection_AsciiString&,
const TCollection_AsciiString&) const
{
TCollection_AsciiString str;
return str;
}
//=================================================================================================
TCollection_AsciiString TopOpeBRepBuild_WireEdgeSet::SNameori(const NCollection_List<TopoDS_Shape>&,
const TCollection_AsciiString&,
const TCollection_AsciiString&) const
{
TCollection_AsciiString str;
return str;
}