Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
c5f20409cThis file is pinned to the selected release. Download the original to open it in your design tool.
// Created on: 2003-10-21
// Created by: Mikhail KLOKOV
// Copyright (c) 2003-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 <BOPAlgo_BOP.hxx>
#include <BOPAlgo_PaveFiller.hxx>
#include <BOPDS_DS.hxx>
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <BRepAlgoAPI_Section.hxx>
#include <BRepFill_TrimShellCorner.hxx>
#include <BRepLib_MakeEdge.hxx>
#include <BRepLib_MakeWire.hxx>
#include <BRepLib_MakeVertex.hxx>
#include <BRepTools_ReShape.hxx>
#include <GCPnts_UniformAbscissa.hxx>
#include <Geom2d_Curve.hxx>
#include <GeomLib.hxx>
#include <gp_Ax2.hxx>
#include <gp_Pln.hxx>
#include <gp_Pnt2d.hxx>
#include <IntTools_BeanFaceIntersector.hxx>
#include <IntTools_Context.hxx>
#include <IntTools_Range.hxx>
#include <IntTools_Tools.hxx>
#include <TColgp_Array1OfDir.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TColgp_SequenceOfPnt.hxx>
#include <TColStd_ListOfInteger.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopLoc_Location.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Shell.hxx>
#include <TopoDS_Wire.hxx>
#include <TopTools_Array1OfListOfShape.hxx>
#include <TopTools_DataMapOfShapeListOfShape.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopTools_SequenceOfShape.hxx>
#include <BRepExtrema_ExtCC.hxx>
#include <ShapeFix_Edge.hxx>
static TopoDS_Edge FindEdgeCloseToBisectorPlane(const TopoDS_Vertex& theVertex,
TopoDS_Compound& theComp,
const gp_Ax1& theAxis);
static Standard_Boolean FindMiddleEdges(const TopoDS_Vertex& theVertex1,
const TopoDS_Vertex& theVertex2,
const gp_Ax1& theAxis,
TopoDS_Compound& theComp,
TopTools_ListOfShape& theElist);
static Standard_Boolean FindCommonVertex(const TopoDS_Edge& theFirstEdge,
const TopoDS_Edge& theLastEdge,
const TopoDS_Vertex& theFirstVertex,
const TopoDS_Vertex& theLastVertex,
TopoDS_Vertex& theCommonVertex);
static Standard_Boolean FindCommonVertex(const BOPDS_PDS& theDS,
const Standard_Integer theEIndex1,
const Standard_Integer theEIndex2,
const gp_Vec& theCrossDirection,
TopoDS_Vertex& theCommonVertex,
Standard_Real& theParamOnE1,
Standard_Real& theParamOnE2);
static Standard_Boolean SplitUEdges(const Handle(TopTools_HArray2OfShape)& theUEdges,
const BOPDS_PDS& theDS,
const gp_Vec& theCrossDirection,
TopTools_DataMapOfShapeListOfShape& theHistMap);
static void StoreVedgeInHistMap(const Handle(TopTools_HArray1OfShape)& theVEdges,
const Standard_Integer theIndex,
const TopoDS_Shape& theNewVedge,
TopTools_DataMapOfShapeListOfShape& theHistMap);
static void FindFreeVertices(const TopoDS_Shape& theShape,
const TopTools_MapOfShape& theVerticesToAvoid,
TopTools_ListOfShape& theListOfVertex);
static Standard_Boolean CheckAndOrientEdges(const TopTools_ListOfShape& theOrderedList,
const gp_Pnt2d& theFirstPoint,
const gp_Pnt2d& theLastPoint,
const TopoDS_Face& theFace,
TopTools_ListOfShape& theOrientedList);
static Standard_Boolean FillGap(const TopoDS_Vertex& theFirstVertex,
const TopoDS_Vertex& theLastVertex,
const gp_Pnt2d& theFirstPoint,
const gp_Pnt2d& theLastPoint,
const TopoDS_Face& theFace,
const TopoDS_Compound& theSectionEdges,
TopTools_ListOfShape& theOrderedList);
static Standard_Boolean FindNextEdge(const TopoDS_Vertex& theFirstVertex,
const TopoDS_Vertex& theLastVertex,
const TopTools_IndexedDataMapOfShapeListOfShape& theMapVE,
const TopTools_MapOfShape& theMapToAvoid,
TopTools_ListOfShape& theOrderedList);
static Standard_Boolean FindVertex(const TopoDS_Edge& theEdge,
const Standard_Integer theRank,
const BOPDS_PDS& theDS,
const TopTools_DataMapOfShapeListOfShape& theHistMap,
TopoDS_Vertex& theVertex,
BOPDS_Pave& thePave);
static Standard_Boolean FindNextVertex(const Standard_Integer theEdgeIndex,
const BOPDS_Pave& thePrevPave,
const BOPDS_PDS& theDS,
TopoDS_Vertex& theNextVertex,
BOPDS_Pave& thePave);
static Standard_Boolean GetPave(const Standard_Integer theEdgeIndex,
const Standard_Boolean isFirst,
const BOPDS_PDS& theDS,
BOPDS_Pave& thePave);
static Standard_Boolean FindFromUEdge(const TopoDS_Edge& theUE1Old,
const TopoDS_Edge& theUE2Old,
const TopoDS_Edge& theUE1New,
const TopoDS_Edge& theUE2New,
const TopoDS_Face& theFace,
const TopoDS_Compound& theSecEdges,
const Standard_Integer theRank,
const TopoDS_Edge& theBoundEdge,
const Standard_Integer theBoundEdgeIndex,
const BOPDS_PDS& theDS,
const TopTools_DataMapOfShapeListOfShape& theHistMap,
TopoDS_Compound& theSecEdgesNew,
TopTools_ListOfShape& theListOfWireEdges,
BOPDS_Pave& theFoundPave,
Standard_Boolean& isOnUEdge);
static Standard_Boolean FindFromVEdge(const BOPDS_Pave& thePrevPave,
const Standard_Boolean& isOnUEdge,
const TopoDS_Edge& theUE1Old,
const TopoDS_Edge& theUE2Old,
const TopoDS_Face& theFace,
const TopoDS_Compound& theSecEdges,
const Standard_Integer theRank,
const TopoDS_Edge& theBoundEdge,
const Standard_Integer theBoundEdgeIndex,
const BOPDS_PDS& theDS,
const TopTools_DataMapOfShapeListOfShape& theHistMap,
TopTools_ListOfShape& theListOfWireEdges,
Standard_Boolean& isSectionFound);
static void RemoveEdges(const TopoDS_Compound& theSourceComp,
const TopTools_ListOfShape& theListToRemove,
TopoDS_Compound& theResultComp);
static Standard_Boolean FilterSectionEdges(const BOPDS_VectorOfCurve& theBCurves,
const TopoDS_Face& theSecPlane,
const BOPDS_PDS& theDS,
TopoDS_Compound& theResult);
static Standard_Boolean GetUEdges(const Standard_Integer theIndex,
const Standard_Integer theRank,
const Handle(TopTools_HArray2OfShape)& theUEdges,
const TopoDS_Edge& theBoundEdge,
const TopoDS_Face& theFace,
TopoDS_Edge& theFirstUEdge,
TopoDS_Edge& theSecondUEdge);
static Standard_Real ComputeAveragePlaneAndMaxDeviation(const TopoDS_Shape& aWire,
gp_Pln& thePlane,
Standard_Boolean& IsSingular);
static void UpdateSectionEdge(TopoDS_Edge& theEdge,
const TopoDS_Vertex& theConstVertex,
TopoDS_Vertex& theVertex,
const Standard_Real theParam);
//=================================================================================================
BRepFill_TrimShellCorner::BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces,
const BRepFill_TransitionStyle theTransition,
const gp_Ax2& theAxeOfBisPlane,
const gp_Vec& theIntPointCrossDir)
: myTransition(theTransition),
myAxeOfBisPlane(theAxeOfBisPlane),
myIntPointCrossDir(theIntPointCrossDir),
myDone(Standard_False),
myHasSection(Standard_False)
{
myFaces = new TopTools_HArray2OfShape(theFaces->LowerRow(),
theFaces->UpperRow(),
theFaces->LowerCol(),
theFaces->UpperCol());
myFaces->ChangeArray2() = theFaces->Array2();
}
//=================================================================================================
void BRepFill_TrimShellCorner::AddBounds(const Handle(TopTools_HArray2OfShape)& theBounds)
{
myBounds = new TopTools_HArray2OfShape(theBounds->LowerRow(),
theBounds->UpperRow(),
theBounds->LowerCol(),
theBounds->UpperCol());
myBounds->ChangeArray2() = theBounds->Array2();
}
//=================================================================================================
void BRepFill_TrimShellCorner::AddUEdges(const Handle(TopTools_HArray2OfShape)& theUEdges)
{
myUEdges = new TopTools_HArray2OfShape(theUEdges->LowerRow(),
theUEdges->UpperRow(),
theUEdges->LowerCol(),
theUEdges->UpperCol());
myUEdges->ChangeArray2() = theUEdges->Array2();
}
//=================================================================================================
void BRepFill_TrimShellCorner::AddVEdges(const Handle(TopTools_HArray2OfShape)& theVEdges,
const Standard_Integer theIndex)
{
myVEdges = new TopTools_HArray1OfShape(theVEdges->LowerRow(), theVEdges->UpperRow());
for (Standard_Integer i = theVEdges->LowerRow(); i <= theVEdges->UpperRow(); i++)
myVEdges->SetValue(i, theVEdges->Value(i, theIndex));
}
//=================================================================================================
void BRepFill_TrimShellCorner::Perform()
{
Standard_Integer anIndex1, anIndex2, nF1, nF2, i, j, aNbP, aNbC;
Standard_Boolean bhassec;
myDone = Standard_False;
myHistMap.Clear();
if (myFaces->RowLength() != 2)
return;
Standard_Integer ii = 0, jj = 0;
BRep_Builder aBB;
for (jj = myFaces->LowerCol(); jj <= myFaces->UpperCol(); jj++)
{
TopoDS_Shell aShell;
aBB.MakeShell(aShell);
for (ii = myFaces->LowerRow(); ii <= myFaces->UpperRow(); ii++)
{
aBB.Add(aShell, myFaces->Value(ii, jj));
}
aShell.Closed(BRep_Tool::IsClosed(aShell));
if (jj == myFaces->LowerCol())
{
myShape1 = aShell;
}
else
{
myShape2 = aShell;
}
}
Standard_Real aMaxTol = 0.;
TopExp_Explorer anExp(myShape1, TopAbs_VERTEX);
for (; anExp.More(); anExp.Next())
{
aMaxTol = Max(aMaxTol, BRep_Tool::Tolerance(TopoDS::Vertex(anExp.Current())));
}
anExp.Init(myShape2, TopAbs_VERTEX);
for (; anExp.More(); anExp.Next())
{
aMaxTol = Max(aMaxTol, BRep_Tool::Tolerance(TopoDS::Vertex(anExp.Current())));
}
Standard_Real aFuzzy = 4. * Precision::Confusion();
BOPAlgo_PaveFiller aPF;
TopTools_ListOfShape aLS;
aLS.Append(myShape1);
aLS.Append(myShape2);
aPF.SetArguments(aLS);
if (aMaxTol < 1.005 * Precision::Confusion())
{
aFuzzy = Max(aPF.FuzzyValue(), aFuzzy);
aPF.SetFuzzyValue(aFuzzy);
}
//
aPF.Perform();
if (aPF.HasErrors())
{
return;
}
//
const BOPDS_PDS& theDS = aPF.PDS();
//
BOPDS_VectorOfInterfFF& aFFs = theDS->InterfFF();
Standard_Integer aNbFFs = aFFs.Length();
if (!SplitUEdges(myUEdges, theDS, myIntPointCrossDir, myHistMap))
{
return;
}
for (ii = myFaces->LowerRow(); ii <= myFaces->UpperRow(); ii++)
{
TopoDS_Shape aF1 = myFaces->Value(ii, myFaces->LowerCol());
TopoDS_Shape aF2 = myFaces->Value(ii, myFaces->UpperCol());
//
anIndex1 = theDS->Index(aF1);
anIndex2 = theDS->Index(aF2);
if ((anIndex1 == -1) || (anIndex2 == -1))
continue;
for (i = 0; i < aNbFFs; ++i)
{
BOPDS_InterfFF& aFFi = aFFs(i);
aFFi.Indices(nF1, nF2);
//
BOPDS_VectorOfPoint& aVP = aFFi.ChangePoints();
aNbP = aVP.Length();
const BOPDS_VectorOfCurve& aVC = aFFi.Curves();
aNbC = aVC.Length();
if (!aNbP && !aNbC)
{
if (!theDS->HasInterfSubShapes(nF1, nF2))
{
continue;
}
}
//
if ((nF1 == anIndex1) && (nF2 == anIndex2))
{
bhassec = Standard_False;
//
for (j = 0; j < aNbC; ++j)
{
const BOPDS_Curve& aBCurve = aVC(j);
const BOPDS_ListOfPaveBlock& aSectEdges = aBCurve.PaveBlocks();
//
if (aSectEdges.Extent())
{
bhassec = Standard_True;
break;
}
}
if (!bhassec)
{
if (!MakeFacesNonSec(ii, theDS, anIndex1, anIndex2))
{
myHistMap.Clear();
return;
}
}
else
{
if (!MakeFacesSec(ii, theDS, anIndex1, anIndex2, i))
{
myHistMap.Clear();
return;
}
}
break;
}
}
}
myDone = Standard_True;
}
//=================================================================================================
Standard_Boolean BRepFill_TrimShellCorner::IsDone() const
{
return myDone;
}
//=================================================================================================
Standard_Boolean BRepFill_TrimShellCorner::HasSection() const
{
return myHasSection;
}
//=================================================================================================
void BRepFill_TrimShellCorner::Modified(const TopoDS_Shape& theShape,
TopTools_ListOfShape& theModified)
{
theModified.Clear();
if (myHistMap.IsBound(theShape))
{
theModified = myHistMap.Find(theShape);
}
}
// ----------------------------------------------------------------------------------------------------
// function: MakeFacesNonSec
// purpose: Updates <myHistMap> by new faces in the case when old faces do not intersect
// ----------------------------------------------------------------------------------------------------
Standard_Boolean BRepFill_TrimShellCorner::MakeFacesNonSec(const Standard_Integer theIndex,
const BOPDS_PDS& theDS,
const Standard_Integer theFaceIndex1,
const Standard_Integer theFaceIndex2)
{
Standard_Boolean bHasNewEdge = Standard_False;
TopoDS_Edge aNewEdge;
BRep_Builder aBB;
const TopoDS_Shape& aE1 = myBounds->Value(theIndex, 1);
const TopoDS_Shape& aE2 = myBounds->Value(theIndex, 2);
// search common vertex between bounds. begin
TopoDS_Vertex aCommonVertex;
Standard_Integer anIndex1 = theDS->Index(aE1);
Standard_Integer anIndex2 = theDS->Index(aE2);
Standard_Real apar1 = 0., apar2 = 0.;
Standard_Boolean bvertexfound =
FindCommonVertex(theDS, anIndex1, anIndex2, myIntPointCrossDir, aCommonVertex, apar1, apar2);
// search common vertex between bounds. end
Handle(BRepTools_ReShape) aSubstitutor = new BRepTools_ReShape();
// search common vertices between uedges. begin
TopTools_ListOfShape aCommonVertices;
Standard_Integer acommonflag = 0; // 0 - no, 1 - first pair, 2 - second pair, 3 - both
Standard_Integer ueit = 0, eindex = 0;
for (ueit = 1, eindex = theIndex; ueit <= 2; ueit++, eindex++)
{
const TopoDS_Shape& aShape1 = myUEdges->Value(eindex, myUEdges->LowerCol());
const TopoDS_Shape& aShape2 = myUEdges->Value(eindex, myUEdges->UpperCol());
TopoDS_Edge aUE1 = TopoDS::Edge(aShape1);
TopoDS_Edge aUE2 = TopoDS::Edge(aShape2);
if (myHistMap.IsBound(aShape1))
{
const TopTools_ListOfShape& lst = myHistMap.Find(aShape1);
if (!lst.IsEmpty())
aUE1 = TopoDS::Edge(lst.First());
}
if (myHistMap.IsBound(aShape2))
{
const TopTools_ListOfShape& lst = myHistMap.Find(aShape2);
if (!lst.IsEmpty())
aUE2 = TopoDS::Edge(lst.First());
}
if (!aShape1.IsSame(aUE1))
aSubstitutor->Replace(aShape1.Oriented(TopAbs_FORWARD), aUE1.Oriented(TopAbs_FORWARD));
if (!aShape2.IsSame(aUE2))
aSubstitutor->Replace(aShape2.Oriented(TopAbs_FORWARD), aUE2.Oriented(TopAbs_FORWARD));
TopoDS_Vertex V1 = TopExp::LastVertex(aUE1);
TopoDS_Vertex V2 = TopExp::FirstVertex(aUE2);
if (V1.IsSame(V2))
{
acommonflag = (acommonflag == 0) ? ueit : 3;
aCommonVertices.Append(V1);
}
}
// search common vertices between uedges. end
if (bvertexfound)
{
if (aCommonVertices.Extent() != 1)
return Standard_False;
if (acommonflag == 1)
aNewEdge = BRepLib_MakeEdge(TopoDS::Vertex(aCommonVertices.First()), aCommonVertex);
else
aNewEdge = BRepLib_MakeEdge(aCommonVertex, TopoDS::Vertex(aCommonVertices.First()));
bHasNewEdge = Standard_True;
}
if (aCommonVertices.Extent() == 2)
{
aNewEdge = BRepLib_MakeEdge(TopoDS::Vertex(aCommonVertices.First()),
TopoDS::Vertex(aCommonVertices.Last()));
bHasNewEdge = Standard_True;
}
Standard_Integer fit = 0;
for (fit = 1; fit <= 2; fit++)
{
TopoDS_Compound aComp;
TopTools_MapOfShape aMapV;
aBB.MakeCompound(aComp);
for (ueit = 1, eindex = theIndex; ueit <= 2; ueit++, eindex++)
{
const TopoDS_Shape& aShape = myUEdges->Value(eindex, myUEdges->LowerCol() + fit - 1);
TopoDS_Shape aUE = aShape;
if (myHistMap.IsBound(aShape))
{
const TopTools_ListOfShape& lst = myHistMap.Find(aShape);
if (!lst.IsEmpty())
aUE = TopoDS::Edge(lst.First());
}
const TopoDS_Shape& aV =
(fit == 1) ? TopExp::FirstVertex(TopoDS::Edge(aUE)) : TopExp::LastVertex(TopoDS::Edge(aUE));
aMapV.Add(aV);
aBB.Add(aComp, aUE);
}
if (bHasNewEdge)
{
aBB.Add(aComp, aNewEdge);
StoreVedgeInHistMap(myVEdges, theIndex, aNewEdge, myHistMap);
}
TopTools_ListOfShape alonevertices;
FindFreeVertices(aComp, aMapV, alonevertices);
if (!alonevertices.IsEmpty() && (alonevertices.Extent() != 2))
return Standard_False;
Standard_Integer aFaceIndex = (fit == 1) ? theFaceIndex1 : theFaceIndex2;
TopoDS_Shape aFace = theDS->Shape(aFaceIndex);
TopAbs_Orientation aFaceOri = aFace.Orientation();
aFace.Orientation(TopAbs_FORWARD);
TopExp_Explorer anExpE(aFace, TopAbs_EDGE);
if (bHasNewEdge)
{
aNewEdge.Orientation(TopAbs_FORWARD);
// Refer to BrepFill_Sweep.cxx BuildEdge Construct an edge via an iso
gp_Pnt P1, P2;
Standard_Real p11, p12, p21, p22;
P1 = BRep_Tool::Pnt(TopExp::FirstVertex(TopoDS::Edge(aNewEdge)));
P2 = BRep_Tool::Pnt(TopExp::LastVertex(TopoDS::Edge(aNewEdge)));
TopoDS_Edge aERef = TopoDS::Edge(fit == 1 ? aE1 : aE2);
p11 = P1.Distance(BRep_Tool::Pnt(TopExp::FirstVertex(aERef)));
p22 = P2.Distance(BRep_Tool::Pnt(TopExp::LastVertex(aERef)));
p12 = P1.Distance(BRep_Tool::Pnt(TopExp::LastVertex(aERef)));
p21 = P2.Distance(BRep_Tool::Pnt(TopExp::FirstVertex(aERef)));
if (p11 > p12 && p22 > p21)
{
aNewEdge.Reverse();
}
// for nonPlane surface, we should add pCurve
Handle(ShapeFix_Edge) sfe = new ShapeFix_Edge();
sfe->FixAddPCurve(aNewEdge, TopoDS::Face(aFace), Standard_False);
}
TopTools_ListOfShape aOrderedList;
if (!alonevertices.IsEmpty())
{
Standard_Integer anEIndex = (fit == 1) ? anIndex1 : anIndex2;
Standard_Boolean bfound1 = Standard_False;
Standard_Boolean bfound2 = Standard_False;
Standard_Real aparam1 = 0., aparam2 = 0.;
BOPDS_ListOfPave aLP;
theDS->Paves(anEIndex, aLP);
BOPDS_ListIteratorOfListOfPave aIt;
aIt.Initialize(aLP);
for (; aIt.More(); aIt.Next())
{
const BOPDS_Pave& aPave = aIt.Value();
const TopoDS_Shape& aV = theDS->Shape(aPave.Index());
if (aV.IsSame(alonevertices.First()))
{
if (!bfound1)
{
aparam1 = aPave.Parameter();
bfound1 = Standard_True;
}
}
if (aV.IsSame(alonevertices.Last()))
{
if (!bfound2)
{
aparam2 = aPave.Parameter();
bfound2 = Standard_True;
}
}
}
if (bfound1 && bfound2)
{
TopoDS_Edge aNewBoundE;
if (fit == 1)
{
aNewBoundE = TopoDS::Edge(aE1.EmptyCopied());
}
else
{
aNewBoundE = TopoDS::Edge(aE2.EmptyCopied());
}
TopoDS_Vertex aV1, aV2;
if (aparam1 < aparam2)
{
aV1 = TopoDS::Vertex(alonevertices.First());
aV2 = TopoDS::Vertex(alonevertices.Last());
}
else
{
aV1 = TopoDS::Vertex(alonevertices.Last());
aV2 = TopoDS::Vertex(alonevertices.First());
Standard_Real tmp = aparam1;
aparam1 = aparam2;
aparam2 = tmp;
}
aV1.Orientation(TopAbs_FORWARD);
aV2.Orientation(TopAbs_REVERSED);
aBB.Add(aNewBoundE, aV1);
aBB.Add(aNewBoundE, aV2);
aBB.Range(aNewBoundE, aparam1, aparam2);
aNewBoundE.Orientation(TopAbs_FORWARD);
aOrderedList.Append(aNewBoundE);
if (bHasNewEdge)
{
TopExp_Explorer anExpV(aNewEdge, TopAbs_VERTEX);
Standard_Boolean bfoundv = Standard_False;
for (; !bfoundv && anExpV.More(); anExpV.Next())
{
if (aV2.IsSame(anExpV.Current()))
bfoundv = Standard_True;
}
if (bfoundv)
aOrderedList.Append(aNewEdge);
else
aOrderedList.Prepend(aNewEdge);
}
}
else
{
return Standard_False;
}
}
else
{
if (bHasNewEdge)
{
aOrderedList.Append(aNewEdge);
}
}
if (!aOrderedList.IsEmpty())
{
TopoDS_Wire aW;
aBB.MakeWire(aW);
TopTools_ListIteratorOfListOfShape anItE(aOrderedList);
for (; anItE.More(); anItE.Next())
{
aBB.Add(aW, anItE.Value());
}
if (fit == 1)
aSubstitutor->Replace(aE1.Oriented(TopAbs_FORWARD), aW);
else
aSubstitutor->Replace(aE2.Oriented(TopAbs_FORWARD), aW);
}
aSubstitutor->Apply(aFace);
TopoDS_Shape aNewFace = aSubstitutor->Value(aFace);
aNewFace.Orientation(aFaceOri);
TopTools_ListOfShape atmpList;
atmpList.Append(aNewFace);
myHistMap.Bind(aFace, atmpList);
anExpE.Init(aFace, TopAbs_EDGE);
for (; anExpE.More(); anExpE.Next())
{
TopoDS_Shape aNewValue = aSubstitutor->Value(anExpE.Current());
if (aNewValue.IsNull() || aNewValue.IsSame(anExpE.Current()))
continue;
if (myHistMap.IsBound(anExpE.Current()))
continue;
TopTools_ListOfShape aListOfNewEdge;
TopExp_Explorer anExpE2(aNewValue, TopAbs_EDGE);
for (; anExpE2.More(); anExpE2.Next())
{
aListOfNewEdge.Append(anExpE2.Current());
}
myHistMap.Bind(anExpE.Current(), aListOfNewEdge);
}
}
return Standard_True;
}
// ----------------------------------------------------------------------------------------------------
// function: MakeFacesSec
// purpose: Updates <myHistMap> by new faces in the case when old faces intersect each other
// ----------------------------------------------------------------------------------------------------
Standard_Boolean BRepFill_TrimShellCorner::MakeFacesSec(const Standard_Integer theIndex,
const BOPDS_PDS& theDS,
const Standard_Integer theFaceIndex1,
const Standard_Integer theFaceIndex2,
const Standard_Integer theSSInterfIndex)
{
const BOPDS_VectorOfInterfFF& aFFs = theDS->InterfFF();
const BOPDS_InterfFF& aFFi = aFFs(theSSInterfIndex);
const BOPDS_VectorOfCurve& aBCurves = aFFi.Curves();
TopoDS_Compound aSecEdges;
TopoDS_Face aSecPlane;
if (!FilterSectionEdges(aBCurves, aSecPlane, theDS, aSecEdges))
return Standard_False;
// Extract vertices on the intersection of correspondent U-edges
const TopoDS_Shape& LeftE1 = myUEdges->Value(theIndex, 1);
const TopoDS_Shape& LeftE2 = myUEdges->Value(theIndex, 2);
const TopoDS_Shape& RightE1 = myUEdges->Value(theIndex + 1, 1);
const TopoDS_Shape& RightE2 = myUEdges->Value(theIndex + 1, 2);
Standard_Integer IndexOfLeftE1 = theDS->Index(LeftE1);
Standard_Integer IndexOfLeftE2 = theDS->Index(LeftE2);
Standard_Integer IndexOfRightE1 = theDS->Index(RightE1);
Standard_Integer IndexOfRightE2 = theDS->Index(RightE2);
TopoDS_Vertex FirstVertex, LastVertex;
Standard_Real ParamOnLeftE1, ParamOnLeftE2, ParamOnRightE1, ParamOnRightE2;
FindCommonVertex(theDS,
IndexOfLeftE1,
IndexOfLeftE2,
myIntPointCrossDir,
FirstVertex,
ParamOnLeftE1,
ParamOnLeftE2);
FindCommonVertex(theDS,
IndexOfRightE1,
IndexOfRightE2,
myIntPointCrossDir,
LastVertex,
ParamOnRightE1,
ParamOnRightE2);
TopoDS_Shape SecWire;
gp_Pln SecPlane;
Standard_Boolean IsSingular;
Standard_Boolean WireFound =
ChooseSection(aSecEdges, FirstVertex, LastVertex, SecWire, SecPlane, IsSingular);
if (WireFound)
{
// aSecEdges = SecWire;
TopoDS_Compound aComp;
BRep_Builder BB;
BB.MakeCompound(aComp);
TopExp_Explorer explo(SecWire, TopAbs_EDGE);
for (; explo.More(); explo.Next())
BB.Add(aComp, explo.Current());
aSecEdges = aComp;
StoreVedgeInHistMap(myVEdges, theIndex, SecWire, myHistMap);
}
TopTools_ListOfShape aCommonVertices;
// Standard_Integer acommonflag = 0; // 0 - no, 1 - first pair, 2 - second pair, 3 - both
Standard_Integer fit = 0; //, ueit = 0, eindex = 0, i = 0;
Handle(BRepTools_ReShape) aSubstitutor = new BRepTools_ReShape();
for (fit = 0; fit < 2; fit++)
{
Standard_Integer aFaceIndex = (fit == 0) ? theFaceIndex1 : theFaceIndex2;
TopoDS_Face aFace = TopoDS::Face(theDS->Shape(aFaceIndex));
TopAbs_Orientation aFaceOri = aFace.Orientation();
TopoDS_Face aFaceF = aFace;
aFaceF.Orientation(TopAbs_FORWARD);
TopoDS_Edge aBoundEdge = TopoDS::Edge(myBounds->Value(theIndex, myBounds->LowerCol() + fit));
Standard_Integer aBoundEdgeIndex = theDS->Index(aBoundEdge);
TopoDS_Edge aUE1;
TopoDS_Edge aUE2;
if (!GetUEdges(theIndex, fit, myUEdges, aBoundEdge, aFaceF, aUE1, aUE2))
return Standard_False;
TopoDS_Edge aUE1old = aUE1;
TopoDS_Edge aUE2old = aUE2;
if (myHistMap.IsBound(aUE1))
{
const TopTools_ListOfShape& lst = myHistMap.Find(aUE1);
if (!lst.IsEmpty())
{
const TopoDS_Shape& anEdge = lst.First().Oriented(aUE1.Orientation());
if (!aUE1.IsSame(anEdge))
aSubstitutor->Replace(aUE1.Oriented(TopAbs_FORWARD), anEdge.Oriented(TopAbs_FORWARD));
aUE1 = TopoDS::Edge(anEdge);
}
}
if (myHistMap.IsBound(aUE2))
{
const TopTools_ListOfShape& lst = myHistMap.Find(aUE2);
if (!lst.IsEmpty())
{
const TopoDS_Shape& anEdge = lst.First().Oriented(aUE2.Orientation());
if (!aUE2.IsSame(anEdge))
aSubstitutor->Replace(aUE2.Oriented(TopAbs_FORWARD), anEdge.Oriented(TopAbs_FORWARD));
aUE2 = TopoDS::Edge(anEdge);
}
}
TopoDS_Vertex aPrevVertex, aNextVertex;
TopoDS_Compound aCompOfSecEdges = aSecEdges;
TopTools_ListOfShape aListOfWireEdges;
BRep_Builder aBB;
BOPDS_Pave aPave1;
Standard_Boolean isPave1OnUEdge = Standard_True;
if (FindFromUEdge(aUE1old,
aUE2old,
aUE1,
aUE2,
aFace,
aSecEdges,
fit,
aBoundEdge,
aBoundEdgeIndex,
theDS,
myHistMap,
aCompOfSecEdges,
aListOfWireEdges,
aPave1,
isPave1OnUEdge))
{
TopTools_ListOfShape aSecondListOfEdges;
Standard_Boolean bisSectionFound = Standard_False;
if (!FindFromVEdge(aPave1,
isPave1OnUEdge,
aUE1old,
aUE2old,
aFace,
aCompOfSecEdges,
fit,
aBoundEdge,
aBoundEdgeIndex,
theDS,
myHistMap,
aSecondListOfEdges,
bisSectionFound))
{
return Standard_False;
}
if (!bisSectionFound && aListOfWireEdges.IsEmpty())
{
return Standard_False;
}
aListOfWireEdges.Append(aSecondListOfEdges);
}
else
{
return Standard_False;
}
if (!aListOfWireEdges.IsEmpty())
{
TopoDS_Wire aW;
aBB.MakeWire(aW);
TopTools_ListIteratorOfListOfShape aEIt(aListOfWireEdges);
for (; aEIt.More(); aEIt.Next())
{
if (!aBoundEdge.IsSame(aEIt.Value()))
aBB.Add(aW, aEIt.Value());
}
aSubstitutor->Replace(aBoundEdge.Oriented(TopAbs_FORWARD), aW);
}
aSubstitutor->Apply(aFace);
TopoDS_Shape aNewFace = aSubstitutor->Value(aFace);
aNewFace.Orientation(aFaceOri);
TopTools_ListOfShape atmpList;
atmpList.Append(aNewFace);
myHistMap.Bind(aFace, atmpList);
TopExp_Explorer anExpE(aFace, TopAbs_EDGE);
for (; anExpE.More(); anExpE.Next())
{
TopoDS_Shape aNewValue = aSubstitutor->Value(anExpE.Current());
if (aNewValue.IsNull() || aNewValue.IsSame(anExpE.Current()))
continue;
if (myHistMap.IsBound(anExpE.Current()))
continue;
TopTools_ListOfShape aListOfNewEdge;
TopExp_Explorer anExpE2(aNewValue, TopAbs_EDGE);
for (; anExpE2.More(); anExpE2.Next())
{
aListOfNewEdge.Append(anExpE2.Current());
}
myHistMap.Bind(anExpE.Current(), aListOfNewEdge);
}
}
return Standard_True;
}
//=================================================================================================
Standard_Boolean BRepFill_TrimShellCorner::ChooseSection(const TopoDS_Shape& Comp,
const TopoDS_Vertex& theFirstVertex,
const TopoDS_Vertex& theLastVertex,
TopoDS_Shape& resWire,
gp_Pln& resPlane,
Standard_Boolean& IsSingular)
{
IsSingular = Standard_False;
Standard_Integer ind, i, j;
BRep_Builder BB;
if (myTransition == BRepFill_Right && !theFirstVertex.IsNull()
&& !theLastVertex.IsNull()) // the case where section wire goes from
// its known first vertex to its known last vertex
{
TopoDS_Wire NewWire;
BB.MakeWire(NewWire);
TopoDS_Compound OldComp;
BB.MakeCompound(OldComp);
TopoDS_Iterator iter(Comp);
for (; iter.More(); iter.Next())
BB.Add(OldComp, iter.Value());
TopoDS_Edge FirstEdge =
FindEdgeCloseToBisectorPlane(theFirstVertex, OldComp, myAxeOfBisPlane.Axis());
if (FirstEdge.IsNull())
return Standard_False;
iter.Initialize(OldComp);
if (!iter.More())
{
iter.Initialize(Comp);
BB.Add(OldComp, iter.Value());
}
TopoDS_Edge LastEdge =
FindEdgeCloseToBisectorPlane(theLastVertex, OldComp, myAxeOfBisPlane.Axis());
if (LastEdge.IsNull())
return Standard_False;
if (FirstEdge.IsNull() || LastEdge.IsNull())
{
return Standard_False;
}
BB.Add(NewWire, FirstEdge);
if (!FirstEdge.IsSame(LastEdge))
{
TopoDS_Vertex aCommonVertex;
Standard_Boolean CommonVertexExists =
FindCommonVertex(FirstEdge, LastEdge, theFirstVertex, theLastVertex, aCommonVertex);
if (CommonVertexExists)
BB.Add(NewWire, LastEdge);
else
{
TopoDS_Vertex Vertex1, Vertex2, V1, V2;
TopExp::Vertices(FirstEdge, V1, V2);
Vertex1 = (theFirstVertex.IsSame(V1)) ? V2 : V1;
TopExp::Vertices(LastEdge, V1, V2);
Vertex2 = (theLastVertex.IsSame(V1)) ? V2 : V1;
TopTools_ListOfShape MiddleEdges;
if (FindMiddleEdges(Vertex1, Vertex2, myAxeOfBisPlane.Axis(), OldComp, MiddleEdges))
{
TopTools_ListIteratorOfListOfShape itl(MiddleEdges);
for (; itl.More(); itl.Next())
BB.Add(NewWire, itl.Value());
BB.Add(NewWire, LastEdge);
}
else
{
// trim <FirstEdge> and <LastEdge> in the points of extrema
// these points become new vertex with centre between them
BRepExtrema_ExtCC Extrema(FirstEdge, LastEdge);
if (Extrema.IsDone() && Extrema.NbExt() > 0)
{
Standard_Integer imin = 1;
for (i = 2; i <= Extrema.NbExt(); i++)
if (Extrema.SquareDistance(i) < Extrema.SquareDistance(imin))
imin = i;
Standard_Real aMinDist = sqrt(Extrema.SquareDistance(imin));
Standard_Real ParamOnFirstEdge = Extrema.ParameterOnE1(imin);
Standard_Real ParamOnLastEdge = Extrema.ParameterOnE2(imin);
gp_Pnt PointOnFirstEdge = Extrema.PointOnE1(imin);
gp_Pnt PointOnLastEdge = Extrema.PointOnE2(imin);
gp_Pnt MidPnt((PointOnFirstEdge.XYZ() + PointOnLastEdge.XYZ()) / 2);
aCommonVertex = BRepLib_MakeVertex(MidPnt);
BB.UpdateVertex(aCommonVertex, 1.001 * aMinDist / 2);
UpdateSectionEdge(FirstEdge, theFirstVertex, aCommonVertex, ParamOnFirstEdge);
UpdateSectionEdge(LastEdge, theLastVertex, aCommonVertex, ParamOnLastEdge);
BB.Add(NewWire, LastEdge);
}
}
}
}
resWire = NewWire;
resPlane = gp_Pln(myAxeOfBisPlane);
return Standard_True;
}
// General case: try to find continuous section closest to bisector plane
TopoDS_Compound OldComp;
BRep_Builder B;
B.MakeCompound(OldComp);
TopoDS_Iterator iter(Comp);
for (; iter.More(); iter.Next())
B.Add(OldComp, iter.Value());
Standard_Boolean anError = Standard_False;
// TopoDS_Wire NewWire [2];
TopTools_SequenceOfShape Wseq;
for (;;)
{
TopExp_Explorer explo(OldComp, TopAbs_EDGE);
if (!explo.More())
break;
TopoDS_Edge FirstEdge = TopoDS::Edge(explo.Current());
TopoDS_Wire NewWire = BRepLib_MakeWire(FirstEdge);
B.Remove(OldComp, FirstEdge);
if (NewWire.Closed())
{
Wseq.Append(NewWire);
continue;
}
for (;;)
{
TopoDS_Vertex Extremity[2];
TopExp::Vertices(NewWire, Extremity[0], Extremity[1]);
if (Extremity[0].IsNull() || Extremity[1].IsNull())
{
anError = Standard_True;
break;
}
TopTools_IndexedDataMapOfShapeListOfShape VEmap;
TopExp::MapShapesAndAncestors(OldComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap);
TopTools_ListOfShape Vedges[2];
for (j = 0; j < 2; j++)
if (VEmap.Contains(Extremity[j]))
Vedges[j] = VEmap.FindFromKey(Extremity[j]);
if (Vedges[0].IsEmpty() && Vedges[1].IsEmpty())
// no more edges in OldComp to continue NewWire
break;
Standard_Boolean Modified = Standard_False;
for (j = 0; j < 2; j++)
{
if (Vedges[j].Extent() == 1)
{
const TopoDS_Edge& anEdge = TopoDS::Edge(Vedges[j].First());
NewWire = BRepLib_MakeWire(NewWire, anEdge);
B.Remove(OldComp, anEdge);
Modified = Standard_True;
}
}
if (!Modified) // only multiple connections
{
ind = (Vedges[0].IsEmpty()) ? 1 : 0;
TopTools_SequenceOfShape Edges;
TopTools_ListIteratorOfListOfShape itl(Vedges[ind]);
for (; itl.More(); itl.Next())
Edges.Append(itl.Value());
Standard_Integer theind = 0;
Standard_Real MinDeviation = RealLast();
for (j = 1; j <= Edges.Length(); j++)
{
TopoDS_Wire aWire = BRepLib_MakeWire(NewWire, TopoDS::Edge(Edges(j)));
gp_Pln aPlane;
Standard_Boolean issing;
Standard_Real Deviation = ComputeAveragePlaneAndMaxDeviation(aWire, aPlane, issing);
if (Deviation < MinDeviation)
{
MinDeviation = Deviation;
theind = j;
}
}
NewWire = BRepLib_MakeWire(NewWire, TopoDS::Edge(Edges(theind)));
B.Remove(OldComp, Edges(theind));
}
if (NewWire.Closed())
break;
}
Wseq.Append(NewWire);
if (anError)
break;
}
Standard_Real MinAngle = RealLast();
TopExp_Explorer Explo(OldComp, TopAbs_EDGE);
if (!anError && !Explo.More()) // wires are built successfully and compound <OldComp> is empty
{
if (Wseq.Length() == 1) // only one wire => it becomes result
{
resWire = Wseq.First();
ComputeAveragePlaneAndMaxDeviation(resWire, resPlane, IsSingular);
return Standard_True;
}
else // we must choose the wire which average plane is closest to bisector plane
{ //(check angle between axes)
for (i = 1; i <= Wseq.Length(); i++)
{
TopoDS_Wire aWire = TopoDS::Wire(Wseq(i));
gp_Pln aPln;
Standard_Boolean issing;
ComputeAveragePlaneAndMaxDeviation(aWire, aPln, issing);
if (issing)
continue;
Standard_Real Angle = aPln.Axis().Angle(myAxeOfBisPlane.Axis());
if (Angle > M_PI / 2)
Angle = M_PI - Angle;
if (Angle < MinAngle)
{
MinAngle = Angle;
resWire = aWire;
resPlane = aPln;
}
}
return Standard_True;
}
}
return Standard_False;
}
// ------------------------------------------------------------------------------------------
// static function: SplitUEdges
// purpose:
// ------------------------------------------------------------------------------------------
Standard_Boolean SplitUEdges(const Handle(TopTools_HArray2OfShape)& theUEdges,
const BOPDS_PDS& theDS,
const gp_Vec& theCrossDirection,
TopTools_DataMapOfShapeListOfShape& theHistMap)
{
const BOPDS_VectorOfInterfVV& aVVs = theDS->InterfVV();
BRep_Builder aBB;
Standard_Integer ueit = 0, upRow, lowCol, upCol;
TopTools_Array2OfShape aNewVertices(1, 2, 1, 2);
//
upRow = theUEdges->UpperRow();
lowCol = theUEdges->LowerCol();
upCol = theUEdges->UpperCol();
//
for (ueit = theUEdges->LowerRow(); ueit <= upRow; ueit++)
{
const TopoDS_Shape& aE1 = theUEdges->Value(ueit, lowCol);
const TopoDS_Shape& aE2 = theUEdges->Value(ueit, upCol);
if (theHistMap.IsBound(aE1) || theHistMap.IsBound(aE2))
continue;
Standard_Integer anEIndex1 = theDS->Index(aE1);
Standard_Integer anEIndex2 = theDS->Index(aE2);
TopoDS_Vertex aCommonVertex;
Standard_Real apar1 = 0., apar2 = 0.;
Standard_Boolean bvertexfound =
FindCommonVertex(theDS, anEIndex1, anEIndex2, theCrossDirection, aCommonVertex, apar1, apar2);
//
if (!bvertexfound)
{
TopoDS_Vertex V1 = TopExp::LastVertex(TopoDS::Edge(aE1));
TopoDS_Vertex V2 = TopExp::FirstVertex(TopoDS::Edge(aE2));
Standard_Integer vindex1 = theDS->Index(V1);
Standard_Integer vindex2 = theDS->Index(V2);
Standard_Integer vvit = 0;
Standard_Integer aNbVVs = aVVs.Length();
for (vvit = 0; !bvertexfound && (vvit < aNbVVs); vvit++)
{
// const BOPTools_VVInterference& aVV = aVVs(vvit);
const BOPDS_InterfVV& aVV = aVVs(vvit);
if (((vindex1 == aVV.Index1()) && (vindex2 == aVV.Index2()))
|| ((vindex1 == aVV.Index2()) && (vindex2 == aVV.Index1())))
{
if (!aVV.HasIndexNew())
{
continue;
}
aCommonVertex = TopoDS::Vertex(theDS->Shape(aVV.IndexNew()));
bvertexfound = Standard_True;
apar1 = BRep_Tool::Parameter(V1, TopoDS::Edge(aE1));
apar2 = BRep_Tool::Parameter(V2, TopoDS::Edge(aE2));
}
}
}
if (bvertexfound)
{
TopoDS_Vertex aV1, aV2;
Standard_Real f = 0., l = 0.;
//
TopoDS_Edge aNewE1 = TopoDS::Edge(aE1.EmptyCopied());
TopExp::Vertices(TopoDS::Edge(aE1), aV1, aV2);
aNewE1.Orientation(TopAbs_FORWARD);
aV1.Orientation(TopAbs_FORWARD);
aBB.Add(aNewE1, aV1);
aCommonVertex.Orientation(TopAbs_REVERSED);
aBB.Add(aNewE1, aCommonVertex);
BRep_Tool::Range(TopoDS::Edge(aE1), f, l);
aBB.Range(aNewE1, f, apar1);
//
TopoDS_Edge aNewE2 = TopoDS::Edge(aE2.EmptyCopied());
TopExp::Vertices(TopoDS::Edge(aE2), aV1, aV2);
aNewE2.Orientation(TopAbs_FORWARD);
aCommonVertex.Orientation(TopAbs_FORWARD);
aBB.Add(aNewE2, aCommonVertex);
aBB.Add(aNewE2, aV2);
BRep_Tool::Range(TopoDS::Edge(aE2), f, l);
aBB.Range(aNewE2, apar2, l);
TopTools_ListOfShape lst;
lst.Append(aNewE1);
theHistMap.Bind(aE1, lst);
lst.Clear();
lst.Append(aNewE2);
theHistMap.Bind(aE2, lst);
}
}
return Standard_True;
}
// ------------------------------------------------------------------------------------------
// static function: StoreVedgeInHistMap
// purpose:
// ------------------------------------------------------------------------------------------
void StoreVedgeInHistMap(const Handle(TopTools_HArray1OfShape)& theVEdges,
const Standard_Integer theIndex,
const TopoDS_Shape& theNewVshape,
TopTools_DataMapOfShapeListOfShape& theHistMap)
{
// Replace default value in the map (v-iso edge of face)
// by intersection of two consecutive faces
const TopoDS_Shape& aVEdge = theVEdges->Value(theIndex);
theHistMap.Bound(aVEdge, TopTools_ListOfShape())->Append(theNewVshape);
}
// ------------------------------------------------------------------------------------------
// static function: FindFreeVertices
// purpose:
// ------------------------------------------------------------------------------------------
void FindFreeVertices(const TopoDS_Shape& theShape,
const TopTools_MapOfShape& theVerticesToAvoid,
TopTools_ListOfShape& theListOfVertex)
{
theListOfVertex.Clear();
TopTools_IndexedDataMapOfShapeListOfShape aMap;
TopExp::MapShapesAndAncestors(theShape, TopAbs_VERTEX, TopAbs_EDGE, aMap);
Standard_Integer i = 0;
for (i = 1; i <= aMap.Extent(); i++)
{
const TopoDS_Shape& aKey = aMap.FindKey(i);
if (theVerticesToAvoid.Contains(aKey))
continue;
const TopTools_ListOfShape& aList = aMap.FindFromIndex(i);
if (aList.Extent() < 2)
{
theListOfVertex.Append(aKey);
}
}
}
// ------------------------------------------------------------------------------------------
// static function: FindCommonVertex
// purpose:
// ------------------------------------------------------------------------------------------
Standard_Boolean FindCommonVertex(const BOPDS_PDS& theDS,
const Standard_Integer theEIndex1,
const Standard_Integer theEIndex2,
const gp_Vec& theCrossDirection,
TopoDS_Vertex& theCommonVertex,
Standard_Real& theParamOnE1,
Standard_Real& theParamOnE2)
{
const BOPDS_VectorOfInterfEE& aEEs = theDS->InterfEE();
Standard_Boolean bvertexfound = Standard_False;
TopoDS_Vertex aCommonVertex;
Standard_Integer eeit = 0;
TopoDS_Edge theE1 = TopoDS::Edge(theDS->Shape(theEIndex1));
TopoDS_Edge theE2 = TopoDS::Edge(theDS->Shape(theEIndex2));
BRepAdaptor_Curve aBC1(theE1), aBC2(theE2);
Standard_Integer aNbEEs;
aNbEEs = aEEs.Length();
for (eeit = 0; eeit < aNbEEs; ++eeit)
{
const BOPDS_InterfEE& aEE = aEEs(eeit);
if ((theEIndex1 == aEE.Index1() && theEIndex2 == aEE.Index2())
|| (theEIndex1 == aEE.Index2() && theEIndex2 == aEE.Index1()))
{
if (!aEE.HasIndexNew())
continue;
IntTools_CommonPrt aCP = aEE.CommonPart();
if (aCP.Type() == TopAbs_VERTEX)
{
theCommonVertex = *(TopoDS_Vertex*)&theDS->Shape(aEE.IndexNew());
if (theEIndex1 == aEE.Index1())
IntTools_Tools::VertexParameters(aCP, theParamOnE1, theParamOnE2);
else
IntTools_Tools::VertexParameters(aCP, theParamOnE2, theParamOnE1);
gp_Pnt aPt;
gp_Vec aDirOnE1, aDirOnE2;
gp_Dir aIntersectPointCrossDir;
// intersect point aDirOnE1.cross(aDirOnE2) should same direction with path
// theCrossDirection
aBC1.D1(theParamOnE1, aPt, aDirOnE1);
aBC2.D1(theParamOnE2, aPt, aDirOnE2);
aIntersectPointCrossDir = aDirOnE1.Crossed(aDirOnE2);
if (aIntersectPointCrossDir.Dot(theCrossDirection) > Precision::SquareConfusion())
{
bvertexfound = Standard_True;
break;
}
}
}
}
return bvertexfound;
}
// ----------------------------------------------------------------------------------------------------
// static function: GetUEdges
// purpose:
// ----------------------------------------------------------------------------------------------------
Standard_Boolean GetUEdges(const Standard_Integer theIndex,
const Standard_Integer theRank,
const Handle(TopTools_HArray2OfShape)& theUEdges,
const TopoDS_Edge& theBoundEdge,
const TopoDS_Face& theFace,
TopoDS_Edge& theFirstUEdge,
TopoDS_Edge& theSecondUEdge)
{
const TopoDS_Shape& aUE1 = theUEdges->Value(theIndex, theUEdges->LowerCol() + theRank);
const TopoDS_Shape& aUE2 = theUEdges->Value(theIndex + 1, theUEdges->LowerCol() + theRank);
TopoDS_Face aFace = theFace;
aFace.Orientation(TopAbs_FORWARD);
TopoDS_Edge E1, E2;
TopExp_Explorer anExp(aFace, TopAbs_EDGE);
for (; anExp.More(); anExp.Next())
{
if (E1.IsNull() && aUE1.IsSame(anExp.Current()))
{
E1 = TopoDS::Edge(anExp.Current());
}
else if (E2.IsNull() && aUE2.IsSame(anExp.Current()))
{
E2 = TopoDS::Edge(anExp.Current());
}
}
if (E1.IsNull() || E2.IsNull())
return Standard_False;
Standard_Real f, l;
Handle(Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E1, aFace, f, l);
if (C1.IsNull())
return Standard_False;
gp_Pnt2d PU1 = (theRank == 0) ? C1->Value(l) : C1->Value(f);
Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(theBoundEdge, aFace, f, l);
if (C2.IsNull())
return Standard_False;
BRep_Tool::Range(theBoundEdge, f, l);
gp_Pnt2d pf = C2->Value(f);
TopoDS_Vertex aV = (theRank == 0) ? TopExp::LastVertex(E1) : TopExp::FirstVertex(E1);
Standard_Real aTolerance = BRep_Tool::Tolerance(aV);
BRepAdaptor_Surface aBAS(aFace, Standard_False);
if (pf.Distance(PU1) > aBAS.UResolution(aTolerance))
{
TopoDS_Edge atmpE = E1;
E1 = E2;
E2 = atmpE;
}
theFirstUEdge = E1;
theSecondUEdge = E2;
return Standard_True;
}
// ----------------------------------------------------------------------------------------------------
// static function: FillGap
// purpose:
// ----------------------------------------------------------------------------------------------------
Standard_Boolean FillGap(const TopoDS_Vertex& theFirstVertex,
const TopoDS_Vertex& theLastVertex,
const gp_Pnt2d& theFirstPoint,
const gp_Pnt2d& theLastPoint,
const TopoDS_Face& theFace,
const TopoDS_Compound& theSectionEdges,
TopTools_ListOfShape& theOrderedList)
{
TopTools_IndexedDataMapOfShapeListOfShape aMap;
TopExp::MapShapesAndAncestors(theSectionEdges, TopAbs_VERTEX, TopAbs_EDGE, aMap);
if (aMap.IsEmpty())
{
return Standard_False;
}
if (!aMap.Contains(theFirstVertex) || !aMap.Contains(theLastVertex))
{
return Standard_False;
}
TopTools_ListOfShape aListOfEdge;
// Standard_Integer i = 0;
// TopoDS_Vertex aCurVertex = theFirstVertex;
TopTools_MapOfShape aMapToAvoid;
if (FindNextEdge(theFirstVertex, theLastVertex, aMap, aMapToAvoid, aListOfEdge))
{
if (!aListOfEdge.IsEmpty())
{
return CheckAndOrientEdges(aListOfEdge, theFirstPoint, theLastPoint, theFace, theOrderedList);
}
}
return Standard_False;
}
// ----------------------------------------------------------------------------------------------------
// static function: FindNextEdge
// purpose:
// ----------------------------------------------------------------------------------------------------
Standard_Boolean FindNextEdge(const TopoDS_Vertex& theFirstVertex,
const TopoDS_Vertex& theLastVertex,
const TopTools_IndexedDataMapOfShapeListOfShape& theMapVE,
const TopTools_MapOfShape& theMapToAvoid,
TopTools_ListOfShape& theOrderedList)
{
TopoDS_Vertex aCurVertex = theFirstVertex;
TopTools_MapOfShape aMapToAvoid;
aMapToAvoid = theMapToAvoid;
TopTools_ListOfShape aListOfEdge;
Standard_Integer i = 0;
for (i = 1; i <= theMapVE.Extent(); i++)
{
if (!theMapVE.Contains(aCurVertex))
break;
const TopTools_ListOfShape& lste = theMapVE.FindFromKey(aCurVertex);
Standard_Boolean befound = Standard_False;
TopTools_ListIteratorOfListOfShape anIt(lste);
for (; anIt.More(); anIt.Next())
{
TopoDS_Shape anEdge = anIt.Value();
TopoDS_Vertex aSaveCurVertex = aCurVertex;
if (!aMapToAvoid.Contains(anEdge))
{
TopoDS_Vertex V1, V2;
TopExp::Vertices(TopoDS::Edge(anEdge), V1, V2);
if (!aCurVertex.IsSame(V1))
{
aCurVertex = V1;
}
else if (!aCurVertex.IsSame(V2))
{
aCurVertex = V2;
}
aMapToAvoid.Add(anEdge);
befound = Standard_True;
aListOfEdge.Append(anEdge);
if (!aCurVertex.IsSame(theLastVertex))
{
TopTools_ListOfShape aListtmp;
if (!FindNextEdge(aCurVertex, theLastVertex, theMapVE, aMapToAvoid, aListtmp))
{
aListOfEdge.Clear();
aCurVertex = aSaveCurVertex;
continue;
}
else
{
aListOfEdge.Append(aListtmp);
theOrderedList.Append(aListOfEdge);
return Standard_True;
}
}
break;
}
}
if (aCurVertex.IsSame(theLastVertex))
break;
if (!befound)
{
return Standard_False;
}
}
if (aCurVertex.IsSame(theLastVertex))
{
theOrderedList.Append(aListOfEdge);
return Standard_True;
}
return Standard_False;
}
// ----------------------------------------------------------------------------------------------------
// static function: CheckAndOrientEdges
// purpose:
// ----------------------------------------------------------------------------------------------------
Standard_Boolean CheckAndOrientEdges(const TopTools_ListOfShape& theOrderedList,
const gp_Pnt2d& theFirstPoint,
const gp_Pnt2d& theLastPoint,
const TopoDS_Face& theFace,
TopTools_ListOfShape& theOrientedList)
{
TopTools_ListIteratorOfListOfShape anIt(theOrderedList);
if (!anIt.More())
return Standard_True;
Standard_Real f, l;
TopoDS_Edge aEPrev = TopoDS::Edge(anIt.Value());
anIt.Next();
Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(aEPrev, theFace, f, l);
TopoDS_Vertex Vf, Vl;
TopExp::Vertices(aEPrev, Vf, Vl);
BRepAdaptor_Surface aBAS(theFace, Standard_False);
Standard_Real aTolerance1 = (Vf.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(Vf);
Standard_Real aTolerance2 = (Vl.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(Vl);
Standard_Real utol = aBAS.UResolution(aTolerance1);
Standard_Real vtol = aBAS.VResolution(aTolerance1);
aTolerance1 = (utol > vtol) ? utol : vtol;
utol = aBAS.UResolution(aTolerance2);
vtol = aBAS.VResolution(aTolerance2);
aTolerance2 = (utol > vtol) ? utol : vtol;
gp_Pnt2d ap = aCurve->Value(f);
Standard_Boolean bFirstFound = Standard_False;
Standard_Boolean bLastFound = Standard_False;
if (ap.Distance(theFirstPoint) < aTolerance1)
{
if (theOrientedList.IsEmpty())
theOrientedList.Append(aEPrev.Oriented(TopAbs_FORWARD));
bFirstFound = Standard_True;
}
else if (ap.Distance(theLastPoint) < aTolerance1)
{
if (theOrientedList.IsEmpty())
theOrientedList.Append(aEPrev.Oriented(TopAbs_REVERSED));
bLastFound = Standard_True;
}
ap = aCurve->Value(l);
if (ap.Distance(theLastPoint) < aTolerance2)
{
if (theOrientedList.IsEmpty())
theOrientedList.Append(aEPrev.Oriented(TopAbs_FORWARD));
bLastFound = Standard_True;
}
else if (ap.Distance(theFirstPoint) < aTolerance2)
{
if (theOrientedList.IsEmpty())
theOrientedList.Append(aEPrev.Oriented(TopAbs_REVERSED));
bFirstFound = Standard_True;
}
if (!theOrientedList.IsEmpty())
aEPrev = TopoDS::Edge(theOrientedList.Last());
for (; anIt.More(); anIt.Next())
{
const TopoDS_Edge& aE = TopoDS::Edge(anIt.Value());
TopoDS_Vertex aV11, aV12;
TopExp::Vertices(aEPrev, aV11, aV12, Standard_True);
TopoDS_Vertex aV21, aV22;
TopExp::Vertices(aE, aV21, aV22, Standard_False);
TopAbs_Orientation anOri =
(aV12.IsSame(aV21) || aV11.IsSame(aV22)) ? TopAbs_FORWARD : TopAbs_REVERSED;
theOrientedList.Append(aE.Oriented(anOri));
aEPrev = TopoDS::Edge(theOrientedList.Last());
aTolerance1 = (aV21.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(aV21);
aTolerance2 = (aV22.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(aV22);
utol = aBAS.UResolution(aTolerance1);
vtol = aBAS.VResolution(aTolerance1);
aTolerance1 = (utol > vtol) ? utol : vtol;
utol = aBAS.UResolution(aTolerance2);
vtol = aBAS.VResolution(aTolerance2);
aTolerance2 = (utol > vtol) ? utol : vtol;
aCurve = BRep_Tool::CurveOnSurface(aE, theFace, f, l);
ap = aCurve->Value(f);
if (ap.Distance(theFirstPoint) < aTolerance1)
{
bFirstFound = Standard_True;
}
else if (ap.Distance(theLastPoint) < aTolerance1)
{
bLastFound = Standard_True;
}
ap = aCurve->Value(l);
if (ap.Distance(theFirstPoint) < aTolerance2)
{
bFirstFound = Standard_True;
}
else if (ap.Distance(theLastPoint) < aTolerance2)
{
bLastFound = Standard_True;
}
}
return bFirstFound && bLastFound;
}
// ----------------------------------------------------------------------------------------------------
// static function: FindVertex
// purpose:
// ----------------------------------------------------------------------------------------------------
Standard_Boolean FindVertex(const TopoDS_Edge& theEdge,
const Standard_Integer theRank,
const BOPDS_PDS& theDS,
const TopTools_DataMapOfShapeListOfShape& theHistMap,
TopoDS_Vertex& theVertex,
BOPDS_Pave& thePave)
{
if (!theHistMap.IsBound(theEdge))
return Standard_False;
const TopTools_ListOfShape& lst = theHistMap.Find(theEdge);
if (lst.IsEmpty())
return Standard_False;
TopoDS_Edge aNewEdge = TopoDS::Edge(lst.First());
Standard_Real f, l;
BRep_Tool::Range(aNewEdge, f, l);
if (theRank == 0)
{
thePave.SetParameter(l);
theVertex = TopExp::LastVertex(aNewEdge);
}
else
{
thePave.SetParameter(f);
theVertex = TopExp::FirstVertex(aNewEdge);
}
Standard_Integer anIndex = theDS->Index(theVertex);
if (anIndex == -1)
{
Standard_Integer i, i1, i2;
i1 = theDS->NbSourceShapes();
i2 = theDS->NbShapes();
for (i = i1; i < i2; ++i)
{
const TopoDS_Shape& aSx = theDS->Shape(i);
if (aSx.IsSame(theVertex))
{
anIndex = i;
break;
}
}
}
thePave.SetIndex(anIndex);
return Standard_True;
}
// ----------------------------------------------------------------------------------------------------
// static function: FindNextVertex
// purpose:
// ----------------------------------------------------------------------------------------------------
Standard_Boolean FindNextVertex(const Standard_Integer theEdgeIndex,
const BOPDS_Pave& thePrevPave,
const BOPDS_PDS& theDS,
TopoDS_Vertex& theNextVertex,
BOPDS_Pave& thePave)
{
Standard_Boolean bTakePave, bFound;
BOPDS_Pave aTmpPave;
BOPDS_ListIteratorOfListOfPave aItP;
//
BOPDS_Pave anullpave;
bFound = Standard_False;
bTakePave = thePrevPave.IsEqual(anullpave);
BOPDS_ListOfPave aLP;
theDS->Paves(theEdgeIndex, aLP);
aItP.Initialize(aLP);
for (; aItP.More(); aItP.Next())
{
aTmpPave = aItP.Value();
//
if (bTakePave)
{
if (theDS->IsNewShape(aTmpPave.Index()))
{
theNextVertex = *(TopoDS_Vertex*)&theDS->Shape(aTmpPave.Index());
thePave = aTmpPave;
bFound = Standard_True;
break;
}
}
//
else if (aTmpPave.IsEqual(thePrevPave))
{
bTakePave = Standard_True;
}
}
return bFound;
}
// ----------------------------------------------------------------------------------------------------
// static function: GetPave
// purpose:
// ----------------------------------------------------------------------------------------------------
Standard_Boolean GetPave(const Standard_Integer theEdgeIndex,
const Standard_Boolean isFirst,
const BOPDS_PDS& theDS,
BOPDS_Pave& thePave)
{
Handle(BOPDS_PaveBlock) aPB;
BOPDS_ListOfPave aLP;
theDS->Paves(theEdgeIndex, aLP);
if (!aLP.Extent())
{
return Standard_False;
}
//
if (isFirst)
{
thePave = aLP.First();
}
else
{
thePave = aLP.Last();
}
return Standard_True;
}
// ----------------------------------------------------------------------------------------------------
// static function: FindFromUEdge
// purpose:
// ----------------------------------------------------------------------------------------------------
Standard_Boolean FindFromUEdge(const TopoDS_Edge& theUE1Old,
const TopoDS_Edge& theUE2Old,
const TopoDS_Edge& theUE1New,
const TopoDS_Edge& theUE2New,
const TopoDS_Face& theFace,
const TopoDS_Compound& theSecEdges,
const Standard_Integer theRank,
const TopoDS_Edge& theBoundEdge,
const Standard_Integer theBoundEdgeIndex,
const BOPDS_PDS& theDS,
const TopTools_DataMapOfShapeListOfShape& theHistMap,
TopoDS_Compound& theSecEdgesNew,
TopTools_ListOfShape& theListOfWireEdges,
BOPDS_Pave& theFoundPave,
Standard_Boolean& isOnUEdge)
{
theFoundPave.SetIndex(0);
theFoundPave.SetParameter(0.);
isOnUEdge = Standard_True;
TopoDS_Face aFaceF = theFace;
aFaceF.Orientation(TopAbs_FORWARD);
TopoDS_Vertex aPrevVertex, aNextVertex;
TopoDS_Compound aCompOfSecEdges = theSecEdges;
TopTools_ListOfShape aListOfWireEdges;
// BRep_Builder aBB;
BOPDS_Pave aPave1, aPave2;
Standard_Real f = 0., l = 0.;
gp_Pnt2d p1, p2;
TopoDS_Vertex aFirstV, aLastV;
BOPDS_Pave atmpPave;
if (!FindVertex(theUE1Old, theRank, theDS, theHistMap, aPrevVertex, atmpPave))
{
return Standard_True;
}
if (aPrevVertex.IsNull())
{
return Standard_False;
}
aFirstV = aPrevVertex;
Standard_Boolean bSecFound = Standard_False;
Handle(Geom2d_Curve) aC1 = BRep_Tool::CurveOnSurface(theUE1New, aFaceF, f, l);
p1 = (theRank == 0) ? aC1->Value(l) : aC1->Value(f);
BOPDS_Pave afoundpave;
BOPDS_ListOfPave aLP;
theDS->Paves(theBoundEdgeIndex, aLP);
Standard_Integer nbpave = aLP.Extent();
Standard_Integer pit = 0;
while (FindNextVertex(theBoundEdgeIndex, aPave1, theDS, aNextVertex, aPave2) && (pit < nbpave))
{
aLastV = aNextVertex;
Handle(Geom2d_Curve) aC2 = BRep_Tool::CurveOnSurface(theBoundEdge, aFaceF, f, l);
p2 = aC2->Value(aPave2.Parameter());
TopTools_ListOfShape aOrderedList;
if (FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList))
{
// remove found edges...
TopoDS_Compound aComp;
RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
aCompOfSecEdges = aComp;
aListOfWireEdges.Append(aOrderedList);
afoundpave = aPave2;
isOnUEdge = Standard_False;
bSecFound = Standard_True;
break;
}
aPrevVertex = aNextVertex;
aPave1 = aPave2;
pit++;
}
if (!bSecFound && FindVertex(theUE2Old, theRank, theDS, theHistMap, aNextVertex, aPave2))
{
aLastV = aNextVertex;
Handle(Geom2d_Curve) aC2 = BRep_Tool::CurveOnSurface(theUE2New, aFaceF, f, l);
p2 = aC2->Value(aPave2.Parameter());
TopTools_ListOfShape aOrderedList;
if (FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList))
{
// remove found edges...
TopoDS_Compound aComp;
RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
aCompOfSecEdges = aComp;
aListOfWireEdges.Append(aOrderedList);
afoundpave = aPave2;
bSecFound = Standard_True;
isOnUEdge = Standard_True;
}
}
if (bSecFound)
{
theFoundPave = afoundpave;
theListOfWireEdges = aListOfWireEdges;
theSecEdgesNew = aCompOfSecEdges;
}
return Standard_True;
}
// ----------------------------------------------------------------------------------------------------
// static function: FindFromVEdge
// purpose:
// ----------------------------------------------------------------------------------------------------
Standard_Boolean FindFromVEdge(const BOPDS_Pave& thePrevPave,
const Standard_Boolean& isOnUEdge,
const TopoDS_Edge& theUE1Old,
const TopoDS_Edge& theUE2Old,
const TopoDS_Face& theFace,
const TopoDS_Compound& theSecEdges,
const Standard_Integer theRank,
const TopoDS_Edge& theBoundEdge,
const Standard_Integer theBoundEdgeIndex,
const BOPDS_PDS& theDS,
const TopTools_DataMapOfShapeListOfShape& theHistMap,
TopTools_ListOfShape& theListOfWireEdges,
Standard_Boolean& isSectionFound)
{
theListOfWireEdges.Clear();
isSectionFound = Standard_False;
//
TopoDS_Face aFaceF = theFace;
aFaceF.Orientation(TopAbs_FORWARD);
TopoDS_Vertex aPrevVertex, aNextVertex;
TopoDS_Compound aCompOfSecEdges = theSecEdges;
TopTools_ListOfShape aListOfWireEdges;
// BRep_Builder aBB;
BOPDS_Pave aPave1, aPave2;
if (isOnUEdge)
{
TopoDS_Vertex atmpVertex;
BOPDS_Pave aPaveOfE2;
if (FindVertex(theUE2Old, theRank, theDS, theHistMap, atmpVertex, aPaveOfE2))
{
if (thePrevPave.IsEqual(aPaveOfE2))
return Standard_True;
}
}
Standard_Real f = 0., l = 0.;
gp_Pnt2d p1(0., 0.), p2(0., 0.);
TopoDS_Vertex aFirstV, aLastV;
Handle(Geom2d_Curve) aC1 = BRep_Tool::CurveOnSurface(theUE1Old, aFaceF, f, l);
Handle(Geom2d_Curve) aC2 = BRep_Tool::CurveOnSurface(theBoundEdge, aFaceF, f, l);
Standard_Boolean bSecFound = Standard_False;
aPave1 = thePrevPave;
if (isOnUEdge)
{
BOPDS_Pave atmpPave;
if (!GetPave(theBoundEdgeIndex, Standard_True, theDS, atmpPave))
{
return Standard_False;
}
aPave1 = atmpPave;
}
p1 = aC2->Value(aPave1.Parameter());
aPrevVertex = TopoDS::Vertex(theDS->Shape(aPave1.Index()));
BOPDS_ListOfPave aLP;
theDS->Paves(theBoundEdgeIndex, aLP);
Standard_Integer nbpave = aLP.Extent();
Standard_Integer pit = 0;
TopTools_Array1OfListOfShape anArrayOfListOfSec(1, nbpave);
// by pairs non continuously. begin
Standard_Integer k = 0;
BOPDS_Pave aFirstPave = aPave1;
TopoDS_Vertex aFirstVertex = aPrevVertex;
gp_Pnt2d apfirst = p1;
BOPDS_ListOfPave aFirstPaves, aLastPaves;
TColStd_ListOfInteger aListOfFlags;
Standard_Integer apaircounter = 1;
for (k = 0; k < nbpave; k++)
{
aPave1 = aFirstPave;
p1 = apfirst;
aPrevVertex = aFirstVertex;
Standard_Boolean bfound = Standard_False;
pit = 0;
while (FindNextVertex(theBoundEdgeIndex, aPave1, theDS, aNextVertex, aPave2) && (pit < nbpave))
{
aFirstV = aPrevVertex;
aLastV = aNextVertex;
p2 = aC2->Value(aPave2.Parameter());
TopTools_ListOfShape aOrderedList;
if (FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList))
{
TopoDS_Compound aComp;
RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
aCompOfSecEdges = aComp;
anArrayOfListOfSec(apaircounter++).Append(aOrderedList);
aFirstPaves.Append(aFirstPave);
aLastPaves.Append(aPave2);
aListOfFlags.Append(1);
aFirstPave = aPave2;
aFirstVertex = aNextVertex;
apfirst = p2;
aPrevVertex = aNextVertex;
bSecFound = Standard_True;
bfound = Standard_True;
}
aPave1 = aPave2;
pit++;
}
if (FindVertex(theUE2Old, theRank, theDS, theHistMap, aNextVertex, aPave2))
{
aFirstV = aPrevVertex;
aLastV = aNextVertex;
Handle(Geom2d_Curve) aC3 = BRep_Tool::CurveOnSurface(theUE2Old, aFaceF, f, l);
p2 = aC3->Value(aPave2.Parameter());
TopTools_ListOfShape aOrderedList;
if (FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList))
{
TopoDS_Compound aComp;
RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
aCompOfSecEdges = aComp;
anArrayOfListOfSec(apaircounter++).Append(aOrderedList);
aFirstPaves.Append(aFirstPave);
aLastPaves.Append(aPave2);
aListOfFlags.Append(0);
bSecFound = Standard_True;
break;
}
}
if (!bfound)
{
if (!FindNextVertex(theBoundEdgeIndex, aFirstPave, theDS, aNextVertex, aPave2))
{
break;
}
aFirstPave = aPave2;
apfirst = aC2->Value(aPave2.Parameter());
aFirstVertex = aNextVertex;
}
}
// by pairs non continuously. end
// by pairs continuously. begin
aPave1 = thePrevPave;
if (isOnUEdge)
{
BOPDS_Pave atmpPave;
if (!GetPave(theBoundEdgeIndex, Standard_True, theDS, atmpPave))
{
return Standard_False;
}
aPave1 = atmpPave;
}
p1 = aC2->Value(aPave1.Parameter());
aPrevVertex = TopoDS::Vertex(theDS->Shape(aPave1.Index()));
pit = 0;
while (FindNextVertex(theBoundEdgeIndex, aPave1, theDS, aNextVertex, aPave2) && (pit < nbpave))
{
aFirstV = aPrevVertex;
aLastV = aNextVertex;
p2 = aC2->Value(aPave2.Parameter());
Standard_Boolean bisinside = Standard_False;
Standard_Integer apbindex = 0;
Standard_Integer apbcounter = 1;
BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
BOPDS_ListIteratorOfListOfPave aPIt1, aPIt2;
TColStd_ListIteratorOfListOfInteger aFlagIt;
for (aPIt1.Initialize(aFirstPaves),
aPIt2.Initialize(aLastPaves),
aFlagIt.Initialize(aListOfFlags);
aPIt1.More() && aPIt2.More() && aFlagIt.More();
aPIt1.Next(), aPIt2.Next(), aFlagIt.Next(), apbcounter++)
{
Standard_Boolean bfin = Standard_False;
Standard_Boolean blin = Standard_False;
if (aPave1.IsEqual(aPIt1.Value()))
{
bfin = Standard_True;
}
else
{
bfin = (aPave1.Parameter() > aPIt1.Value().Parameter());
}
if (aFlagIt.Value())
{
if (aPave2.IsEqual(aPIt2.Value()))
{
blin = Standard_True;
}
else
{
blin = (aPave2.Parameter() < aPIt2.Value().Parameter());
}
}
else
{
if ((aPave2.Index() == aPIt2.Value().Index()) && (aPave2.Index() > 0))
{
Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface(theUE2Old, aFaceF, f, l);
gp_Pnt2d p3 = pc->Value(aPIt2.Value().Parameter());
TopoDS_Vertex aV = TopoDS::Vertex(theDS->Shape(aPave2.Index()));
BRepAdaptor_Surface aBAS(aFaceF, Standard_False);
Standard_Real aTolerance = BRep_Tool::Tolerance(aV);
Standard_Real utol = aBAS.UResolution(aTolerance);
Standard_Real vtol = aBAS.VResolution(aTolerance);
aTolerance = (utol > vtol) ? utol : vtol;
if (p2.Distance(p3) < aTolerance)
blin = Standard_True;
}
}
if (bfin && blin)
{
apbindex = apbcounter;
bisinside = Standard_True;
break;
}
}
if (!bisinside)
{
TopTools_ListOfShape aOrderedList;
if (FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList))
{
TopoDS_Compound aComp;
RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
aCompOfSecEdges = aComp;
aListOfWireEdges.Append(aOrderedList);
bSecFound = Standard_True;
}
else
{
TopoDS_Edge aESplit;
// get split
aPBIt.Initialize(theDS->PaveBlocks(theBoundEdgeIndex));
for (; aPBIt.More(); aPBIt.Next())
{
const Handle(BOPDS_PaveBlock)& aPB1 = aPBIt.Value();
if (aPB1->OriginalEdge() == theBoundEdgeIndex && aPB1->Pave1().IsEqual(aPave1)
&& aPB1->Pave2().IsEqual(aPave2))
{
if (aPB1->Edge() > 0)
{
aESplit = *(TopoDS_Edge*)&theDS->Shape(aPB1->Edge());
break;
}
}
}
if (!aESplit.IsNull())
{
aListOfWireEdges.Append(aESplit);
}
}
}
else
{
if (apbindex > 0)
{
TopTools_ListOfShape& aListOfSec = anArrayOfListOfSec(apbindex);
aListOfWireEdges.Append(aListOfSec);
}
}
aPave1 = aPave2;
aPrevVertex = aNextVertex;
p1 = p2;
pit++;
}
if (FindVertex(theUE2Old, theRank, theDS, theHistMap, aNextVertex, aPave2))
{
aFirstV = aPrevVertex;
aLastV = aNextVertex;
Handle(Geom2d_Curve) aC3 = BRep_Tool::CurveOnSurface(theUE2Old, aFaceF, f, l);
p2 = aC3->Value(aPave2.Parameter());
Standard_Boolean bisinside = Standard_False;
Standard_Integer apbindex = 0;
Standard_Integer apbcounter = 1;
BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
BOPDS_ListIteratorOfListOfPave aPIt1, aPIt2;
TColStd_ListIteratorOfListOfInteger aFlagIt;
for (aPIt1.Initialize(aFirstPaves),
aPIt2.Initialize(aLastPaves),
aFlagIt.Initialize(aListOfFlags);
aPIt1.More() && aPIt2.More() && aFlagIt.More();
aPIt1.Next(), aPIt2.Next(), aFlagIt.Next(), apbcounter++)
{
Standard_Boolean bfin = Standard_False;
Standard_Boolean blin = Standard_False;
if (aPave1.IsEqual(aPIt1.Value()))
{
bfin = Standard_True;
}
else
{
bfin = (aPave1.Parameter() > aPIt1.Value().Parameter());
}
if (aFlagIt.Value())
{
if (aPave2.IsEqual(aPIt2.Value()))
{
blin = Standard_True;
}
else
{
blin = (aPave2.Parameter() < aPIt2.Value().Parameter());
}
}
else
{
blin = Standard_True;
}
if (bfin && blin)
{
apbindex = apbcounter;
bisinside = Standard_True;
break;
}
}
if (!bisinside)
{
TopTools_ListOfShape aOrderedList;
if (FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList))
{
TopoDS_Compound aComp;
RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
aCompOfSecEdges = aComp;
aListOfWireEdges.Append(aOrderedList);
bSecFound = Standard_True;
}
else
{
// add split
TopoDS_Edge aESplit;
// get split
if (!GetPave(theBoundEdgeIndex, Standard_False, theDS, aPave2))
return Standard_False;
//
aPBIt.Initialize(theDS->PaveBlocks(theBoundEdgeIndex));
for (; aPBIt.More(); aPBIt.Next())
{
const Handle(BOPDS_PaveBlock)& aPB1 = aPBIt.Value();
if (aPB1->OriginalEdge() == theBoundEdgeIndex && aPB1->Pave1().IsEqual(aPave1)
&& aPB1->Pave2().IsEqual(aPave2))
{
if (aPB1->Edge() > 0)
{
aESplit = *(TopoDS_Edge*)&theDS->Shape(aPB1->Edge());
break;
}
}
}
if (!aESplit.IsNull())
{
aListOfWireEdges.Append(aESplit);
}
}
}
else
{
if (apbindex > 0)
{
TopTools_ListOfShape& aListOfSec = anArrayOfListOfSec(apbindex);
aListOfWireEdges.Append(aListOfSec);
}
}
}
else
{
// add split
TopoDS_Edge aESplit;
// get split
if (!GetPave(theBoundEdgeIndex, Standard_False, theDS, aPave2))
return Standard_False;
BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
aPBIt.Initialize(theDS->PaveBlocks(theBoundEdgeIndex));
for (; aPBIt.More(); aPBIt.Next())
{
const Handle(BOPDS_PaveBlock)& aPB1 = aPBIt.Value();
if (aPB1->OriginalEdge() == theBoundEdgeIndex && aPB1->Pave1().IsEqual(aPave1)
&& aPB1->Pave2().IsEqual(aPave2))
{
if (aPB1->Edge() > 0)
{
aESplit = *(TopoDS_Edge*)&theDS->Shape(aPB1->Edge());
break;
}
}
}
if (!aESplit.IsNull())
{
aListOfWireEdges.Append(aESplit);
}
}
// by pairs continuously. end
theListOfWireEdges = aListOfWireEdges;
isSectionFound = bSecFound;
return Standard_True;
}
// ----------------------------------------------------------------------------------------------------
// static function: RemoveEdges
// purpose:
// ----------------------------------------------------------------------------------------------------
void RemoveEdges(const TopoDS_Compound& theSourceComp,
const TopTools_ListOfShape& theListToRemove,
TopoDS_Compound& theResultComp)
{
BRep_Builder aBB;
TopoDS_Compound aComp;
aBB.MakeCompound(aComp);
TopExp_Explorer anExp(theSourceComp, TopAbs_EDGE);
for (; anExp.More(); anExp.Next())
{
Standard_Boolean bfound = Standard_False;
TopTools_ListIteratorOfListOfShape anIt(theListToRemove);
for (; !bfound && anIt.More(); anIt.Next())
{
bfound = anExp.Current().IsSame(anIt.Value());
}
if (!bfound)
{
aBB.Add(aComp, anExp.Current());
}
}
theResultComp = aComp;
}
// ----------------------------------------------------------------------------------------------------
// static function: FilterSectionEdges
// purpose:
// ----------------------------------------------------------------------------------------------------
Standard_Boolean FilterSectionEdges(const BOPDS_VectorOfCurve& theBCurves,
const TopoDS_Face& theSecPlane,
const BOPDS_PDS& theDS,
TopoDS_Compound& theResult)
{
theResult.Nullify();
BRep_Builder aBB;
aBB.MakeCompound(theResult);
Standard_Integer aNbCurves = theBCurves.Length();
Standard_Integer cit = 0;
BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
for (cit = 0; cit < aNbCurves; ++cit)
{
const BOPDS_Curve& aBCurve = theBCurves(cit);
const BOPDS_ListOfPaveBlock& aSectEdges = aBCurve.PaveBlocks();
aPBIt.Initialize(aSectEdges);
for (; aPBIt.More(); aPBIt.Next())
{
const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
Standard_Integer nSect = aPB->Edge();
const TopoDS_Shape& aS = theDS->Shape(nSect);
TopoDS_Edge anEdge = TopoDS::Edge(aS);
Standard_Boolean bAddEdge = Standard_True;
if (!theSecPlane.IsNull())
{
IntTools_BeanFaceIntersector anIntersector(anEdge, theSecPlane);
Standard_Real f = 0., l = 0.;
BRep_Tool::Range(anEdge, f, l);
anIntersector.SetBeanParameters(f, l);
//
Handle(IntTools_Context) aContext = new IntTools_Context;
anIntersector.SetContext(aContext);
//
anIntersector.Perform();
if (anIntersector.IsDone())
{
bAddEdge = Standard_False;
Standard_Integer r = 0;
for (r = 1; r <= anIntersector.Result().Length(); r++)
{
const IntTools_Range& aRange = anIntersector.Result().Value(r);
if (((aRange.First() - f) < Precision::PConfusion())
&& ((l - aRange.Last()) < Precision::PConfusion()))
{
bAddEdge = Standard_True;
break;
} // if(((aRange.First() - f) < Precision::PConfusion()) &&
} // for(r = 1; r <= anIntersector.Result().Length(); r++) {
} // if(anIntersector.IsDone()) {
} // if(!theSecPlane.IsNull()) {
if (bAddEdge)
{
aBB.Add(theResult, aS);
}
} // for (; aPBIt.More(); aPBIt.Next()) {
} // for(cit = 0; cit < aNbCurves; ++cit) {
return Standard_True;
}
//=================================================================================================
static Standard_Real ComputeAveragePlaneAndMaxDeviation(const TopoDS_Shape& aWire,
gp_Pln& thePlane,
Standard_Boolean& IsSingular)
{
Standard_Integer N = 40;
Standard_Integer nedges = aWire.NbChildren();
TColgp_Array1OfPnt Pnts(1, nedges * N);
Standard_Integer ind = 1, i;
for (TopoDS_Iterator iter(aWire); iter.More(); iter.Next())
{
const TopoDS_Edge& anEdge = TopoDS::Edge(iter.Value());
BRepAdaptor_Curve aCurve(anEdge);
GCPnts_UniformAbscissa Distribution(aCurve, N + 1);
for (i = 1; i <= N; i++)
{
Standard_Real par = Distribution.Parameter(i);
Pnts(ind++) = aCurve.Value(par);
}
}
gp_Ax2 Axe;
GeomLib::AxeOfInertia(Pnts, Axe, IsSingular);
if (IsSingular)
return -1;
thePlane = gp_Pln(Axe);
Standard_Real MaxDeviation = 0;
for (i = 1; i <= Pnts.Length(); i++)
{
Standard_Real dist = thePlane.Distance(Pnts(i));
if (dist > MaxDeviation)
MaxDeviation = dist;
}
return MaxDeviation;
}
static void UpdateSectionEdge(TopoDS_Edge& theEdge,
const TopoDS_Vertex& theConstVertex,
TopoDS_Vertex& theVertex,
const Standard_Real theParam)
{
TopoDS_Edge F_Edge = theEdge;
F_Edge.Orientation(TopAbs_FORWARD);
TopAbs_Orientation OrOfVertex;
TopoDS_Vertex V1, V2, AnotherVertex;
TopExp::Vertices(F_Edge, V1, V2);
if (theConstVertex.IsSame(V1))
{
// OrOfConst = TopAbs_FORWARD;
OrOfVertex = TopAbs_REVERSED;
AnotherVertex = V2;
}
else
{
// OrOfConst = TopAbs_REVERSED;
OrOfVertex = TopAbs_FORWARD;
AnotherVertex = V1;
}
BRep_Builder BB;
Standard_Real fpar, lpar;
BRep_Tool::Range(F_Edge, fpar, lpar);
if (OrOfVertex == TopAbs_FORWARD)
fpar = theParam;
else
lpar = theParam;
BB.Range(F_Edge, fpar, lpar);
F_Edge.Free(Standard_True);
BB.Remove(F_Edge, AnotherVertex);
theVertex.Orientation(OrOfVertex);
BB.Add(F_Edge, theVertex);
}
// Finds the edge connected to <theVertex> in the compound <theComp>
// that is closest to bisector plane angularly.
// Removes found edge from <theComp>
//<theAxis> is the axis of bisector plane
static TopoDS_Edge FindEdgeCloseToBisectorPlane(const TopoDS_Vertex& theVertex,
TopoDS_Compound& theComp,
const gp_Ax1& theAxis)
{
TopTools_IndexedDataMapOfShapeListOfShape VEmap;
TopExp::MapShapesAndAncestors(theComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap);
TopoDS_Edge MinEdge;
if (!VEmap.Contains(theVertex))
return MinEdge;
BRep_Builder BB;
const TopTools_ListOfShape& Edges = VEmap.FindFromKey(theVertex);
if (Edges.Extent() == 1)
MinEdge = TopoDS::Edge(Edges.First());
else
{
TopTools_ListIteratorOfListOfShape itl(Edges);
Standard_Real MinAngle = RealLast();
for (; itl.More(); itl.Next())
{
const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
TopoDS_Wire aWire;
BB.MakeWire(aWire);
BB.Add(aWire, anEdge);
gp_Pln aPln;
Standard_Boolean issing;
ComputeAveragePlaneAndMaxDeviation(aWire, aPln, issing);
Standard_Real anAngle;
if (issing) // edge is a segment of line
{
//<anAngle> is angle between <anEdge> and its projection on bisector plane
BRepAdaptor_Curve BAcurve(anEdge);
gp_Pnt FirstPnt = BAcurve.Value(BAcurve.FirstParameter());
gp_Pnt LastPnt = BAcurve.Value(BAcurve.LastParameter());
gp_Vec EdgeVec(FirstPnt, LastPnt);
gp_Ax1 EdgeAxis(FirstPnt, EdgeVec);
anAngle = EdgeAxis.Direction().Angle(theAxis.Direction());
if (anAngle > M_PI / 2)
anAngle = M_PI - anAngle;
anAngle = M_PI / 2 - anAngle;
}
else
{
anAngle = aPln.Axis().Angle(theAxis);
if (anAngle > M_PI / 2)
anAngle = M_PI - anAngle;
}
if (anAngle < MinAngle)
{
MinAngle = anAngle;
MinEdge = anEdge;
}
}
} // else (more than one edge)
BB.Remove(theComp, MinEdge);
return MinEdge;
}
static Standard_Boolean FindMiddleEdges(const TopoDS_Vertex& theVertex1,
const TopoDS_Vertex& theVertex2,
const gp_Ax1& theAxis,
TopoDS_Compound& theComp,
TopTools_ListOfShape& theElist)
{
TopTools_IndexedDataMapOfShapeListOfShape VEmap;
TopExp::MapShapesAndAncestors(theComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap);
if (VEmap.IsEmpty())
return Standard_False;
if (!VEmap.Contains(theVertex1) || !VEmap.Contains(theVertex2))
return Standard_False;
TopoDS_Vertex CurVertex = theVertex1;
for (;;)
{
TopoDS_Edge CurEdge;
CurEdge = FindEdgeCloseToBisectorPlane(CurVertex, theComp, theAxis);
if (CurEdge.IsNull())
return Standard_False;
TopoDS_Vertex V1, V2;
TopExp::Vertices(CurEdge, V1, V2);
CurVertex = (V1.IsSame(CurVertex)) ? V2 : V1;
theElist.Append(CurEdge);
if (CurVertex.IsSame(theVertex2))
return Standard_True;
}
}
static Standard_Boolean FindCommonVertex(const TopoDS_Edge& theFirstEdge,
const TopoDS_Edge& theLastEdge,
const TopoDS_Vertex& theFirstVertex,
const TopoDS_Vertex& theLastVertex,
TopoDS_Vertex& theCommonVertex)
{
if (!theFirstVertex.IsSame(theLastVertex))
{
Standard_Boolean CommonVertexExists =
TopExp::CommonVertex(theFirstEdge, theLastEdge, theCommonVertex);
return CommonVertexExists;
}
TopoDS_Vertex V1, V2, V3, V4;
TopExp::Vertices(theFirstEdge, V1, V2);
TopExp::Vertices(theLastEdge, V3, V4);
if (V1.IsSame(theFirstVertex))
{
if (V2.IsSame(V3) || V2.IsSame(V4))
{
theCommonVertex = V2;
return Standard_True;
}
}
else
{
if (V1.IsSame(V3) || V1.IsSame(V4))
{
theCommonVertex = V1;
return Standard_True;
}
}
return Standard_False;
}