Loading files
4f95ecaa3This file is pinned to the selected release. Download the original to open it in your design tool.
// Created on: 1994-02-01
// 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 <BRepAdaptor_Curve2d.hxx>
#include <BRepClass3d_SolidExplorer.hxx>
#include <BRepClass_FaceClassifier.hxx>
#include <BRepClass_FacePassiveClassifier.hxx>
#include <BRepTopAdaptor_FClass2d.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom_Curve.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
#include <Precision.hxx>
#include <Standard_ProgramError.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Shape.hxx>
#include <TopOpeBRepTool_2d.hxx>
#include <TopOpeBRepTool_CurveTool.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_IndexedMap.hxx>
#include <NCollection_DataMap.hxx>
#include <Standard_Integer.hxx>
#include <NCollection_IndexedDataMap.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Vertex.hxx>
#include <TCollection_AsciiString.hxx>
#include <TopOpeBRepTool_ShapeClassifier.hxx>
#include <TopOpeBRepTool_SolidClassifier.hxx>
//=================================================================================================
TopOpeBRepTool_ShapeClassifier::TopOpeBRepTool_ShapeClassifier()
: myP3Ddef(false),
myP2Ddef(false)
{
}
//=================================================================================================
TopOpeBRepTool_ShapeClassifier::TopOpeBRepTool_ShapeClassifier(const TopoDS_Shape& SRef)
: myP3Ddef(false),
myP2Ddef(false)
{
myRef = SRef;
}
//=================================================================================================
void TopOpeBRepTool_ShapeClassifier::ClearAll()
{
ClearCurrent();
mySolidClassifier.Clear();
}
//=================================================================================================
void TopOpeBRepTool_ShapeClassifier::ClearCurrent()
{
mySameDomain = -1;
myS.Nullify();
myRef.Nullify();
myAvS.Nullify();
myMapAvS.Clear();
mymre.Clear();
mymren = 0;
mymredone = false;
myState = TopAbs_UNKNOWN;
myEdge.Nullify();
myFace.Nullify();
myP3Ddef = myP2Ddef = false;
}
//=================================================================================================
int TopOpeBRepTool_ShapeClassifier::SameDomain() const
{
return mySameDomain;
}
//=================================================================================================
void TopOpeBRepTool_ShapeClassifier::SameDomain(const int sam)
{
mySameDomain = sam;
}
//=================================================================================================
void TopOpeBRepTool_ShapeClassifier::SetReference(const TopoDS_Shape& SRef)
{
myRef = SRef;
MapRef();
}
//=================================================================================================
void TopOpeBRepTool_ShapeClassifier::MapRef()
{
mymre.Clear();
mymren = 0;
if (myRef.ShapeType() == TopAbs_FACE && mySameDomain == 1)
{
TopExp::MapShapes(myRef, TopAbs_EDGE, mymre);
mymren = mymre.Extent();
if (mymren == 1)
{
TopExp_Explorer x(myRef, TopAbs_EDGE);
const TopoDS_Edge& E = TopoDS::Edge(x.Current());
TopoDS_Vertex v1, v2;
TopExp::Vertices(E, v1, v2);
if (v1.IsSame(v2))
{
mymren = 0;
}
}
}
mymredone = true;
}
//=================================================================================================
TopAbs_State TopOpeBRepTool_ShapeClassifier::StateShapeShape(const TopoDS_Shape& S,
const TopoDS_Shape& SRef,
const int samedomain)
{
ClearCurrent();
mySameDomain = samedomain;
myS = S;
myAvS.Nullify();
myPAvLS = nullptr;
myRef = SRef;
Perform();
return myState;
}
//=================================================================================================
TopAbs_State TopOpeBRepTool_ShapeClassifier::StateShapeShape(const TopoDS_Shape& S,
const TopoDS_Shape& AvS,
const TopoDS_Shape& SRef)
{
ClearCurrent();
myS = S;
myAvS = AvS;
myPAvLS = nullptr;
myRef = SRef;
Perform();
return myState;
}
//=================================================================================================
TopAbs_State TopOpeBRepTool_ShapeClassifier::StateShapeShape(
const TopoDS_Shape& S,
const NCollection_List<TopoDS_Shape>& AvLS,
const TopoDS_Shape& SRef)
{
ClearCurrent();
myS = S;
myAvS.Nullify();
myPAvLS = (NCollection_List<TopoDS_Shape>*)&AvLS;
myRef = SRef;
Perform();
return myState;
}
//=================================================================================================
TopAbs_State TopOpeBRepTool_ShapeClassifier::StateShapeReference(const TopoDS_Shape& S,
const TopoDS_Shape& AvS)
{
myS = S;
myAvS = AvS;
myPAvLS = nullptr;
Perform();
return myState;
}
//=================================================================================================
TopAbs_State TopOpeBRepTool_ShapeClassifier::StateShapeReference(
const TopoDS_Shape& S,
const NCollection_List<TopoDS_Shape>& AvLS)
{
myS = S;
myAvS.Nullify();
myPAvLS = (NCollection_List<TopoDS_Shape>*)&AvLS;
Perform();
return myState;
}
//=================================================================================================
TopOpeBRepTool_SolidClassifier& TopOpeBRepTool_ShapeClassifier::ChangeSolidClassifier()
{
return mySolidClassifier;
}
//=================================================================================================
void TopOpeBRepTool_ShapeClassifier::FindEdge()
{
myEdge.Nullify();
myFace.Nullify();
TopAbs_ShapeEnum t = myS.ShapeType();
if (t < TopAbs_FACE)
{ // compsolid .. shell
FindFace(myS);
FindEdge(myFace);
}
else
{
FindEdge(myS);
}
}
//=================================================================================================
void TopOpeBRepTool_ShapeClassifier::FindEdge(const TopoDS_Shape& S)
{
myEdge.Nullify();
bool isavls = HasAvLS();
bool isavs = (!myAvS.IsNull());
if (S.IsNull())
{
return;
}
TopAbs_ShapeEnum tS = S.ShapeType();
TopExp_Explorer eex;
if (!myFace.IsNull())
{
eex.Init(myFace, TopAbs_EDGE);
}
else
{
eex.Init(S, TopAbs_EDGE);
}
for (; eex.More(); eex.Next())
{
const TopoDS_Edge& E = TopoDS::Edge(eex.Current());
bool toavoid = false;
if (isavls || isavs)
{
toavoid = toavoid || myMapAvS.Contains(E);
if (!myAvS.IsNull())
{
toavoid = toavoid || E.IsSame(myAvS);
}
}
else if (BRep_Tool::Degenerated(E))
{
toavoid = (tS != TopAbs_EDGE);
}
if (toavoid)
{
continue;
}
myEdge = E;
break;
}
}
//=================================================================================================
void TopOpeBRepTool_ShapeClassifier::FindFace(const TopoDS_Shape& S)
{
myFace.Nullify();
bool isavls = HasAvLS();
bool isavs = (!myAvS.IsNull());
TopExp_Explorer fex(S, TopAbs_FACE);
for (; fex.More(); fex.Next())
{
const TopoDS_Face& F = TopoDS::Face(fex.Current());
bool toavoid = false;
if (isavls || isavs)
{
toavoid = toavoid || myMapAvS.Contains(F);
if (!myAvS.IsNull())
{
toavoid = toavoid || F.IsSame(myAvS);
}
}
if (toavoid)
{
continue;
}
myFace = F;
break;
}
}
//=================================================================================================
void TopOpeBRepTool_ShapeClassifier::Perform()
{
myState = TopAbs_UNKNOWN;
if (myS.IsNull())
{
return;
}
if (myRef.IsNull())
{
return;
}
if (!mymredone)
{
MapRef();
}
if (!myAvS.IsNull())
{
// tAvS = FACE,EDGE --> map(AvS,EDGE)
// rejet des aretes de myAvS comme arete de classification
// (le rejet simple de myAvS est insuffisant (connexite))
myMapAvS.Clear();
TopAbs_ShapeEnum tAvS = myAvS.ShapeType();
if (tAvS == TopAbs_FACE)
{
myMapAvS.Add(myAvS);
TopExp::MapShapes(myAvS, TopAbs_EDGE, myMapAvS);
}
else if (tAvS == TopAbs_EDGE)
{
TopExp::MapShapes(myAvS, TopAbs_EDGE, myMapAvS);
}
}
else if (HasAvLS())
{
// tAvS = FACE,EDGE --> map(AvS,EDGE)
// rejet des aretes de myPAvLS comme arete de classification
// (le rejet simple de myPAvLS est insuffisant (connexite))
myMapAvS.Clear();
TopAbs_ShapeEnum tAvS = myPAvLS->First().ShapeType();
if (tAvS == TopAbs_FACE)
{
NCollection_List<TopoDS_Shape>::Iterator it((*myPAvLS));
for (; it.More(); it.Next())
{
const TopoDS_Shape& S = it.Value();
myMapAvS.Add(S);
TopExp::MapShapes(S, TopAbs_EDGE, myMapAvS);
}
}
else if (tAvS == TopAbs_EDGE)
{
NCollection_List<TopoDS_Shape>::Iterator it((*myPAvLS));
for (; it.More(); it.Next())
{
const TopoDS_Shape& S = it.Value();
TopExp::MapShapes(S, TopAbs_EDGE, myMapAvS);
}
}
}
else
{
if (myS.ShapeType() == TopAbs_FACE)
{
myP3Ddef = BRepClass3d_SolidExplorer::FindAPointInTheFace(TopoDS::Face(myS), myP3D);
}
}
TopAbs_ShapeEnum tS = myS.ShapeType();
TopAbs_ShapeEnum tR = myRef.ShapeType();
if (tS == TopAbs_VERTEX)
{
if (tR <= TopAbs_SOLID)
{
gp_Pnt P3D = BRep_Tool::Pnt(TopoDS::Vertex(myS));
StateP3DReference(P3D);
}
}
else if (tS == TopAbs_EDGE)
{
if (tR == TopAbs_FACE || tR <= TopAbs_SOLID)
{
FindEdge();
StateEdgeReference();
}
}
else if (tS == TopAbs_WIRE)
{
if (tR == TopAbs_FACE || tR <= TopAbs_SOLID)
{
FindEdge();
StateEdgeReference();
}
}
else if (tS == TopAbs_FACE)
{
if (tR == TopAbs_FACE)
{
FindEdge();
if (mySameDomain == 1)
{
StateEdgeReference();
}
else
{
if (!myP3Ddef)
{
myP3Ddef = BRepClass3d_SolidExplorer::FindAPointInTheFace(TopoDS::Face(myS), myP3D);
}
if (myP3Ddef)
{
StateP3DReference(myP3D);
}
else
{
myState = TopAbs_UNKNOWN;
throw Standard_ProgramError("TopOpeBRepTool_ShapeClassifier !P3Ddef");
}
}
}
else if (tR <= TopAbs_SOLID)
{
FindEdge();
if (myP3Ddef)
{
StateP3DReference(myP3D);
}
else
{
StateEdgeReference();
}
}
}
else if (tS == TopAbs_SHELL)
{
if (tR <= TopAbs_SOLID)
{
FindEdge();
StateEdgeReference();
}
}
else if (tS == TopAbs_SOLID)
{
if (tR <= TopAbs_SOLID)
{
FindEdge();
StateEdgeReference();
}
}
else
{
throw Standard_ProgramError("StateShapeShape : bad operands");
}
// take orientation of reference shape in account
TopAbs_Orientation oriRef = myRef.Orientation();
if (oriRef == TopAbs_EXTERNAL || oriRef == TopAbs_INTERNAL)
{
if (myState == TopAbs_IN)
{
myState = TopAbs_OUT;
}
}
}
//=================================================================================================
void TopOpeBRepTool_ShapeClassifier::StateEdgeReference()
{
myState = TopAbs_UNKNOWN;
if (myEdge.IsNull())
{
return;
}
if (myRef.IsNull())
{
return;
}
occ::handle<Geom_Curve> C3D;
gp_Pnt P3D;
double f3d, l3d;
occ::handle<Geom2d_Curve> C2D;
gp_Pnt2d P2D;
double f2d, l2d, tol2d;
TopAbs_ShapeEnum tR = myRef.ShapeType();
// myEdge est une arete de myS, pas de myRef
if (tR == TopAbs_FACE)
{
const TopoDS_Face& F = TopoDS::Face(myRef);
if (mySameDomain)
{
bool trimCurve = true;
C2D = FC2D_CurveOnSurface(myEdge, F, f2d, l2d, tol2d, trimCurve);
if (C2D.IsNull())
{
throw Standard_ProgramError("StateShapeShape : no 2d curve");
}
double t = 0.127956477;
double p = (1 - t) * f2d + t * l2d;
P2D = C2D->Value(p);
#ifdef OCCT_DEBUG
C3D = BRep_Tool::Curve(myEdge, f3d, l3d);
if (!C3D.IsNull())
P3D = C3D->Value(p);
#endif
StateP2DReference(P2D);
return;
}
else
{ // myEdge/myRef=face en 3d
C3D = BRep_Tool::Curve(myEdge, f3d, l3d);
if (C3D.IsNull())
{
throw Standard_ProgramError("StateShapeShape : no 3d curve");
}
double t = 0.127956477;
double p = (1 - t) * f3d + t * l3d;
P3D = C3D->Value(p);
StateP3DReference(P3D);
return;
}
}
else if (tR <= TopAbs_SOLID)
{
bool degen = BRep_Tool::Degenerated(myEdge);
if (degen)
{
const TopoDS_Vertex& v = TopExp::FirstVertex(myEdge);
P3D = BRep_Tool::Pnt(v);
StateP3DReference(P3D);
return;
}
else
{
C3D = BRep_Tool::Curve(myEdge, f3d, l3d);
if (C3D.IsNull())
{
throw Standard_ProgramError("StateShapeShape : no 3d curve");
}
double t = 0.127956477;
double p = (1 - t) * f3d + t * l3d;
P3D = C3D->Value(p);
StateP3DReference(P3D);
return;
}
}
else
{
throw Standard_ProgramError("StateShapeShape : bad operands");
}
}
//=================================================================================================
void TopOpeBRepTool_ShapeClassifier::StateP2DReference(const gp_Pnt2d& P2D)
{
myState = TopAbs_UNKNOWN;
if (myRef.IsNull())
{
return;
}
TopAbs_ShapeEnum tR = myRef.ShapeType();
if (tR == TopAbs_FACE)
{
if (mymren == 1)
{
TopExp_Explorer x;
for (x.Init(myRef, TopAbs_EDGE); x.More(); x.Next())
{
// for(TopExp_Explorer x(myRef,TopAbs_EDGE);x.More();x.Next()) {
TopAbs_Orientation o = x.Current().Orientation();
// if (o == TopAbs_EXTERNAL) myState == TopAbs_OUT;
if (o == TopAbs_EXTERNAL)
{
myState = TopAbs_OUT;
// else if (o == TopAbs_INTERNAL) myState == TopAbs_IN;
}
else if (o == TopAbs_INTERNAL)
{
myState = TopAbs_IN;
}
else
{
#ifdef OCCT_DEBUG
std::cout << "StateP2DReference o<>E,I" << std::endl;
#endif
break;
}
}
}
else
{
myP2D = P2D;
myP2Ddef = true;
TopoDS_Face F = TopoDS::Face(myRef);
F.Orientation(TopAbs_FORWARD);
double TolClass = 1e-8;
BRepTopAdaptor_FClass2d FClass2d(F, TolClass);
myState = FClass2d.Perform(P2D);
}
}
else
{
throw Standard_ProgramError("StateShapeShape : bad operands");
}
}
//=================================================================================================
void TopOpeBRepTool_ShapeClassifier::StateP3DReference(const gp_Pnt& P3D)
{
myState = TopAbs_UNKNOWN;
if (myRef.IsNull())
{
return;
}
TopAbs_ShapeEnum tR = myRef.ShapeType();
if (tR == TopAbs_SOLID)
{
myP3D = P3D;
myP3Ddef = true;
const TopoDS_Solid& SO = TopoDS::Solid(myRef);
double tol3d = Precision::Confusion();
mySolidClassifier.Classify(SO, P3D, tol3d);
myState = mySolidClassifier.State();
}
else if (tR < TopAbs_SOLID)
{
myP3D = P3D;
myP3Ddef = true;
TopExp_Explorer ex;
for (ex.Init(myRef, TopAbs_SOLID); ex.More(); ex.Next())
{
// for (TopExp_Explorer ex(myRef,TopAbs_SOLID);ex.More();ex.Next()) {
const TopoDS_Solid& SO = TopoDS::Solid(ex.Current());
double tol3d = Precision::Confusion();
mySolidClassifier.Classify(SO, P3D, tol3d);
myState = mySolidClassifier.State();
if (myState == TopAbs_IN || myState == TopAbs_ON)
{
break;
}
}
}
else
{
throw Standard_ProgramError("StateShapeShape : bad operands");
}
}
//=================================================================================================
TopAbs_State TopOpeBRepTool_ShapeClassifier::State() const
{
return myState;
}
//=================================================================================================
const gp_Pnt& TopOpeBRepTool_ShapeClassifier::P3D() const
{
if (myP3Ddef)
{
return myP3D;
}
throw Standard_ProgramError("ShapeClassifier::P3D undefined");
}
//=================================================================================================
const gp_Pnt2d& TopOpeBRepTool_ShapeClassifier::P2D() const
{
if (myP2Ddef)
{
return myP2D;
}
throw Standard_ProgramError("ShapeClassifier::P2D undefined");
}
//=================================================================================================
bool TopOpeBRepTool_ShapeClassifier::HasAvLS() const
{
bool hasavls = (myPAvLS) ? (!myPAvLS->IsEmpty()) : false;
return hasavls;
}