mirror of
https://git.salome-platform.org/gitpub/modules/geom.git
synced 2025-03-21 01:47:56 +05:00
880 lines
23 KiB
C++
Executable File
880 lines
23 KiB
C++
Executable File
// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
|
|
//
|
|
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
|
|
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
|
|
//
|
|
// This library is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
// License as published by the Free Software Foundation; either
|
|
// version 2.1 of the License.
|
|
//
|
|
// This library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
// Lesser General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
// License along with this library; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
//
|
|
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
|
//
|
|
|
|
// File: GEOMAlgo_WireSplitter.cxx
|
|
// Created:
|
|
// Author: Peter KURNEV
|
|
// <pkv@irinox>
|
|
//
|
|
#include <GEOMAlgo_WireSplitter.ixx>
|
|
|
|
#include <TColStd_SequenceOfReal.hxx>
|
|
#include <Precision.hxx>
|
|
|
|
#include <gp_Pnt2d.hxx>
|
|
#include <gp_Vec2d.hxx>
|
|
#include <TColgp_SequenceOfPnt2d.hxx>
|
|
|
|
#include <Geom_Curve.hxx>
|
|
#include <Geom2d_Curve.hxx>
|
|
#include <GeomAdaptor_Surface.hxx>
|
|
|
|
#include <TopAbs_Orientation.hxx>
|
|
|
|
#include <TopoDS.hxx>
|
|
#include <TopoDS_Vertex.hxx>
|
|
#include <TopoDS_Edge.hxx>
|
|
#include <TopoDS_Face.hxx>
|
|
#include <TopoDS_Iterator.hxx>
|
|
|
|
|
|
#include <BRep_Tool.hxx>
|
|
#include <BRepAdaptor_Surface.hxx>
|
|
#include <BRepAdaptor_Curve2d.hxx>
|
|
|
|
#include <TopExp.hxx>
|
|
#include <TopExp_Explorer.hxx>
|
|
|
|
|
|
|
|
#include <TopTools_SequenceOfShape.hxx>
|
|
#include <TopTools_ListOfShape.hxx>
|
|
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
|
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
|
#include <TopTools_IndexedMapOfShape.hxx>
|
|
|
|
#include <BOPTColStd_ListOfListOfShape.hxx>
|
|
#include <BOPTColStd_ListIteratorOfListOfListOfShape.hxx>
|
|
|
|
#include <BOPTools_Tools2D.hxx>
|
|
|
|
#include <BOP_EdgeInfo.hxx>
|
|
#include <BOP_ListOfEdgeInfo.hxx>
|
|
#include <BOP_ListIteratorOfListOfEdgeInfo.hxx>
|
|
#include <BOP_IndexedDataMapOfVertexListEdgeInfo.hxx>
|
|
|
|
static
|
|
void Path (const GeomAdaptor_Surface& aGAS,
|
|
const TopoDS_Face& myFace,
|
|
const TopoDS_Vertex& aVa,
|
|
const TopoDS_Edge& aEOuta,
|
|
BOP_EdgeInfo& anEdgeInfo,
|
|
TopTools_SequenceOfShape& aLS,
|
|
TopTools_SequenceOfShape& aVertVa,
|
|
TColgp_SequenceOfPnt2d& aCoordVa,
|
|
BOPTColStd_ListOfListOfShape& myShapes,
|
|
BOP_IndexedDataMapOfVertexListEdgeInfo& mySmartMap);
|
|
|
|
|
|
static
|
|
Standard_Real Angle (const gp_Dir2d& aDir2D);
|
|
|
|
|
|
static
|
|
void GetNextVertex(const TopoDS_Vertex& aV,
|
|
const TopoDS_Edge& aE,
|
|
TopoDS_Vertex& aV1);
|
|
static
|
|
Standard_Real ClockWiseAngle(const Standard_Real aAngleIn,
|
|
const Standard_Real aAngleOut);
|
|
|
|
static
|
|
Standard_Real AngleIn(const TopoDS_Edge& aEIn,
|
|
const BOP_ListOfEdgeInfo& aLEInfo);
|
|
|
|
static
|
|
Standard_Real Angle2D (const TopoDS_Vertex& aV,
|
|
const TopoDS_Edge& anEdge,
|
|
const TopoDS_Face& myFace,
|
|
const GeomAdaptor_Surface& aGAS,
|
|
const Standard_Boolean aFlag);
|
|
static
|
|
gp_Pnt2d Coord2d (const TopoDS_Vertex& aV1,
|
|
const TopoDS_Edge& aE1,
|
|
const TopoDS_Face& aF);
|
|
static
|
|
gp_Pnt2d Coord2dVf (const TopoDS_Edge& aE,
|
|
const TopoDS_Face& aF);
|
|
static
|
|
Standard_Real Tolerance2D (const TopoDS_Vertex& aV,
|
|
const GeomAdaptor_Surface& aGAS);
|
|
|
|
static
|
|
Standard_Integer NbWaysOut(const BOP_ListOfEdgeInfo& );
|
|
//
|
|
|
|
//=======================================================================
|
|
// function:
|
|
// purpose:
|
|
//=======================================================================
|
|
GEOMAlgo_WireSplitter::GEOMAlgo_WireSplitter()
|
|
:
|
|
GEOMAlgo_Algo(),
|
|
myNothingToDo(Standard_False)
|
|
{
|
|
}
|
|
//=======================================================================
|
|
// function: ~
|
|
// purpose:
|
|
//=======================================================================
|
|
GEOMAlgo_WireSplitter::~GEOMAlgo_WireSplitter()
|
|
{
|
|
}
|
|
//=======================================================================
|
|
// function: SetFace
|
|
// purpose:
|
|
//=======================================================================
|
|
void GEOMAlgo_WireSplitter::SetFace(const TopoDS_Face& aFace)
|
|
{
|
|
myFace=aFace;
|
|
}
|
|
//=======================================================================
|
|
// function: Face
|
|
// purpose:
|
|
//=======================================================================
|
|
const TopoDS_Face& GEOMAlgo_WireSplitter::Face()const
|
|
{
|
|
return myFace;
|
|
}
|
|
//=======================================================================
|
|
// function: SetEdges
|
|
// purpose:
|
|
//=======================================================================
|
|
void GEOMAlgo_WireSplitter::SetEdges(const TopTools_ListOfShape& aLE)
|
|
{
|
|
TopTools_ListIteratorOfListOfShape anIt;
|
|
//
|
|
myEdges.Clear();
|
|
anIt.Initialize(aLE);
|
|
for (; anIt.More(); anIt.Next()) {
|
|
const TopoDS_Shape& aE =anIt.Value();
|
|
//
|
|
if (aE.Orientation()==TopAbs_INTERNAL){
|
|
continue;
|
|
}
|
|
//
|
|
myEdges.Append(aE);
|
|
}
|
|
}
|
|
//=======================================================================
|
|
// function: Edges
|
|
// purpose:
|
|
//=======================================================================
|
|
const TopTools_ListOfShape& GEOMAlgo_WireSplitter::Edges()const
|
|
{
|
|
return myEdges;
|
|
}
|
|
//=======================================================================
|
|
// function: IsNothingToDo
|
|
// purpose:
|
|
//=======================================================================
|
|
Standard_Boolean GEOMAlgo_WireSplitter::IsNothingToDo()const
|
|
{
|
|
return myNothingToDo;
|
|
}
|
|
//=======================================================================
|
|
// function: Shapes
|
|
// purpose:
|
|
//=======================================================================
|
|
const BOPTColStd_ListOfListOfShape& GEOMAlgo_WireSplitter::Shapes()const
|
|
{
|
|
return myShapes;
|
|
}
|
|
//=======================================================================
|
|
// function: Perform
|
|
// purpose:
|
|
//=======================================================================
|
|
void GEOMAlgo_WireSplitter::Perform()
|
|
{
|
|
myErrorStatus=2;
|
|
myNothingToDo=Standard_True;
|
|
|
|
Standard_Integer index, i, aNb, aCntIn, aCntOut;
|
|
Standard_Boolean anIsIn;
|
|
Standard_Real anAngle;
|
|
|
|
BOP_ListOfEdgeInfo emptyInfo;
|
|
TopTools_ListIteratorOfListOfShape anItList;
|
|
//
|
|
// 1.Filling mySmartMap
|
|
mySmartMap.Clear();
|
|
|
|
anItList.Initialize(myEdges);
|
|
for (; anItList.More(); anItList.Next()) {
|
|
const TopoDS_Edge& anEdge = TopoDS::Edge(anItList.Value());
|
|
//
|
|
if (!BOPTools_Tools2D::HasCurveOnSurface (anEdge, myFace)) {
|
|
continue;
|
|
}
|
|
//
|
|
TopExp_Explorer anExpVerts (anEdge, TopAbs_VERTEX);
|
|
for (; anExpVerts.More(); anExpVerts.Next()) {
|
|
const TopoDS_Shape& aVertex= anExpVerts.Current();
|
|
|
|
index = mySmartMap.FindIndex(aVertex);
|
|
if (!index) {
|
|
index=mySmartMap.Add(aVertex, emptyInfo);
|
|
}
|
|
|
|
BOP_ListOfEdgeInfo& aListOfEInfo=mySmartMap(index);
|
|
|
|
BOP_EdgeInfo aEInfo;
|
|
aEInfo.SetEdge(anEdge);
|
|
|
|
TopAbs_Orientation anOr=aVertex.Orientation();
|
|
|
|
if (anOr==TopAbs_FORWARD) {
|
|
aEInfo.SetInFlag(Standard_False);
|
|
}
|
|
|
|
else if (anOr==TopAbs_REVERSED) {
|
|
aEInfo.SetInFlag(Standard_True);
|
|
}
|
|
|
|
aListOfEInfo.Append(aEInfo);
|
|
}
|
|
}
|
|
//
|
|
aNb=mySmartMap.Extent();
|
|
//
|
|
// 2. myNothingToDo
|
|
myNothingToDo=Standard_True;
|
|
|
|
for (i=1; i<=aNb; i++) {
|
|
aCntIn=0;
|
|
aCntOut=0;
|
|
const BOP_ListOfEdgeInfo& aLEInfo= mySmartMap(i);
|
|
BOP_ListIteratorOfListOfEdgeInfo anIt(aLEInfo);
|
|
for (; anIt.More(); anIt.Next()) {
|
|
const BOP_EdgeInfo& anEdgeInfo=anIt.Value();
|
|
anIsIn=anEdgeInfo.IsIn();
|
|
if (anIsIn) {
|
|
aCntIn++;
|
|
}
|
|
else {
|
|
aCntOut++;
|
|
}
|
|
}
|
|
if (aCntIn!=1 || aCntOut!=1) {
|
|
myNothingToDo=Standard_False;
|
|
break;
|
|
}
|
|
}
|
|
//
|
|
// Each vertex has one edge In and one - Out. Good. But it is not enought
|
|
// to consider that nothing to do with this. We must check edges on TShape
|
|
// coinsidence. If there are such edges there is something to do with.
|
|
//
|
|
if (myNothingToDo) {
|
|
Standard_Integer aNbE, aNbMapEE;
|
|
TopTools_IndexedDataMapOfShapeListOfShape aMapEE;
|
|
aNbE=myEdges.Extent();
|
|
|
|
anItList.Initialize(myEdges);
|
|
for (; anItList.More(); anItList.Next()) {
|
|
const TopoDS_Shape& aE = anItList.Value();
|
|
|
|
if (!aMapEE.Contains(aE)) {
|
|
TopTools_ListOfShape aLEx;
|
|
aLEx.Append(aE);
|
|
aMapEE.Add(aE, aLEx);
|
|
}
|
|
else {
|
|
TopTools_ListOfShape& aLEx=aMapEE.ChangeFromKey(aE);
|
|
aLEx.Append(aE);
|
|
}
|
|
}
|
|
|
|
Standard_Boolean bFlag;
|
|
bFlag=Standard_True;
|
|
aNbMapEE=aMapEE.Extent();
|
|
for (i=1; i<=aNbMapEE; i++) {
|
|
const TopTools_ListOfShape& aLEx=aMapEE(i);
|
|
aNbE=aLEx.Extent();
|
|
if (aNbE==1) {
|
|
// usual case
|
|
continue;
|
|
}
|
|
else if (aNbE==2){
|
|
const TopoDS_Shape& aE1=aLEx.First();
|
|
const TopoDS_Shape& aE2=aLEx.Last();
|
|
if (aE1.IsSame(aE2)) {
|
|
bFlag=Standard_False;
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
bFlag=Standard_False;
|
|
break;
|
|
}
|
|
}
|
|
myNothingToDo=myNothingToDo && bFlag;
|
|
}
|
|
//
|
|
//
|
|
if (myNothingToDo) {
|
|
myErrorStatus=0;
|
|
return;
|
|
}
|
|
//
|
|
// 3. Angles in mySmartMap
|
|
BRepAdaptor_Surface aBAS(myFace);
|
|
const GeomAdaptor_Surface& aGAS=aBAS.Surface();
|
|
for (i=1; i<=aNb; i++) {
|
|
const TopoDS_Vertex& aV=TopoDS::Vertex (mySmartMap.FindKey(i));
|
|
const BOP_ListOfEdgeInfo& aLEInfo= mySmartMap(i);
|
|
|
|
BOP_ListIteratorOfListOfEdgeInfo anIt(aLEInfo);
|
|
for (; anIt.More(); anIt.Next()) {
|
|
BOP_EdgeInfo& anEdgeInfo=anIt.Value();
|
|
const TopoDS_Edge& aE=anEdgeInfo.Edge();
|
|
//
|
|
TopoDS_Vertex aVV=aV;
|
|
//
|
|
anIsIn=anEdgeInfo.IsIn();
|
|
if (anIsIn) {
|
|
//
|
|
aVV.Orientation(TopAbs_REVERSED);
|
|
anAngle=Angle2D (aVV, aE, myFace, aGAS, Standard_True);
|
|
}
|
|
//
|
|
else { // OUT
|
|
//
|
|
aVV.Orientation(TopAbs_FORWARD);
|
|
anAngle=Angle2D (aVV, aE, myFace, aGAS, Standard_False);
|
|
}
|
|
anEdgeInfo.SetAngle(anAngle);
|
|
|
|
}
|
|
}
|
|
//
|
|
// 4. Do
|
|
//
|
|
Standard_Boolean anIsOut, anIsNotPassed;
|
|
|
|
TopTools_SequenceOfShape aLS, aVertVa;
|
|
TColgp_SequenceOfPnt2d aCoordVa;
|
|
|
|
BOP_ListIteratorOfListOfEdgeInfo anIt;
|
|
|
|
for (i=1; i<=aNb; i++) {
|
|
const TopoDS_Vertex aVa=TopoDS::Vertex (mySmartMap.FindKey(i));
|
|
const BOP_ListOfEdgeInfo& aLEInfo=mySmartMap(i);
|
|
|
|
anIt.Initialize(aLEInfo);
|
|
for (; anIt.More(); anIt.Next()) {
|
|
BOP_EdgeInfo& anEdgeInfo=anIt.Value();
|
|
const TopoDS_Edge& aEOuta=anEdgeInfo.Edge();
|
|
|
|
anIsOut=!anEdgeInfo.IsIn();
|
|
anIsNotPassed=!anEdgeInfo.Passed();
|
|
|
|
if (anIsOut && anIsNotPassed) {
|
|
//
|
|
aLS.Clear();
|
|
aVertVa.Clear();
|
|
aCoordVa.Clear();
|
|
//
|
|
Path(aGAS, myFace, aVa, aEOuta, anEdgeInfo, aLS,
|
|
aVertVa, aCoordVa, myShapes, mySmartMap);
|
|
}
|
|
}
|
|
}
|
|
//
|
|
{
|
|
Standard_Integer aNbV, aNbE;
|
|
TopoDS_Vertex aV1, aV2;
|
|
BOPTColStd_ListOfListOfShape aShapes;
|
|
BOPTColStd_ListIteratorOfListOfListOfShape anItW(myShapes);
|
|
|
|
for (; anItW.More(); anItW.Next()) {
|
|
TopTools_IndexedMapOfShape aMV, aME;
|
|
const TopTools_ListOfShape& aLE=anItW.Value();
|
|
TopTools_ListIteratorOfListOfShape anItE(aLE);
|
|
for (; anItE.More(); anItE.Next()) {
|
|
const TopoDS_Edge& aE=TopoDS::Edge(anItE.Value());
|
|
aME.Add(aE);
|
|
TopExp::Vertices(aE, aV1, aV2);
|
|
aMV.Add(aV1);
|
|
aMV.Add(aV2);
|
|
}
|
|
aNbV=aMV.Extent();
|
|
aNbE=aME.Extent();
|
|
if (aNbV<=aNbE) {
|
|
aShapes.Append(aLE);
|
|
}
|
|
}
|
|
//
|
|
myShapes.Clear();
|
|
anItW.Initialize(aShapes);
|
|
for (; anItW.More(); anItW.Next()) {
|
|
const TopTools_ListOfShape& aLE=anItW.Value();
|
|
myShapes.Append(aLE);
|
|
}
|
|
}
|
|
//
|
|
myErrorStatus=0;
|
|
}
|
|
//=======================================================================
|
|
// function: Path
|
|
// purpose:
|
|
//=======================================================================
|
|
void Path (const GeomAdaptor_Surface& aGAS,
|
|
const TopoDS_Face& myFace,
|
|
const TopoDS_Vertex& aVa,
|
|
const TopoDS_Edge& aEOuta,
|
|
BOP_EdgeInfo& anEdgeInfo,
|
|
TopTools_SequenceOfShape& aLS,
|
|
TopTools_SequenceOfShape& aVertVa,
|
|
TColgp_SequenceOfPnt2d& aCoordVa,
|
|
BOPTColStd_ListOfListOfShape& myShapes,
|
|
BOP_IndexedDataMapOfVertexListEdgeInfo& mySmartMap)
|
|
|
|
{
|
|
Standard_Integer i,j, aNb, aNbj;
|
|
Standard_Real aTol, anAngleIn, anAngleOut, anAngle, aMinAngle;
|
|
Standard_Real aTol2D, aTol2D2;
|
|
Standard_Real aTol2, aD2;//, aTolUVb, aTolVVb;
|
|
Standard_Boolean anIsSameV2d, anIsSameV, anIsFound, anIsOut, anIsNotPassed;
|
|
BOP_ListIteratorOfListOfEdgeInfo anIt;
|
|
TopoDS_Vertex aVb;
|
|
TopoDS_Edge aEOutb;
|
|
//
|
|
aTol=1.e-7;
|
|
//
|
|
// append block
|
|
//
|
|
// Do not escape through edge from which you enter
|
|
aNb=aLS.Length();
|
|
if (aNb==1) {
|
|
const TopoDS_Shape& anEPrev=aLS(aNb);
|
|
if (anEPrev.IsSame(aEOuta)) {
|
|
return;
|
|
}
|
|
}
|
|
//
|
|
//
|
|
anEdgeInfo.SetPassed(Standard_True);
|
|
aLS.Append(aEOuta);
|
|
aVertVa.Append(aVa);
|
|
|
|
TopoDS_Vertex pVa=aVa;
|
|
pVa.Orientation(TopAbs_FORWARD);
|
|
gp_Pnt2d aPa=Coord2d(pVa, aEOuta, myFace);
|
|
aCoordVa.Append(aPa);
|
|
|
|
GetNextVertex (pVa, aEOuta, aVb);
|
|
|
|
gp_Pnt2d aPb=Coord2d(aVb, aEOuta, myFace);
|
|
|
|
//const BOP_ListOfEdgeInfo& aLEInfoVb=mySmartMap.FindFromKey(aVb);
|
|
//
|
|
aTol=2.*Tolerance2D(aVb, aGAS);
|
|
aTol2=10.*aTol*aTol;
|
|
//
|
|
aNb=aLS.Length();
|
|
if (aNb>0) {
|
|
//
|
|
TopTools_ListOfShape aBuf;
|
|
//
|
|
for (i=aNb; i>0; i--) {
|
|
const TopoDS_Shape& aVPrev=aVertVa(i);
|
|
const gp_Pnt2d& aPaPrev=aCoordVa(i);
|
|
const TopoDS_Shape& aEPrev=aLS(i);
|
|
|
|
aBuf.Append(aEPrev);
|
|
|
|
anIsSameV=aVPrev.IsSame(aVb);
|
|
anIsSameV2d=Standard_False;
|
|
|
|
if (anIsSameV) {
|
|
anIsSameV2d = Standard_True;
|
|
//
|
|
aD2=aPaPrev.SquareDistance(aPb);
|
|
anIsSameV2d =aD2<aTol2;
|
|
}//if (anIsSameV) {
|
|
//
|
|
if (anIsSameV && anIsSameV2d) {
|
|
myShapes.Append(aBuf);
|
|
//
|
|
TopTools_SequenceOfShape aLSt, aVertVat;
|
|
TColgp_SequenceOfPnt2d aCoordVat;
|
|
//
|
|
aNbj=i-1;
|
|
if (aNbj<1) {
|
|
//
|
|
aLS.Clear();
|
|
aVertVa.Clear();
|
|
aCoordVa.Clear();
|
|
//
|
|
return;
|
|
}
|
|
|
|
aVb=TopoDS::Vertex(aVertVa(i));
|
|
|
|
for (j=1; j<=aNbj; j++) {
|
|
aLSt.Append(aLS(j));
|
|
aVertVat.Append(aVertVa(j));
|
|
aCoordVat.Append(aCoordVa(j));
|
|
}
|
|
//
|
|
aLS.Clear();
|
|
aVertVa.Clear();
|
|
aCoordVa.Clear();
|
|
|
|
aLS=aLSt;
|
|
aVertVa=aVertVat;
|
|
aCoordVa=aCoordVat;
|
|
//
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
//
|
|
aTol2D=2.*Tolerance2D(aVb, aGAS);
|
|
aTol2D2=100.*aTol2D*aTol2D;
|
|
//
|
|
// anAngleIn in Vb from edge aEOuta
|
|
const BOP_ListOfEdgeInfo& aLEInfo=mySmartMap.FindFromKey(aVb);
|
|
//
|
|
anAngleIn=AngleIn(aEOuta, aLEInfo);
|
|
//
|
|
// aEOutb
|
|
BOP_EdgeInfo *pEdgeInfo=NULL;
|
|
|
|
aMinAngle=100.;
|
|
anIsFound=Standard_False;
|
|
|
|
Standard_Integer aCurIndexE = 0;
|
|
|
|
anIt.Initialize(aLEInfo);
|
|
for (; anIt.More(); anIt.Next()) {
|
|
BOP_EdgeInfo& anEI=anIt.Value();
|
|
const TopoDS_Edge& aE=anEI.Edge();
|
|
anIsOut=!anEI.IsIn();
|
|
anIsNotPassed=!anEI.Passed();
|
|
|
|
if (anIsOut && anIsNotPassed) {
|
|
aCurIndexE++;
|
|
//
|
|
// Is there one way to go out of the vertex
|
|
// we have to use it only.
|
|
Standard_Integer iCnt;
|
|
iCnt=NbWaysOut (aLEInfo);
|
|
//
|
|
if (!iCnt) {
|
|
// no way to go . (Error)
|
|
return ;
|
|
}
|
|
//
|
|
if (iCnt==1) {
|
|
// the one and only way to go out .
|
|
pEdgeInfo=&anEI;
|
|
anIsFound=Standard_True;
|
|
break;
|
|
}
|
|
//
|
|
// Look for minimal angle and make the choice.
|
|
gp_Pnt2d aP2Dx;
|
|
//
|
|
aP2Dx=Coord2dVf(aE, myFace);
|
|
//
|
|
aD2=aP2Dx.SquareDistance(aPb);
|
|
if (aD2 > aTol2D2){
|
|
continue;
|
|
}
|
|
//
|
|
//
|
|
anAngleOut=anEI.Angle();
|
|
//
|
|
anAngle=ClockWiseAngle(anAngleIn, anAngleOut);
|
|
if (anAngle < aMinAngle) {
|
|
aMinAngle=anAngle;
|
|
pEdgeInfo=&anEI;
|
|
anIsFound=Standard_True;
|
|
}
|
|
}
|
|
} // for (; anIt.More(); anIt.Next())
|
|
//
|
|
if (!anIsFound) {
|
|
// no way to go . (Error)
|
|
return;
|
|
}
|
|
|
|
aEOutb=pEdgeInfo->Edge();
|
|
//
|
|
Path (aGAS, myFace, aVb, aEOutb, *pEdgeInfo, aLS,
|
|
aVertVa, aCoordVa, myShapes, mySmartMap);
|
|
}
|
|
//=======================================================================
|
|
// function: Coord2dVf
|
|
// purpose:
|
|
//=======================================================================
|
|
gp_Pnt2d Coord2dVf (const TopoDS_Edge& aE,
|
|
const TopoDS_Face& aF)
|
|
{
|
|
Standard_Real aCoord=99.;
|
|
gp_Pnt2d aP2D1(aCoord, aCoord);
|
|
TopoDS_Iterator aIt;
|
|
//
|
|
aIt.Initialize(aE);
|
|
for (; aIt.More(); aIt.Next()) {
|
|
const TopoDS_Shape& aVx=aIt.Value();
|
|
if (aVx.Orientation()==TopAbs_FORWARD) {
|
|
const TopoDS_Vertex& aVxx=TopoDS::Vertex(aVx);
|
|
aP2D1=Coord2d(aVxx, aE, aF);
|
|
return aP2D1;
|
|
}
|
|
}
|
|
return aP2D1;
|
|
}
|
|
//=======================================================================
|
|
// function: Tolerance2D
|
|
// purpose:
|
|
//=======================================================================
|
|
Standard_Real Tolerance2D (const TopoDS_Vertex& aV,
|
|
const GeomAdaptor_Surface& aGAS)
|
|
{
|
|
Standard_Real aTol2D, anUr, aVr, aTolV3D;
|
|
GeomAbs_SurfaceType aType;
|
|
//
|
|
aType=aGAS.GetType();
|
|
aTolV3D=BRep_Tool::Tolerance(aV);
|
|
|
|
anUr=aGAS.UResolution(aTolV3D);
|
|
aVr =aGAS.VResolution(aTolV3D);
|
|
aTol2D=(aVr>anUr) ? aVr : anUr;
|
|
//
|
|
if (aType==GeomAbs_BSplineSurface||
|
|
aType==GeomAbs_Sphere||
|
|
GeomAbs_SurfaceOfRevolution) {
|
|
if (aTol2D < aTolV3D) {
|
|
aTol2D=aTolV3D;
|
|
}
|
|
}
|
|
if (aType==GeomAbs_BSplineSurface) {
|
|
aTol2D=1.1*aTol2D;
|
|
}
|
|
//
|
|
return aTol2D;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: Coord2d
|
|
// purpose:
|
|
//=======================================================================
|
|
gp_Pnt2d Coord2d (const TopoDS_Vertex& aV1,
|
|
const TopoDS_Edge& aE1,
|
|
const TopoDS_Face& aF)
|
|
{
|
|
Standard_Real aT, aFirst, aLast;
|
|
Handle(Geom2d_Curve) aC2D;
|
|
gp_Pnt2d aP2D1;
|
|
//
|
|
aT=BRep_Tool::Parameter (aV1, aE1, aF);
|
|
aC2D=BRep_Tool::CurveOnSurface(aE1, aF, aFirst, aLast);
|
|
aC2D->D0 (aT, aP2D1);
|
|
//
|
|
return aP2D1;
|
|
}
|
|
//=======================================================================
|
|
// function: AngleIn
|
|
// purpose:
|
|
//=======================================================================
|
|
Standard_Real AngleIn(const TopoDS_Edge& aEIn,
|
|
const BOP_ListOfEdgeInfo& aLEInfo)
|
|
{
|
|
Standard_Real anAngleIn;
|
|
Standard_Boolean anIsIn;
|
|
BOP_ListIteratorOfListOfEdgeInfo anIt;
|
|
|
|
anIt.Initialize(aLEInfo);
|
|
for (; anIt.More(); anIt.Next()) {
|
|
BOP_EdgeInfo& anEdgeInfo=anIt.Value();
|
|
const TopoDS_Edge& aE=anEdgeInfo.Edge();
|
|
anIsIn=anEdgeInfo.IsIn();
|
|
//
|
|
if (anIsIn && aE==aEIn) {
|
|
anAngleIn=anEdgeInfo.Angle();
|
|
return anAngleIn;
|
|
}
|
|
}
|
|
anAngleIn=0.;
|
|
return anAngleIn;
|
|
}
|
|
//=======================================================================
|
|
// function: ClockWiseAngle
|
|
// purpose:
|
|
//=======================================================================
|
|
Standard_Real ClockWiseAngle(const Standard_Real aAngleIn,
|
|
const Standard_Real aAngleOut)
|
|
{
|
|
Standard_Real aTwoPi=Standard_PI+Standard_PI;
|
|
Standard_Real dA, A1, A2, AIn, AOut ;
|
|
|
|
AIn=aAngleIn;
|
|
AOut=aAngleOut;
|
|
if (AIn >= aTwoPi) {
|
|
AIn=AIn-aTwoPi;
|
|
}
|
|
|
|
if (AOut >= aTwoPi) {
|
|
AOut=AOut-aTwoPi;
|
|
}
|
|
|
|
A1=AIn+Standard_PI;
|
|
|
|
if (A1 >= aTwoPi) {
|
|
A1=A1-aTwoPi;
|
|
}
|
|
|
|
A2=AOut;
|
|
|
|
dA=A1-A2;
|
|
if (dA <= 0.) {
|
|
dA=aTwoPi+dA;
|
|
//modified by NIZNHY-PKV Thu Feb 17 08:26:39 2011f
|
|
if (dA <= 1.e-14) {
|
|
dA=aTwoPi;
|
|
}
|
|
//modified by NIZNHY-PKV Thu Feb 17 08:26:42 2011t
|
|
}
|
|
//xx
|
|
else if (dA <= 1.e-14) {
|
|
dA=aTwoPi;
|
|
}
|
|
return dA;
|
|
}
|
|
//=======================================================================
|
|
// function: GetNextVertex
|
|
// purpose:
|
|
//=======================================================================
|
|
void GetNextVertex(const TopoDS_Vertex& aV,
|
|
const TopoDS_Edge& aE,
|
|
TopoDS_Vertex& aV1)
|
|
{
|
|
TopoDS_Iterator aIt;
|
|
//
|
|
aIt.Initialize(aE);
|
|
for (; aIt.More(); aIt.Next()) {
|
|
const TopoDS_Shape& aVx=aIt.Value();
|
|
if (!aVx.IsEqual(aV)) {
|
|
aV1=TopoDS::Vertex(aVx);
|
|
return ;
|
|
}
|
|
}
|
|
aV1=aV;
|
|
}
|
|
//=======================================================================
|
|
// function: Angle2D
|
|
// purpose:
|
|
//=======================================================================
|
|
Standard_Real Angle2D (const TopoDS_Vertex& aV,
|
|
const TopoDS_Edge& anEdge,
|
|
const TopoDS_Face& myFace,
|
|
const GeomAdaptor_Surface& aGAS,
|
|
const Standard_Boolean aFlag)
|
|
{
|
|
Standard_Real aFirst, aLast, aToler, dt, aTV, aTV1, anAngle, aTX;
|
|
gp_Pnt2d aPV, aPV1;
|
|
gp_Vec2d aV2D;
|
|
Handle(Geom2d_Curve) aC2D;
|
|
//
|
|
aTV=BRep_Tool::Parameter (aV, anEdge, myFace);
|
|
if (Precision::IsInfinite(aTV)) {
|
|
return 0.;
|
|
}
|
|
//
|
|
BOPTools_Tools2D::CurveOnSurface (anEdge, myFace, aC2D,
|
|
aFirst, aLast, aToler, Standard_True);
|
|
//dt=1.e-7;
|
|
dt=2.*Tolerance2D(aV, aGAS);
|
|
//
|
|
aTX=0.25*(aLast - aFirst);
|
|
if(dt > aTX) {
|
|
// to save direction of the curve as much as it possible
|
|
// in the case of big tolerances
|
|
dt = aTX;
|
|
}
|
|
//
|
|
if (fabs (aTV-aFirst) < fabs(aTV - aLast)) {
|
|
aTV1=aTV + dt;
|
|
}
|
|
else {
|
|
aTV1=aTV - dt;
|
|
}
|
|
//
|
|
aC2D->D0 (aTV, aPV);
|
|
aC2D->D0 (aTV1, aPV1);
|
|
//
|
|
if (aFlag) {//IN
|
|
gp_Vec2d aV2DIn(aPV1, aPV);
|
|
aV2D=aV2DIn;
|
|
}
|
|
else {
|
|
gp_Vec2d aV2DOut(aPV, aPV1);
|
|
aV2D=aV2DOut;
|
|
}
|
|
//
|
|
gp_Dir2d aDir2D(aV2D);
|
|
anAngle=Angle(aDir2D);
|
|
//
|
|
return anAngle;
|
|
}
|
|
//=======================================================================
|
|
// function: Angle
|
|
// purpose:
|
|
//=======================================================================
|
|
Standard_Real Angle (const gp_Dir2d& aDir2D)
|
|
{
|
|
gp_Dir2d aRefDir(1., 0.);
|
|
Standard_Real anAngle = aRefDir.Angle(aDir2D);
|
|
|
|
if (anAngle < 0.)
|
|
anAngle += Standard_PI + Standard_PI;
|
|
|
|
return anAngle;
|
|
}
|
|
//
|
|
//=======================================================================
|
|
// function: NbWaysOut
|
|
// purpose:
|
|
//=======================================================================
|
|
Standard_Integer NbWaysOut(const BOP_ListOfEdgeInfo& aLEInfo)
|
|
{
|
|
Standard_Boolean bIsOut, bIsNotPassed;
|
|
Standard_Integer iCnt=0;
|
|
BOP_ListIteratorOfListOfEdgeInfo anIt;
|
|
//
|
|
anIt.Initialize(aLEInfo);
|
|
for (; anIt.More(); anIt.Next()) {
|
|
BOP_EdgeInfo& anEI=anIt.Value();
|
|
//
|
|
bIsOut=!anEI.IsIn();
|
|
bIsNotPassed=!anEI.Passed();
|
|
if (bIsOut && bIsNotPassed) {
|
|
iCnt++;
|
|
}
|
|
}
|
|
return iCnt;
|
|
}
|