mirror of
https://github.com/Open-Cascade-SAS/OCCT.git
synced 2026-09-04 03:38:01 +08:00
Modeling Algorithms - Enhance fillet and chamfer handling. Part 2 (#1449)
- Detect complete coincidence between fillet and chamfer intersection curves. - Preserve orientation relationships between equivalent intersection curves. - Reuse existing restriction edges instead of constructing duplicate topology. - Merge coincident curve endpoints into shared topological vertices. - Exclude fully consumed faces and their obsolete boundary edges during reconstruction. - Mark edges collapsed to a single vertex as degenerated during construction. - Accept tangential contacts while rejecting transversal intersections. - Preserve generated and modified shape history in the resulting topology. - Add GTests for convex, concave, opposing-edge, chamfer, and history cases.
This commit is contained in:
@@ -6,4 +6,5 @@ set(OCCT_TKBool_GTests_FILES
|
||||
BRepAlgoAPI_Fuse_Test.cxx
|
||||
BRepAlgoAPI_Section_Test.cxx
|
||||
BRepFill_PipeShell_Test.cxx
|
||||
TopOpeBRepDS_BuildTool_Test.cxx
|
||||
)
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
// Copyright (c) 2026 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 <gtest/gtest.h>
|
||||
|
||||
#include <BRepBuilderAPI_MakeEdge.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <Geom_Circle.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <TopOpeBRepDS_BuildTool.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
|
||||
TEST(TopOpeBRepDS_BuildToolTest, CopyReversedPeriodicEdgePreservesRange)
|
||||
{
|
||||
const occ::handle<Geom_Circle> aCircle = new Geom_Circle(gp_Ax2(), 1.0);
|
||||
TopoDS_Edge aSource = BRepBuilderAPI_MakeEdge(aCircle);
|
||||
aSource.Reverse();
|
||||
|
||||
TopOpeBRepDS_BuildTool aBuildTool;
|
||||
TopoDS_Shape aCopy;
|
||||
aBuildTool.CopyEdge(aSource, aCopy);
|
||||
for (TopExp_Explorer aVertexIt(aSource, TopAbs_VERTEX); aVertexIt.More(); aVertexIt.Next())
|
||||
{
|
||||
aBuildTool.AddEdgeVertex(aSource, aCopy, aVertexIt.Current());
|
||||
}
|
||||
|
||||
double aFirst, aLast;
|
||||
BRep_Tool::Range(TopoDS::Edge(aCopy), aFirst, aLast);
|
||||
EXPECT_NEAR(aFirst, aCircle->FirstParameter(), Precision::PConfusion());
|
||||
EXPECT_NEAR(aLast, aCircle->LastParameter(), Precision::PConfusion());
|
||||
}
|
||||
@@ -15,9 +15,15 @@
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#include <Standard_Integer.hxx>
|
||||
#include <Geom2dAdaptor_Curve.hxx>
|
||||
#include <Geom2dInt_GInter.hxx>
|
||||
#include <IntRes2d_IntersectionSegment.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <NCollection_HArray1.hxx>
|
||||
#include <NCollection_LinearVector.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopOpeBRepBuild_define.hxx>
|
||||
#include <TopOpeBRepBuild_EdgeBuilder.hxx>
|
||||
@@ -29,10 +35,121 @@
|
||||
#include <TopOpeBRepDS_HDataStructure.hxx>
|
||||
#include <TopOpeBRepDS_PointIterator.hxx>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
#ifdef OCCT_DEBUG
|
||||
extern bool TopOpeBRepBuild_GettraceCU();
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
struct TopOpeBRepBuild_SurfaceCurve
|
||||
{
|
||||
int Index;
|
||||
occ::handle<Geom2d_Curve> PCurve;
|
||||
double FirstParameter;
|
||||
double LastParameter;
|
||||
};
|
||||
|
||||
bool TopOpeBRepBuild_CurveRange(const TopOpeBRepDS_Curve& theCurve,
|
||||
const occ::handle<Geom2d_Curve>& thePCurve,
|
||||
double& theFirst,
|
||||
double& theLast)
|
||||
{
|
||||
const auto isValidRange = [](const double theRangeFirst, const double theRangeLast) {
|
||||
return theRangeFirst < theRangeLast && !Precision::IsInfinite(theRangeFirst)
|
||||
&& !Precision::IsInfinite(theRangeLast);
|
||||
};
|
||||
|
||||
if (theCurve.Range(theFirst, theLast) && isValidRange(theFirst, theLast))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!thePCurve.IsNull())
|
||||
{
|
||||
theFirst = thePCurve->FirstParameter();
|
||||
theLast = thePCurve->LastParameter();
|
||||
if (isValidRange(theFirst, theLast))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
const occ::handle<Geom_Curve>& aCurve3d = theCurve.Curve();
|
||||
if (!aCurve3d.IsNull())
|
||||
{
|
||||
theFirst = aCurve3d->FirstParameter();
|
||||
theLast = aCurve3d->LastParameter();
|
||||
return isValidRange(theFirst, theLast);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TopOpeBRepBuild_HasCompleteCoincidence(const Geom2dInt_GInter& theIntersector,
|
||||
const Geom2dAdaptor_Curve& theFirstCurve,
|
||||
const Geom2dAdaptor_Curve& theSecondCurve,
|
||||
bool& theIsReversed)
|
||||
{
|
||||
if (theIntersector.NbSegments() != 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const IntRes2d_IntersectionSegment& aSegment = theIntersector.Segment(1);
|
||||
if (!aSegment.HasFirstPoint() || !aSegment.HasLastPoint())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const double aFirstOnFirst = aSegment.FirstPoint().ParamOnFirst();
|
||||
const double aLastOnFirst = aSegment.LastPoint().ParamOnFirst();
|
||||
const double aFirstOnSecond = aSegment.FirstPoint().ParamOnSecond();
|
||||
const double aLastOnSecond = aSegment.LastPoint().ParamOnSecond();
|
||||
const double aTolerance = Precision::PConfusion();
|
||||
const bool isComplete =
|
||||
std::abs(std::min(aFirstOnFirst, aLastOnFirst) - theFirstCurve.FirstParameter()) <= aTolerance
|
||||
&& std::abs(std::max(aFirstOnFirst, aLastOnFirst) - theFirstCurve.LastParameter()) <= aTolerance
|
||||
&& std::abs(std::min(aFirstOnSecond, aLastOnSecond) - theSecondCurve.FirstParameter())
|
||||
<= aTolerance
|
||||
&& std::abs(std::max(aFirstOnSecond, aLastOnSecond) - theSecondCurve.LastParameter())
|
||||
<= aTolerance;
|
||||
if (isComplete)
|
||||
{
|
||||
theIsReversed = (aLastOnFirst - aFirstOnFirst) * (aLastOnSecond - aFirstOnSecond) < 0.0;
|
||||
}
|
||||
return isComplete;
|
||||
}
|
||||
|
||||
bool TopOpeBRepBuild_FindCurveEnd(const occ::handle<TopOpeBRepDS_HDataStructure>& theHDS,
|
||||
const int theCurveIndex,
|
||||
const bool theCurveStart,
|
||||
int& theGeometryIndex,
|
||||
bool& theIsPoint)
|
||||
{
|
||||
double aFirst, aLast;
|
||||
if (!TopOpeBRepBuild_CurveRange(theHDS->Curve(theCurveIndex), nullptr, aFirst, aLast))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const double aParameter = theCurveStart ? aFirst : aLast;
|
||||
double aBestDistance = RealLast();
|
||||
for (TopOpeBRepDS_PointIterator aPointIt(theHDS->CurvePoints(theCurveIndex)); aPointIt.More();
|
||||
aPointIt.Next())
|
||||
{
|
||||
const double aDistance = std::abs(aPointIt.Parameter() - aParameter);
|
||||
if (aDistance < aBestDistance)
|
||||
{
|
||||
aBestDistance = aDistance;
|
||||
theGeometryIndex = aPointIt.Current();
|
||||
theIsPoint = aPointIt.IsPoint();
|
||||
}
|
||||
}
|
||||
return aBestDistance <= Precision::PConfusion();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void TopOpeBRepBuild_Builder::BuildEdges(const int iC,
|
||||
@@ -52,6 +169,36 @@ void TopOpeBRepBuild_Builder::BuildEdges(const int
|
||||
return;
|
||||
}
|
||||
|
||||
if (C.EquivalentCurve() > 0 && C.EquivalentCurve() != iC)
|
||||
{
|
||||
const int aReferenceCurve = C.EquivalentCurve();
|
||||
if (NewEdges(aReferenceCurve).IsEmpty())
|
||||
{
|
||||
BuildEdges(aReferenceCurve, HDS);
|
||||
}
|
||||
ChangeNewEdges(iC) = NewEdges(aReferenceCurve);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!C.ExistingEdge().IsNull())
|
||||
{
|
||||
if (!myCoincidentEdges.IsBound(C.ExistingEdge()))
|
||||
{
|
||||
TopoDS_Shape aCopiedEdge;
|
||||
myBuildTool.CopyEdge(C.ExistingEdge(), aCopiedEdge);
|
||||
for (TopExp_Explorer aVertexIt(C.ExistingEdge(), TopAbs_VERTEX); aVertexIt.More();
|
||||
aVertexIt.Next())
|
||||
{
|
||||
myBuildTool.AddEdgeVertex(C.ExistingEdge(), aCopiedEdge, aVertexIt.Current());
|
||||
}
|
||||
myCoincidentEdges.Bind(C.ExistingEdge(), aCopiedEdge);
|
||||
}
|
||||
TopoDS_Shape anEdge = myCoincidentEdges(C.ExistingEdge());
|
||||
anEdge.Orientation(TopAbs_FORWARD);
|
||||
ChangeNewEdges(iC).Append(anEdge);
|
||||
return;
|
||||
}
|
||||
|
||||
TopoDS_Shape anEdge;
|
||||
const TopOpeBRepDS_Curve& curC = HDS->Curve(iC);
|
||||
myBuildTool.MakeEdge(anEdge, curC, HDS->DS());
|
||||
@@ -106,8 +253,168 @@ void TopOpeBRepBuild_Builder::BuildEdges(const occ::handle<TopOpeBRepDS_HDataStr
|
||||
TopOpeBRepDS_DataStructure& BDS = HDS->ChangeDS();
|
||||
|
||||
myNewEdges.Clear();
|
||||
myCoincidentEdges.Clear();
|
||||
TopOpeBRepDS_CurveExplorer cex;
|
||||
|
||||
NCollection_LinearVector<TopOpeBRepBuild_SurfaceCurve> aSurfaceCurves;
|
||||
for (int aSurfaceIndex = 1; aSurfaceIndex <= HDS->NbSurfaces(); ++aSurfaceIndex)
|
||||
{
|
||||
aSurfaceCurves.Clear();
|
||||
for (TopOpeBRepDS_CurveIterator aCurveIt(HDS->SurfaceCurves(aSurfaceIndex)); aCurveIt.More();
|
||||
aCurveIt.Next())
|
||||
{
|
||||
const occ::handle<Geom2d_Curve>& aPCurve = aCurveIt.PCurve();
|
||||
const TopOpeBRepDS_Curve& aCurve = HDS->Curve(aCurveIt.Current());
|
||||
if (aPCurve.IsNull() || aCurve.Curve().IsNull())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
double aFirst, aLast;
|
||||
if (TopOpeBRepBuild_CurveRange(aCurve, aPCurve, aFirst, aLast))
|
||||
{
|
||||
aSurfaceCurves.Append({aCurveIt.Current(), aPCurve, aFirst, aLast});
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t aFirstIndex = 0; aFirstIndex < aSurfaceCurves.Size(); ++aFirstIndex)
|
||||
{
|
||||
for (size_t aSecondIndex = aFirstIndex + 1; aSecondIndex < aSurfaceCurves.Size();
|
||||
++aSecondIndex)
|
||||
{
|
||||
const TopOpeBRepBuild_SurfaceCurve& aFirst = aSurfaceCurves[aFirstIndex];
|
||||
const TopOpeBRepBuild_SurfaceCurve& aSecond = aSurfaceCurves[aSecondIndex];
|
||||
Geom2dAdaptor_Curve aFirstCurve(aFirst.PCurve, aFirst.FirstParameter, aFirst.LastParameter);
|
||||
Geom2dAdaptor_Curve aSecondCurve(aSecond.PCurve,
|
||||
aSecond.FirstParameter,
|
||||
aSecond.LastParameter);
|
||||
Geom2dInt_GInter anIntersector(aFirstCurve,
|
||||
aSecondCurve,
|
||||
Precision::PConfusion(),
|
||||
Precision::PConfusion());
|
||||
bool isReversed = false;
|
||||
if (TopOpeBRepBuild_HasCompleteCoincidence(anIntersector,
|
||||
aFirstCurve,
|
||||
aSecondCurve,
|
||||
isReversed))
|
||||
{
|
||||
BDS.MergeEquivalentCurves(aFirst.Index, aSecond.Index, isReversed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (cex.Init(BDS, false); cex.More(); cex.Next())
|
||||
{
|
||||
const int aCurveIndex = cex.Index();
|
||||
if (cex.Curve().EquivalentCurve() <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
bool isReversed = false;
|
||||
const int aRoot = BDS.FindEquivalentCurve(aCurveIndex, isReversed);
|
||||
BDS.ChangeCurve(aCurveIndex).SetEquivalentCurve(aRoot, isReversed);
|
||||
}
|
||||
|
||||
NCollection_DataMap<int, TopoDS_Shape> anEquivalentPointVertices;
|
||||
for (cex.Init(BDS, false); cex.More(); cex.Next())
|
||||
{
|
||||
const int aCurveIndex = cex.Index();
|
||||
for (int anEnd = 0; anEnd < 2; ++anEnd)
|
||||
{
|
||||
const bool isCurveStart = (anEnd == 0);
|
||||
bool isReferenceStart = false;
|
||||
const int aReferenceCurve =
|
||||
BDS.FindEquivalentCurvePoint(aCurveIndex, isCurveStart, isReferenceStart);
|
||||
if (aReferenceCurve == aCurveIndex && isReferenceStart == isCurveStart)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const int aReference = 2 * aReferenceCurve + (isReferenceStart ? 0 : 1);
|
||||
if (anEquivalentPointVertices.IsBound(aReference))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int aGeometryIndex = 0;
|
||||
bool isPoint = false;
|
||||
if (TopOpeBRepBuild_FindCurveEnd(HDS,
|
||||
aReferenceCurve,
|
||||
isReferenceStart,
|
||||
aGeometryIndex,
|
||||
isPoint))
|
||||
{
|
||||
anEquivalentPointVertices.Bind(aReference,
|
||||
isPoint ? NewVertex(aGeometryIndex)
|
||||
: HDS->Shape(aGeometryIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (cex.Init(BDS, false); cex.More(); cex.Next())
|
||||
{
|
||||
const int aCurveIndex = cex.Index();
|
||||
for (int anEnd = 0; anEnd < 2; ++anEnd)
|
||||
{
|
||||
const bool isCurveStart = (anEnd == 0);
|
||||
bool isReferenceStart = false;
|
||||
const int aReferenceCurve =
|
||||
BDS.FindEquivalentCurvePoint(aCurveIndex, isCurveStart, isReferenceStart);
|
||||
const int aReference = 2 * aReferenceCurve + (isReferenceStart ? 0 : 1);
|
||||
if (!anEquivalentPointVertices.IsBound(aReference))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int aGeometryIndex = 0;
|
||||
bool isPoint = false;
|
||||
if (TopOpeBRepBuild_FindCurveEnd(HDS, aCurveIndex, isCurveStart, aGeometryIndex, isPoint)
|
||||
&& isPoint)
|
||||
{
|
||||
ChangeNewVertex(aGeometryIndex) = anEquivalentPointVertices(aReference);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (cex.Init(BDS, false); cex.More(); cex.Next())
|
||||
{
|
||||
const int aCurveIndex = cex.Index();
|
||||
const int aReferenceCurve = cex.Curve().EquivalentCurve();
|
||||
if (aReferenceCurve <= 0 || aReferenceCurve == aCurveIndex)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (TopOpeBRepDS_PointIterator aPointIt(HDS->CurvePoints(aCurveIndex)); aPointIt.More();
|
||||
aPointIt.Next())
|
||||
{
|
||||
if (!aPointIt.IsPoint())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const int aPointIndex = aPointIt.Current();
|
||||
const TopOpeBRepDS_Point& aPoint = HDS->Point(aPointIndex);
|
||||
for (TopOpeBRepDS_PointIterator aReferencePointIt(HDS->CurvePoints(aReferenceCurve));
|
||||
aReferencePointIt.More();
|
||||
aReferencePointIt.Next())
|
||||
{
|
||||
if (!aReferencePointIt.IsPoint())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const int aReferencePointIndex = aReferencePointIt.Current();
|
||||
const TopOpeBRepDS_Point& aReferencePoint = HDS->Point(aReferencePointIndex);
|
||||
const double aTolerance = std::max(aPoint.Tolerance(), aReferencePoint.Tolerance());
|
||||
if (aPoint.Point().Distance(aReferencePoint.Point()) <= aTolerance)
|
||||
{
|
||||
ChangeNewVertex(aPointIndex) = NewVertex(aReferencePointIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ick = 0;
|
||||
for (cex.Init(BDS, false); cex.More(); cex.Next())
|
||||
{
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <NCollection_FlatDataMap.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopOpeBRepBuild_define.hxx>
|
||||
#include <TopOpeBRepBuild_FaceBuilder.hxx>
|
||||
@@ -53,7 +55,41 @@ void TopOpeBRepBuild_Builder::BuildFaces(const int
|
||||
// myBuildTool.MakeFace(aFace,HDS->Surface(iS));
|
||||
// modified by NIZNHY-PKV Mon Dec 13 10:01:03 2010t
|
||||
//
|
||||
TopOpeBRepBuild_WireEdgeSet WES(aFace, this);
|
||||
TopOpeBRepBuild_WireEdgeSet WES(aFace, this);
|
||||
NCollection_FlatDataMap<int, int> anEquivalentCurveOrientations;
|
||||
for (TopOpeBRepDS_CurveIterator aCurveIt(HDS->SurfaceCurves(iS)); aCurveIt.More();
|
||||
aCurveIt.Next())
|
||||
{
|
||||
const TopOpeBRepDS_Curve& aCurve = HDS->Curve(aCurveIt.Current());
|
||||
const int aReferenceCurve = aCurve.EquivalentCurve();
|
||||
if (aReferenceCurve > 0)
|
||||
{
|
||||
TopAbs_Orientation anOrientation = aCurveIt.Orientation(TopAbs_IN);
|
||||
if (aCurve.IsEquivalentCurveReversed())
|
||||
{
|
||||
anOrientation = TopAbs::Reverse(anOrientation);
|
||||
}
|
||||
int anOrientationMask = anEquivalentCurveOrientations.IsBound(aReferenceCurve)
|
||||
? anEquivalentCurveOrientations(aReferenceCurve)
|
||||
: 0;
|
||||
if (anOrientation == TopAbs_FORWARD)
|
||||
{
|
||||
anOrientationMask |= 1;
|
||||
}
|
||||
else if (anOrientation == TopAbs_REVERSED)
|
||||
{
|
||||
anOrientationMask |= 2;
|
||||
}
|
||||
if (anEquivalentCurveOrientations.IsBound(aReferenceCurve))
|
||||
{
|
||||
anEquivalentCurveOrientations.ChangeFind(aReferenceCurve) = anOrientationMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
anEquivalentCurveOrientations.Bind(aReferenceCurve, anOrientationMask);
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
#ifdef OCCT_DEBUG
|
||||
bool tSE = TopOpeBRepBuild_GettraceSPF();
|
||||
@@ -62,8 +98,14 @@ void TopOpeBRepBuild_Builder::BuildFaces(const int
|
||||
TopOpeBRepDS_CurveIterator SCurves(HDS->SurfaceCurves(iS));
|
||||
for (; SCurves.More(); SCurves.Next())
|
||||
{
|
||||
int iC = SCurves.Current();
|
||||
const TopOpeBRepDS_Curve& CDS = HDS->Curve(iC);
|
||||
int iC = SCurves.Current();
|
||||
const TopOpeBRepDS_Curve& CDS = HDS->Curve(iC);
|
||||
const int aReferenceCurve = CDS.EquivalentCurve();
|
||||
if (aReferenceCurve > 0 && anEquivalentCurveOrientations.IsBound(aReferenceCurve)
|
||||
&& anEquivalentCurveOrientations(aReferenceCurve) == 3)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
if (tSE)
|
||||
std::cout << std::endl << "BuildFaces : C " << iC << " on S " << iS << std::endl;
|
||||
@@ -82,6 +124,10 @@ void TopOpeBRepBuild_Builder::BuildFaces(const int
|
||||
}
|
||||
// modified by NIZNHY-PKV Mon Dec 13 10:09:43 2010f
|
||||
TopAbs_Orientation ori = SCurves.Orientation(TopAbs_IN);
|
||||
if (CDS.IsEquivalentCurveReversed())
|
||||
{
|
||||
ori = TopAbs::Reverse(ori);
|
||||
}
|
||||
myBuildTool.Orientation(anEdge, ori);
|
||||
const occ::handle<Geom2d_Curve>& PC = SCurves.PCurve();
|
||||
myBuildTool.PCurve(aFace, anEdge, CDS, PC);
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <TopExp.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Iterator.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopOpeBRepBuild_Builder.hxx>
|
||||
@@ -36,10 +37,12 @@
|
||||
#include <TopOpeBRepBuild_WireEdgeSet.hxx>
|
||||
#include <TopOpeBRepDS_BuildTool.hxx>
|
||||
#include <TopOpeBRepDS_Config.hxx>
|
||||
#include <TopOpeBRepDS_CurveExplorer.hxx>
|
||||
#include <TopOpeBRepDS_CurveIterator.hxx>
|
||||
#include <TopOpeBRepDS_ListOfShapeOn1State.hxx>
|
||||
#include <TopTools_ShapeMapHasher.hxx>
|
||||
#include <NCollection_DataMap.hxx>
|
||||
#include <NCollection_FlatDataMap.hxx>
|
||||
#include <TopOpeBRepDS_Filter.hxx>
|
||||
#include <TopOpeBRepDS_HDataStructure.hxx>
|
||||
#include <TopOpeBRepDS_PointIterator.hxx>
|
||||
@@ -75,6 +78,49 @@ static thread_local int STATIC_SOLIDINDEX = 0;
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
static TopoDS_Shape SubstituteCoincidentEdges(
|
||||
const TopoDS_Shape& theShape,
|
||||
const NCollection_DataMap<TopoDS_Shape, TopoDS_Shape, TopTools_ShapeMapHasher>& theEdges,
|
||||
const TopOpeBRepDS_BuildTool& theBuildTool)
|
||||
{
|
||||
if (theShape.ShapeType() != TopAbs_FACE && theShape.ShapeType() != TopAbs_WIRE)
|
||||
{
|
||||
return theShape;
|
||||
}
|
||||
|
||||
TopoDS_Shape aCopy = theShape.EmptyCopied();
|
||||
bool isModified = false;
|
||||
for (TopoDS_Iterator anIt(theShape, false, false); anIt.More(); anIt.Next())
|
||||
{
|
||||
TopoDS_Shape aSubShape = anIt.Value();
|
||||
if (aSubShape.ShapeType() == TopAbs_EDGE && theEdges.IsBound(aSubShape))
|
||||
{
|
||||
const TopAbs_Orientation anOrientation = aSubShape.Orientation();
|
||||
aSubShape = theEdges(aSubShape);
|
||||
aSubShape.Orientation(anOrientation);
|
||||
isModified = true;
|
||||
}
|
||||
else if (aSubShape.ShapeType() == TopAbs_WIRE)
|
||||
{
|
||||
TopoDS_Shape aNewWire = SubstituteCoincidentEdges(aSubShape, theEdges, theBuildTool);
|
||||
isModified = isModified || !aNewWire.IsSame(aSubShape);
|
||||
aSubShape = aNewWire;
|
||||
}
|
||||
|
||||
if (theShape.ShapeType() == TopAbs_FACE)
|
||||
{
|
||||
theBuildTool.AddFaceWire(aCopy, aSubShape);
|
||||
}
|
||||
else
|
||||
{
|
||||
theBuildTool.AddWireEdge(aCopy, aSubShape);
|
||||
}
|
||||
}
|
||||
return isModified ? aCopy : theShape;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
TopOpeBRepBuild_Builder::TopOpeBRepBuild_Builder(const TopOpeBRepDS_BuildTool& BT)
|
||||
: myBuildTool(BT),
|
||||
mySectionDone(false),
|
||||
@@ -114,6 +160,95 @@ occ::handle<TopOpeBRepDS_HDataStructure> TopOpeBRepBuild_Builder::DataStructure(
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
static void FillEquivalentCurveOrientationMasks(
|
||||
const TopoDS_Shape& theFace,
|
||||
const TopAbs_State theState,
|
||||
const bool theReverse,
|
||||
const occ::handle<TopOpeBRepDS_HDataStructure>& theDataStructure,
|
||||
NCollection_FlatDataMap<int, int>& theOrientationMasks)
|
||||
{
|
||||
for (TopOpeBRepDS_CurveIterator aCurveIt(theDataStructure->FaceCurves(theFace)); aCurveIt.More();
|
||||
aCurveIt.Next())
|
||||
{
|
||||
const int aReferenceCurve = theDataStructure->Curve(aCurveIt.Current()).EquivalentCurve();
|
||||
if (aReferenceCurve <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
TopAbs_Orientation anOrientation =
|
||||
TopOpeBRepBuild_Builder::Orient(aCurveIt.Orientation(theState), theReverse);
|
||||
if (theDataStructure->Curve(aCurveIt.Current()).IsEquivalentCurveReversed())
|
||||
{
|
||||
anOrientation = TopAbs::Reverse(anOrientation);
|
||||
}
|
||||
int anOrientationMask =
|
||||
theOrientationMasks.IsBound(aReferenceCurve) ? theOrientationMasks(aReferenceCurve) : 0;
|
||||
if (anOrientation == TopAbs_FORWARD)
|
||||
{
|
||||
anOrientationMask |= 1;
|
||||
}
|
||||
else if (anOrientation == TopAbs_REVERSED)
|
||||
{
|
||||
anOrientationMask |= 2;
|
||||
}
|
||||
if (theOrientationMasks.IsBound(aReferenceCurve))
|
||||
{
|
||||
theOrientationMasks.ChangeFind(aReferenceCurve) = anOrientationMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
theOrientationMasks.Bind(aReferenceCurve, anOrientationMask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
static bool IsConsumedByCoincidentCurves(
|
||||
const TopoDS_Shape& theFace,
|
||||
const occ::handle<TopOpeBRepDS_HDataStructure>& theDataStructure)
|
||||
{
|
||||
for (int aStateIndex = 0; aStateIndex < 2; ++aStateIndex)
|
||||
{
|
||||
const TopAbs_State aState = aStateIndex == 0 ? TopAbs_IN : TopAbs_OUT;
|
||||
NCollection_FlatDataMap<int, int> anOrientationMasks;
|
||||
FillEquivalentCurveOrientationMasks(theFace,
|
||||
aState,
|
||||
false,
|
||||
theDataStructure,
|
||||
anOrientationMasks);
|
||||
for (NCollection_FlatDataMap<int, int>::Iterator anIt(anOrientationMasks); anIt.More();
|
||||
anIt.Next())
|
||||
{
|
||||
if (anIt.Value() == 3)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
static void RegisterConsumedFaceEdges(
|
||||
const TopoDS_Shape& theFace,
|
||||
const NCollection_DataMap<TopoDS_Shape, bool, TopTools_ShapeMapHasher>& theRestrictions,
|
||||
NCollection_DataMap<TopoDS_Shape, bool, TopTools_ShapeMapHasher>& theConsumedEdges)
|
||||
{
|
||||
for (TopExp_Explorer anEdgeIt(theFace, TopAbs_EDGE); anEdgeIt.More(); anEdgeIt.Next())
|
||||
{
|
||||
const TopoDS_Shape& anEdge = anEdgeIt.Current();
|
||||
if (!theRestrictions.IsBound(anEdge) && !theConsumedEdges.IsBound(anEdge))
|
||||
{
|
||||
theConsumedEdges.Bind(anEdge, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void TopOpeBRepBuild_Builder::Perform(const occ::handle<TopOpeBRepDS_HDataStructure>& HDS)
|
||||
{
|
||||
#ifdef OCCT_DEBUG
|
||||
@@ -124,6 +259,28 @@ void TopOpeBRepBuild_Builder::Perform(const occ::handle<TopOpeBRepDS_HDataStruct
|
||||
BuildVertices(HDS);
|
||||
SplitEvisoONperiodicF();
|
||||
BuildEdges(HDS);
|
||||
myConsumedFaces.Clear();
|
||||
myConsumedFaceEdges.Clear();
|
||||
NCollection_DataMap<TopoDS_Shape, bool, TopTools_ShapeMapHasher> aReusedRestrictionEdges;
|
||||
TopOpeBRepDS_CurveExplorer aCurveIt;
|
||||
for (aCurveIt.Init(HDS->DS(), false); aCurveIt.More(); aCurveIt.Next())
|
||||
{
|
||||
const TopoDS_Edge& aRestriction = aCurveIt.Curve().ExistingEdge();
|
||||
if (!aRestriction.IsNull() && !aReusedRestrictionEdges.IsBound(aRestriction))
|
||||
{
|
||||
aReusedRestrictionEdges.Bind(aRestriction, true);
|
||||
}
|
||||
}
|
||||
for (int aShapeIndex = 1; aShapeIndex <= HDS->NbShapes(); ++aShapeIndex)
|
||||
{
|
||||
const TopoDS_Shape& aShape = HDS->Shape(aShapeIndex, false);
|
||||
if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_FACE
|
||||
&& IsConsumedByCoincidentCurves(aShape, HDS))
|
||||
{
|
||||
myConsumedFaces.Bind(aShape, true);
|
||||
RegisterConsumedFaceEdges(aShape, aReusedRestrictionEdges, myConsumedFaceEdges);
|
||||
}
|
||||
}
|
||||
BuildFaces(HDS);
|
||||
myIsKPart = 0;
|
||||
InitSection();
|
||||
@@ -153,6 +310,13 @@ void TopOpeBRepBuild_Builder::AddIntersectionEdges(TopoDS_Shape& aFa
|
||||
const bool RevOri1,
|
||||
TopOpeBRepBuild_ShapeSet& WES) const
|
||||
{
|
||||
NCollection_FlatDataMap<int, int> aConsumedCurveGroups;
|
||||
FillEquivalentCurveOrientationMasks(aFace,
|
||||
ToBuild1,
|
||||
RevOri1,
|
||||
myDataStructure,
|
||||
aConsumedCurveGroups);
|
||||
|
||||
TopoDS_Shape anEdge;
|
||||
TopOpeBRepDS_CurveIterator FCurves = myDataStructure->FaceCurves(aFace);
|
||||
for (; FCurves.More(); FCurves.Next())
|
||||
@@ -162,8 +326,33 @@ void TopOpeBRepBuild_Builder::AddIntersectionEdges(TopoDS_Shape& aFa
|
||||
for (NCollection_List<TopoDS_Shape>::Iterator Iti(LnewE); Iti.More(); Iti.Next())
|
||||
{
|
||||
anEdge = Iti.Value();
|
||||
const int aReferenceCurve = myDataStructure->Curve(iC).EquivalentCurve();
|
||||
if (aReferenceCurve > 0 && aConsumedCurveGroups.IsBound(aReferenceCurve)
|
||||
&& aConsumedCurveGroups(aReferenceCurve) == 3)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const TopoDS_Edge& anExistingEdge = myDataStructure->Curve(iC).ExistingEdge();
|
||||
bool isBoundaryEdge = false;
|
||||
for (TopExp_Explorer anEdgeIt(aFace, TopAbs_EDGE); anEdgeIt.More(); anEdgeIt.Next())
|
||||
{
|
||||
if (anEdge.IsSame(anEdgeIt.Current())
|
||||
|| (!anExistingEdge.IsNull() && anExistingEdge.IsSame(anEdgeIt.Current())))
|
||||
{
|
||||
isBoundaryEdge = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isBoundaryEdge)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
TopAbs_Orientation ori = FCurves.Orientation(ToBuild1);
|
||||
TopAbs_Orientation newori = Orient(ori, RevOri1);
|
||||
if (myDataStructure->Curve(iC).IsEquivalentCurveReversed())
|
||||
{
|
||||
newori = TopAbs::Reverse(newori);
|
||||
}
|
||||
|
||||
if (newori == TopAbs_EXTERNAL)
|
||||
{
|
||||
@@ -172,7 +361,7 @@ void TopOpeBRepBuild_Builder::AddIntersectionEdges(TopoDS_Shape& aFa
|
||||
|
||||
myBuildTool.Orientation(anEdge, newori);
|
||||
const occ::handle<Geom2d_Curve>& PC = FCurves.PCurve();
|
||||
myBuildTool.PCurve(aFace, anEdge, PC);
|
||||
myBuildTool.PCurve(aFace, anEdge, myDataStructure->Curve(iC), PC);
|
||||
WES.AddStartElement(anEdge);
|
||||
}
|
||||
}
|
||||
@@ -1270,7 +1459,10 @@ void TopOpeBRepBuild_Builder::SplitFace1(const TopoDS_Shape& Foriented,
|
||||
// Build the new faces
|
||||
// -------------------
|
||||
NCollection_List<TopoDS_Shape>& FaceList = ChangeMerged(Fforward, ToBuild1);
|
||||
MakeFaces(Fforward, FBU, FaceList);
|
||||
if (!myConsumedFaces.IsBound(Fforward))
|
||||
{
|
||||
MakeFaces(Fforward, FBU, FaceList);
|
||||
}
|
||||
|
||||
// connect new faces as faces built <ToBuild1> on LF1 faces
|
||||
// --------------------------------------------------------
|
||||
@@ -1447,7 +1639,10 @@ void TopOpeBRepBuild_Builder::SplitFace2(const TopoDS_Shape& Foriented,
|
||||
// Build the new faces
|
||||
// -------------------
|
||||
NCollection_List<TopoDS_Shape>& FaceList1 = ChangeMerged(Fforward, ToBuild1);
|
||||
MakeFaces(Fforward, FBU1, FaceList1);
|
||||
if (!myConsumedFaces.IsBound(Fforward))
|
||||
{
|
||||
MakeFaces(Fforward, FBU1, FaceList1);
|
||||
}
|
||||
|
||||
// connect new faces as faces built <ToBuild1> on LF1 faces
|
||||
// --------------------------------------------------------
|
||||
@@ -1514,7 +1709,10 @@ void TopOpeBRepBuild_Builder::SplitFace2(const TopoDS_Shape& Foriented,
|
||||
// Build the new faces
|
||||
// -------------------
|
||||
NCollection_List<TopoDS_Shape>& FaceList2 = ChangeMerged(Fforward, ToBuild2);
|
||||
MakeFaces(Fforward, FBU2, FaceList2);
|
||||
if (!myConsumedFaces.IsBound(Fforward))
|
||||
{
|
||||
MakeFaces(Fforward, FBU2, FaceList2);
|
||||
}
|
||||
|
||||
// connect new faces as faces built <ToBuild2> on LF2 faces
|
||||
// --------------------------------------------------------
|
||||
@@ -1723,6 +1921,8 @@ void TopOpeBRepBuild_Builder::SplitShapes(TopOpeBRepTool_ShapeExplorer& Ex,
|
||||
for (; Ex.More(); Ex.Next())
|
||||
{
|
||||
aShape = Ex.Current();
|
||||
const bool isConsumedFaceEdge =
|
||||
aShape.ShapeType() == TopAbs_EDGE && myConsumedFaceEdges.IsBound(aShape);
|
||||
|
||||
// compute new orientation <newori> to give to the new shapes
|
||||
newori = Orient(myBuildTool.Orientation(aShape), RevOri);
|
||||
@@ -1768,7 +1968,12 @@ void TopOpeBRepBuild_Builder::SplitShapes(TopOpeBRepTool_ShapeExplorer& Ex,
|
||||
//----------------------- IFV
|
||||
for (; It.More(); It.Next())
|
||||
{
|
||||
if (isConsumedFaceEdge)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
newShape = It.Value();
|
||||
newShape = SubstituteCoincidentEdges(newShape, myCoincidentEdges, myBuildTool);
|
||||
myBuildTool.Orientation(newShape, newori);
|
||||
#ifdef OCCT_DEBUG
|
||||
// TopAbs_ShapeEnum tns = TopType(newShape);
|
||||
@@ -1861,8 +2066,9 @@ void TopOpeBRepBuild_Builder::SplitShapes(TopOpeBRepTool_ShapeExplorer& Ex,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (add)
|
||||
if (add && !isConsumedFaceEdge)
|
||||
{
|
||||
aShape = SubstituteCoincidentEdges(aShape, myCoincidentEdges, myBuildTool);
|
||||
myBuildTool.Orientation(aShape, newori);
|
||||
aSet.AddElement(aShape);
|
||||
}
|
||||
@@ -1932,7 +2138,8 @@ void TopOpeBRepBuild_Builder::FillShape(const TopoDS_Shape& S1
|
||||
bool keep = KeepShape(aSubShape, LS2, ToBuild1);
|
||||
if (keep)
|
||||
{
|
||||
newori = Orient(myBuildTool.Orientation(aSubShape), RevOri);
|
||||
newori = Orient(myBuildTool.Orientation(aSubShape), RevOri);
|
||||
aSubShape = SubstituteCoincidentEdges(aSubShape, myCoincidentEdges, myBuildTool);
|
||||
myBuildTool.Orientation(aSubShape, newori);
|
||||
aSet.AddShape(aSubShape);
|
||||
}
|
||||
|
||||
@@ -857,15 +857,18 @@ protected:
|
||||
const NCollection_DataMap<TopoDS_Shape, TopoDS_Shape, TopTools_ShapeMapHasher>& mlf,
|
||||
const TopAbs_State state);
|
||||
|
||||
TopAbs_State myState1;
|
||||
TopAbs_State myState2;
|
||||
TopoDS_Shape myShape1;
|
||||
TopoDS_Shape myShape2;
|
||||
occ::handle<TopOpeBRepDS_HDataStructure> myDataStructure;
|
||||
TopOpeBRepDS_BuildTool myBuildTool;
|
||||
occ::handle<NCollection_HArray1<TopoDS_Shape>> myNewVertices;
|
||||
NCollection_DataMap<int, NCollection_List<TopoDS_Shape>> myNewEdges;
|
||||
occ::handle<NCollection_HArray1<NCollection_List<TopoDS_Shape>>> myNewFaces;
|
||||
TopAbs_State myState1;
|
||||
TopAbs_State myState2;
|
||||
TopoDS_Shape myShape1;
|
||||
TopoDS_Shape myShape2;
|
||||
occ::handle<TopOpeBRepDS_HDataStructure> myDataStructure;
|
||||
TopOpeBRepDS_BuildTool myBuildTool;
|
||||
occ::handle<NCollection_HArray1<TopoDS_Shape>> myNewVertices;
|
||||
NCollection_DataMap<int, NCollection_List<TopoDS_Shape>> myNewEdges;
|
||||
NCollection_DataMap<TopoDS_Shape, TopoDS_Shape, TopTools_ShapeMapHasher> myCoincidentEdges;
|
||||
NCollection_DataMap<TopoDS_Shape, bool, TopTools_ShapeMapHasher> myConsumedFaces;
|
||||
NCollection_DataMap<TopoDS_Shape, bool, TopTools_ShapeMapHasher> myConsumedFaceEdges;
|
||||
occ::handle<NCollection_HArray1<NCollection_List<TopoDS_Shape>>> myNewFaces;
|
||||
NCollection_DataMap<TopoDS_Shape, TopOpeBRepDS_ListOfShapeOn1State, TopTools_ShapeMapHasher>
|
||||
mySplitIN;
|
||||
NCollection_DataMap<TopoDS_Shape, TopOpeBRepDS_ListOfShapeOn1State, TopTools_ShapeMapHasher>
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <BRepCheck.hxx>
|
||||
#include <BRepCheck_Analyzer.hxx>
|
||||
#include <BRepCheck_Status.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <NCollection_List.hxx>
|
||||
#include <NCollection_Shared.hxx>
|
||||
#include <BRepCheck_Result.hxx>
|
||||
@@ -36,6 +37,9 @@
|
||||
#include <TopOpeBRepTool_ShapeExplorer.hxx>
|
||||
#include <TopTools_ShapeMapHasher.hxx>
|
||||
#include <NCollection_IndexedDataMap.hxx>
|
||||
#include <Precision.hxx>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
// #include <DBRep.hxx>
|
||||
#ifdef OCCT_DEBUG
|
||||
@@ -540,7 +544,13 @@ void TopOpeBRepBuild_Builder::MakeEdges(const TopoDS_Shape& anEdge,
|
||||
|
||||
myBuildTool.CopyEdge(anEdge, newEdge);
|
||||
|
||||
bool hasvertex = false;
|
||||
bool hasvertex = false;
|
||||
bool hasForwardVertex = false;
|
||||
bool hasReversedVertex = false;
|
||||
double aForwardParameter = 0.0;
|
||||
double aReversedParameter = 0.0;
|
||||
TopoDS_Shape aForwardVertex;
|
||||
TopoDS_Shape aReversedVertex;
|
||||
for (EDBU.InitVertex(); EDBU.MoreVertex(); EDBU.NextVertex())
|
||||
{
|
||||
TopoDS_Shape V = EDBU.Vertex();
|
||||
@@ -593,6 +603,18 @@ void TopOpeBRepBuild_Builder::MakeEdges(const TopoDS_Shape& anEdge,
|
||||
{
|
||||
hasvertex = true;
|
||||
double parV = EDBU.Parameter();
|
||||
if (Vori == TopAbs_FORWARD)
|
||||
{
|
||||
hasForwardVertex = true;
|
||||
aForwardVertex = V;
|
||||
aForwardParameter = parV;
|
||||
}
|
||||
else if (Vori == TopAbs_REVERSED)
|
||||
{
|
||||
hasReversedVertex = true;
|
||||
aReversedVertex = V;
|
||||
aReversedParameter = parV;
|
||||
}
|
||||
myBuildTool.AddEdgeVertex(newEdge, V);
|
||||
myBuildTool.Parameter(newEdge, V, parV);
|
||||
}
|
||||
@@ -616,6 +638,12 @@ void TopOpeBRepBuild_Builder::MakeEdges(const TopoDS_Shape& anEdge,
|
||||
|
||||
if (hasvertex)
|
||||
{
|
||||
if (hasForwardVertex && hasReversedVertex && aForwardVertex.IsSame(aReversedVertex)
|
||||
&& std::abs(aForwardParameter - aReversedParameter) <= Precision::PConfusion())
|
||||
{
|
||||
BRep_Builder aBuilder;
|
||||
aBuilder.Degenerated(TopoDS::Edge(newEdge), true);
|
||||
}
|
||||
L.Append(newEdge);
|
||||
}
|
||||
} // loop on EDBU edges
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopOpeBRepBuild_define.hxx>
|
||||
@@ -21,6 +22,7 @@
|
||||
#include <TopOpeBRepBuild_WireEdgeSet.hxx>
|
||||
#include <TopOpeBRepDS.hxx>
|
||||
#include <TopOpeBRepDS_BuildTool.hxx>
|
||||
#include <TopOpeBRepDS_Curve.hxx>
|
||||
#include <TopOpeBRepDS_CurveIterator.hxx>
|
||||
#include <TopOpeBRepDS_EXPORT.hxx>
|
||||
#include <TopOpeBRepDS_HDataStructure.hxx>
|
||||
@@ -196,7 +198,23 @@ void TopOpeBRepBuild_Builder::GFillCurveTopologyWES(const TopOpeBRepDS_CurveIter
|
||||
return;
|
||||
}
|
||||
|
||||
int iG = FCit.Current();
|
||||
int iG = FCit.Current();
|
||||
if (myDataStructure->Curve(iG).IsEquivalentCurveReversed())
|
||||
{
|
||||
neworiE = TopAbs::Reverse(neworiE);
|
||||
}
|
||||
const int anEquivalentCurve = myDataStructure->Curve(iG).EquivalentCurve();
|
||||
const TopoDS_Edge& aRestrictionEdge = myDataStructure->Curve(iG).ExistingEdge();
|
||||
if (!aRestrictionEdge.IsNull())
|
||||
{
|
||||
for (TopExp_Explorer anEdgeIt(WESF, TopAbs_EDGE); anEdgeIt.More(); anEdgeIt.Next())
|
||||
{
|
||||
if (aRestrictionEdge.IsSame(anEdgeIt.Current()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
const NCollection_List<TopoDS_Shape>& LnewE = NewEdges(iG);
|
||||
NCollection_List<TopoDS_Shape>::Iterator Iti(LnewE);
|
||||
for (; Iti.More(); Iti.Next())
|
||||
@@ -204,6 +222,24 @@ void TopOpeBRepBuild_Builder::GFillCurveTopologyWES(const TopOpeBRepDS_CurveIter
|
||||
TopoDS_Shape EE = Iti.Value();
|
||||
TopoDS_Edge& E = TopoDS::Edge(EE);
|
||||
|
||||
if (anEquivalentCurve > 0)
|
||||
{
|
||||
bool isAlreadyAdded = false;
|
||||
for (NCollection_List<TopoDS_Shape>::Iterator aStartIt(WES.StartElements()); aStartIt.More();
|
||||
aStartIt.Next())
|
||||
{
|
||||
if (E.IsSame(aStartIt.Value()))
|
||||
{
|
||||
isAlreadyAdded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isAlreadyAdded)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// modified by NIZHNY-MZV Fri Mar 17 12:51:03 2000
|
||||
if (BRep_Tool::Degenerated(E))
|
||||
{
|
||||
@@ -221,7 +257,7 @@ void TopOpeBRepBuild_Builder::GFillCurveTopologyWES(const TopOpeBRepDS_CurveIter
|
||||
// modified by NIZHNY-MZV Mon Mar 27 15:24:39 2000
|
||||
if (!EhasPConFTF)
|
||||
{
|
||||
myBuildTool.PCurve(FTF, E, PC);
|
||||
myBuildTool.PCurve(FTF, E, myDataStructure->Curve(iG), PC);
|
||||
}
|
||||
|
||||
bool EhasPConWESF = FC2D_HasCurveOnSurface(E, WESF);
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#include <TopExp.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopOpeBRepBuild_define.hxx>
|
||||
@@ -27,6 +29,8 @@
|
||||
#include <TopOpeBRepTool_ShapeExplorer.hxx>
|
||||
#include <TopOpeBRepTool_TOOL.hxx>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#ifdef OCCT_DEBUG
|
||||
extern void debfillp(const int i);
|
||||
|
||||
@@ -117,7 +121,9 @@ void TopOpeBRepBuild_Builder::GEDBUMakeEdges(const TopoDS_Shape& EF,
|
||||
|
||||
myBuildTool.CopyEdge(EF, newEdge);
|
||||
|
||||
int nVF = 0, nVR = 0; // nb vertex FORWARD,REVERSED
|
||||
int nVF = 0, nVR = 0; // nb vertex FORWARD,REVERSED
|
||||
double aForwardParameter = 0.0;
|
||||
double aReversedParameter = 0.0;
|
||||
|
||||
TopoDS_Shape VF, VR; // gestion du bit Closed
|
||||
VF.Nullify();
|
||||
@@ -180,7 +186,8 @@ void TopOpeBRepBuild_Builder::GEDBUMakeEdges(const TopoDS_Shape& EF,
|
||||
nVF++;
|
||||
if (nVF == 1)
|
||||
{
|
||||
VF = V;
|
||||
VF = V;
|
||||
aForwardParameter = EDBU.Parameter();
|
||||
}
|
||||
}
|
||||
if (Vori == TopAbs_REVERSED)
|
||||
@@ -188,7 +195,8 @@ void TopOpeBRepBuild_Builder::GEDBUMakeEdges(const TopoDS_Shape& EF,
|
||||
nVR++;
|
||||
if (nVR == 1)
|
||||
{
|
||||
VR = V;
|
||||
VR = V;
|
||||
aReversedParameter = EDBU.Parameter();
|
||||
}
|
||||
}
|
||||
if (oriV == TopAbs_INTERNAL)
|
||||
@@ -205,6 +213,12 @@ void TopOpeBRepBuild_Builder::GEDBUMakeEdges(const TopoDS_Shape& EF,
|
||||
bool addedge = (nVF == 1 && nVR == 1);
|
||||
if (addedge)
|
||||
{
|
||||
if (VF.IsSame(VR)
|
||||
&& std::abs(aForwardParameter - aReversedParameter) <= Precision::PConfusion())
|
||||
{
|
||||
BRep_Builder aBuilder;
|
||||
aBuilder.Degenerated(TopoDS::Edge(newEdge), true);
|
||||
}
|
||||
if (tosplit)
|
||||
{
|
||||
NCollection_List<TopoDS_Shape> loe;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <Geom2d_Curve.hxx>
|
||||
#include <Geom2d_Line.hxx>
|
||||
#include <Geom2d_OffsetCurve.hxx>
|
||||
#include <Geom2d_TrimmedCurve.hxx>
|
||||
#include <Geom_BSplineCurve.hxx>
|
||||
#include <Geom_Curve.hxx>
|
||||
#include <Geom_Plane.hxx>
|
||||
@@ -32,6 +33,7 @@
|
||||
#include <Geom_TrimmedCurve.hxx>
|
||||
#include <GeomAPI_ProjectPointOnCurve.hxx>
|
||||
#include <GeomAPI_ProjectPointOnSurf.hxx>
|
||||
#include <GeomLib.hxx>
|
||||
#include <gp.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
@@ -903,10 +905,16 @@ void TopOpeBRepDS_BuildTool::AddEdgeVertex(const TopoDS_Shape& Ein,
|
||||
TopoDS_Shape& Eou,
|
||||
const TopoDS_Shape& V) const
|
||||
{
|
||||
myBuilder.Add(Eou, V);
|
||||
TopoDS_Edge e1 = TopoDS::Edge(Ein);
|
||||
TopoDS_Edge e2 = TopoDS::Edge(Eou);
|
||||
TopoDS_Vertex v1 = TopoDS::Vertex(V);
|
||||
if (e1.Orientation() == TopAbs_REVERSED)
|
||||
{
|
||||
v1.Reverse();
|
||||
}
|
||||
e1.Orientation(TopAbs_FORWARD);
|
||||
e2.Orientation(TopAbs_FORWARD);
|
||||
myBuilder.Add(e2, v1);
|
||||
myBuilder.Transfert(e1, e2, v1, v1);
|
||||
}
|
||||
|
||||
@@ -1250,9 +1258,9 @@ void TopOpeBRepDS_BuildTool::PCurve(TopoDS_Shape& F,
|
||||
TopoDS_Face FF = TopoDS::Face(F);
|
||||
TopoDS_Edge EE = TopoDS::Edge(E);
|
||||
|
||||
const occ::handle<Geom2d_Curve>& PCT = PC;
|
||||
double CDSmin, CDSmax;
|
||||
bool rangedef = CDS.Range(CDSmin, CDSmax);
|
||||
occ::handle<Geom2d_Curve> PCT = PC;
|
||||
double CDSmin, CDSmax;
|
||||
bool rangedef = CDS.Range(CDSmin, CDSmax);
|
||||
|
||||
TopLoc_Location L;
|
||||
double Cf, Cl;
|
||||
@@ -1260,27 +1268,43 @@ void TopOpeBRepDS_BuildTool::PCurve(TopoDS_Shape& F,
|
||||
|
||||
if (!C.IsNull())
|
||||
{
|
||||
bool deca = (std::abs(Cf - CDSmin) > Precision::PConfusion());
|
||||
occ::handle<Geom2d_Line> line2d = occ::down_cast<Geom2d_Line>(PCT);
|
||||
bool isline2d = !line2d.IsNull();
|
||||
bool tran = (rangedef && deca && C->IsPeriodic() && isline2d);
|
||||
if (tran)
|
||||
if (rangedef && (CDS.IsExistingEdgeReversed() || CDS.IsEquivalentCurveReversed()))
|
||||
{
|
||||
TopLoc_Location Loc;
|
||||
const occ::handle<Geom_Surface> Surf = BRep_Tool::Surface(FF, Loc);
|
||||
bool isUperio = Surf->IsUPeriodic();
|
||||
bool isVperio = Surf->IsVPeriodic();
|
||||
gp_Dir2d dir2d = line2d->Direction();
|
||||
double delta;
|
||||
if (isUperio && dir2d.IsParallel(gp::DX2d(), Precision::Angular()))
|
||||
occ::handle<Geom2d_TrimmedCurve> aReversedPCurve =
|
||||
new Geom2d_TrimmedCurve(PCT, CDSmin, CDSmax);
|
||||
aReversedPCurve->Reverse();
|
||||
GeomLib::SameRange(Precision::PConfusion(),
|
||||
aReversedPCurve,
|
||||
aReversedPCurve->FirstParameter(),
|
||||
aReversedPCurve->LastParameter(),
|
||||
Cf,
|
||||
Cl,
|
||||
PCT);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool deca = (std::abs(Cf - CDSmin) > Precision::PConfusion());
|
||||
occ::handle<Geom2d_Line> line2d = occ::down_cast<Geom2d_Line>(PCT);
|
||||
bool isline2d = !line2d.IsNull();
|
||||
bool tran = (rangedef && deca && C->IsPeriodic() && isline2d);
|
||||
if (tran)
|
||||
{
|
||||
delta = (CDSmin - Cf) * dir2d.X();
|
||||
PCT->Translate(gp_Vec2d(delta, 0.));
|
||||
}
|
||||
else if (isVperio && dir2d.IsParallel(gp::DY2d(), Precision::Angular()))
|
||||
{
|
||||
delta = (CDSmin - Cf) * dir2d.Y();
|
||||
PCT->Translate(gp_Vec2d(0., delta));
|
||||
TopLoc_Location Loc;
|
||||
const occ::handle<Geom_Surface> Surf = BRep_Tool::Surface(FF, Loc);
|
||||
bool isUperio = Surf->IsUPeriodic();
|
||||
bool isVperio = Surf->IsVPeriodic();
|
||||
gp_Dir2d dir2d = line2d->Direction();
|
||||
double delta;
|
||||
if (isUperio && dir2d.IsParallel(gp::DX2d(), Precision::Angular()))
|
||||
{
|
||||
delta = (CDSmin - Cf) * dir2d.X();
|
||||
PCT->Translate(gp_Vec2d(delta, 0.));
|
||||
}
|
||||
else if (isVperio && dir2d.IsParallel(gp::DY2d(), Precision::Angular()))
|
||||
{
|
||||
delta = (CDSmin - Cf) * dir2d.Y();
|
||||
PCT->Translate(gp_Vec2d(0., delta));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,6 +147,50 @@ TopoDS_Shape& TopOpeBRepDS_Curve::ChangeShape2()
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void TopOpeBRepDS_Curve::SetExistingEdge(const TopoDS_Edge& theEdge, const bool theIsReversed)
|
||||
{
|
||||
myExistingEdge = theEdge;
|
||||
myIsExistingEdgeReversed = theIsReversed;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
const TopoDS_Edge& TopOpeBRepDS_Curve::ExistingEdge() const
|
||||
{
|
||||
return myExistingEdge;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
bool TopOpeBRepDS_Curve::IsExistingEdgeReversed() const
|
||||
{
|
||||
return myIsExistingEdgeReversed;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void TopOpeBRepDS_Curve::SetEquivalentCurve(const int theCurveIndex, const bool theIsReversed)
|
||||
{
|
||||
myEquivalentCurve = theCurveIndex;
|
||||
myIsEquivalentCurveReversed = theIsReversed;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
int TopOpeBRepDS_Curve::EquivalentCurve() const
|
||||
{
|
||||
return myEquivalentCurve;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
bool TopOpeBRepDS_Curve::IsEquivalentCurveReversed() const
|
||||
{
|
||||
return myIsEquivalentCurveReversed;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
occ::handle<Geom_Curve>& TopOpeBRepDS_Curve::ChangeCurve()
|
||||
{
|
||||
return myCurve;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <Standard_Handle.hxx>
|
||||
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
class Geom_Curve;
|
||||
class TopOpeBRepDS_Interference;
|
||||
@@ -111,6 +112,28 @@ public:
|
||||
|
||||
Standard_EXPORT void ChangeDSIndex(const int I);
|
||||
|
||||
//! Associates this intersection curve with an existing full edge.
|
||||
//! The topology builder uses the edge instead of constructing a duplicate.
|
||||
//! @param[in] theEdge existing edge representing this curve
|
||||
//! @param[in] theIsReversed true if edge parameters run opposite to this curve
|
||||
Standard_EXPORT void SetExistingEdge(const TopoDS_Edge& theEdge,
|
||||
const bool theIsReversed = false);
|
||||
|
||||
Standard_EXPORT const TopoDS_Edge& ExistingEdge() const;
|
||||
|
||||
//! Returns true when the existing edge has the opposite parameter direction to this curve.
|
||||
Standard_EXPORT bool IsExistingEdgeReversed() const;
|
||||
|
||||
//! Sets another intersection curve that represents the same complete boundary.
|
||||
Standard_EXPORT void SetEquivalentCurve(const int theCurveIndex,
|
||||
const bool theIsReversed = false);
|
||||
|
||||
//! Returns the index of an equivalent intersection curve, or zero if there is none.
|
||||
Standard_EXPORT int EquivalentCurve() const;
|
||||
|
||||
//! Returns true when this curve has the opposite parameter direction to its equivalent curve.
|
||||
Standard_EXPORT bool IsEquivalentCurveReversed() const;
|
||||
|
||||
private:
|
||||
occ::handle<Geom_Curve> myCurve;
|
||||
double myFirst;
|
||||
@@ -125,6 +148,10 @@ private:
|
||||
bool myKeep;
|
||||
int myMother;
|
||||
int myDSIndex;
|
||||
TopoDS_Edge myExistingEdge;
|
||||
bool myIsExistingEdgeReversed = false;
|
||||
int myEquivalentCurve = 0;
|
||||
bool myIsEquivalentCurveReversed = false;
|
||||
};
|
||||
|
||||
#endif // _TopOpeBRepDS_Curve_HeaderFile
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include <TopOpeBRepDS_SurfaceData.hxx>
|
||||
#include <TopOpeBRepTool_ShapeTool.hxx>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
TopOpeBRepDS_DataStructure::TopOpeBRepDS_DataStructure()
|
||||
@@ -48,6 +50,7 @@ void TopOpeBRepDS_DataStructure::Init()
|
||||
myNbPoints = 0;
|
||||
mySurfaces.Clear();
|
||||
myCurves.Clear();
|
||||
myEquivalentCurvePoints.Clear();
|
||||
myPoints.Clear();
|
||||
myShapes.Clear();
|
||||
// Begin modified by NIZHNY-MZV Tue Apr 18 16:33:26 2000
|
||||
@@ -184,6 +187,61 @@ void TopOpeBRepDS_DataStructure::ChangeKeepCurve(TopOpeBRepDS_Curve& C, const bo
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
int TopOpeBRepDS_DataStructure::FindEquivalentCurvePoint(const int theCurve,
|
||||
const bool theCurveStart,
|
||||
bool& theRepresentativeStart) const
|
||||
{
|
||||
int aPoint = 2 * theCurve + (theCurveStart ? 0 : 1);
|
||||
while (myEquivalentCurvePoints.IsBound(aPoint) && myEquivalentCurvePoints(aPoint) != aPoint)
|
||||
{
|
||||
aPoint = myEquivalentCurvePoints(aPoint);
|
||||
}
|
||||
theRepresentativeStart = (aPoint % 2 == 0);
|
||||
return aPoint / 2;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void TopOpeBRepDS_DataStructure::MergeEquivalentCurvePoints(const int theFirstCurve,
|
||||
const bool theFirstCurveStart,
|
||||
const int theSecondCurve,
|
||||
const bool theSecondCurveStart)
|
||||
{
|
||||
bool isFirstRootStart = false;
|
||||
bool isSecondRootStart = false;
|
||||
const int aFirstRootCurve =
|
||||
FindEquivalentCurvePoint(theFirstCurve, theFirstCurveStart, isFirstRootStart);
|
||||
const int aSecondRootCurve =
|
||||
FindEquivalentCurvePoint(theSecondCurve, theSecondCurveStart, isSecondRootStart);
|
||||
const int aFirstRoot = 2 * aFirstRootCurve + (isFirstRootStart ? 0 : 1);
|
||||
const int aSecondRoot = 2 * aSecondRootCurve + (isSecondRootStart ? 0 : 1);
|
||||
if (aFirstRoot == aSecondRoot)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const int aRoot = std::min(aFirstRoot, aSecondRoot);
|
||||
const int aChild = std::max(aFirstRoot, aSecondRoot);
|
||||
if (myEquivalentCurvePoints.IsBound(aRoot))
|
||||
{
|
||||
myEquivalentCurvePoints.ChangeFind(aRoot) = aRoot;
|
||||
}
|
||||
else
|
||||
{
|
||||
myEquivalentCurvePoints.Bind(aRoot, aRoot);
|
||||
}
|
||||
if (myEquivalentCurvePoints.IsBound(aChild))
|
||||
{
|
||||
myEquivalentCurvePoints.ChangeFind(aChild) = aRoot;
|
||||
}
|
||||
else
|
||||
{
|
||||
myEquivalentCurvePoints.Bind(aChild, aRoot);
|
||||
}
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
int TopOpeBRepDS_DataStructure::AddPoint(const TopOpeBRepDS_Point& PDS)
|
||||
{
|
||||
myNbPoints++;
|
||||
@@ -1106,6 +1164,42 @@ TopOpeBRepDS_Curve& TopOpeBRepDS_DataStructure::ChangeCurve(const int I)
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
int TopOpeBRepDS_DataStructure::FindEquivalentCurve(const int I, bool& theIsReversed) const
|
||||
{
|
||||
int aRoot = I;
|
||||
theIsReversed = false;
|
||||
while (Curve(aRoot).EquivalentCurve() > 0 && Curve(aRoot).EquivalentCurve() != aRoot)
|
||||
{
|
||||
theIsReversed ^= Curve(aRoot).IsEquivalentCurveReversed();
|
||||
aRoot = Curve(aRoot).EquivalentCurve();
|
||||
}
|
||||
return aRoot;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void TopOpeBRepDS_DataStructure::MergeEquivalentCurves(const int theFirst,
|
||||
const int theSecond,
|
||||
const bool theIsReversed)
|
||||
{
|
||||
bool isFirstReversed = false;
|
||||
bool isSecondReversed = false;
|
||||
const int aFirstRoot = FindEquivalentCurve(theFirst, isFirstReversed);
|
||||
const int aSecondRoot = FindEquivalentCurve(theSecond, isSecondReversed);
|
||||
if (aFirstRoot == aSecondRoot)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const int aReference = aFirstRoot < aSecondRoot ? aFirstRoot : aSecondRoot;
|
||||
const int anEquivalent = aFirstRoot < aSecondRoot ? aSecondRoot : aFirstRoot;
|
||||
const bool isRootReversed = isFirstReversed ^ isSecondReversed ^ theIsReversed;
|
||||
ChangeCurve(aReference).SetEquivalentCurve(aReference, false);
|
||||
ChangeCurve(anEquivalent).SetEquivalentCurve(aReference, isRootReversed);
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
const TopOpeBRepDS_Point& TopOpeBRepDS_DataStructure::Point(const int I) const
|
||||
{
|
||||
if (I < 1 || I > myNbPoints)
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <Standard_Integer.hxx>
|
||||
#include <TopOpeBRepDS_SurfaceData.hxx>
|
||||
#include <NCollection_DataMap.hxx>
|
||||
#include <NCollection_FlatDataMap.hxx>
|
||||
#include <TopOpeBRepDS_CurveData.hxx>
|
||||
#include <TopOpeBRepDS_PointData.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
@@ -85,6 +86,19 @@ public:
|
||||
|
||||
Standard_EXPORT void ChangeKeepCurve(TopOpeBRepDS_Curve& C, const bool FindKeep);
|
||||
|
||||
//! Records that the specified ends of two intersection curves represent
|
||||
//! the same topological point.
|
||||
Standard_EXPORT void MergeEquivalentCurvePoints(const int theFirstCurve,
|
||||
const bool theFirstCurveStart,
|
||||
const int theSecondCurve,
|
||||
const bool theSecondCurveStart);
|
||||
|
||||
//! Returns the representative curve end for the specified curve end.
|
||||
//! The returned curve index is equal to theCurve when no equivalence is recorded.
|
||||
Standard_EXPORT int FindEquivalentCurvePoint(const int theCurve,
|
||||
const bool theCurveStart,
|
||||
bool& theRepresentativeStart) const;
|
||||
|
||||
//! Insert a new point. Returns the index.
|
||||
Standard_EXPORT int AddPoint(const TopOpeBRepDS_Point& PDS);
|
||||
|
||||
@@ -243,6 +257,15 @@ public:
|
||||
//! Returns the Curve of index <I>.
|
||||
Standard_EXPORT TopOpeBRepDS_Curve& ChangeCurve(const int I);
|
||||
|
||||
//! Returns the representative of an equivalent-curve group and reports whether
|
||||
//! the curve parameter direction is reversed relative to that representative.
|
||||
Standard_EXPORT int FindEquivalentCurve(const int I, bool& theIsReversed) const;
|
||||
|
||||
//! Joins two complete coincident curves into one oriented topological boundary.
|
||||
Standard_EXPORT void MergeEquivalentCurves(const int theFirst,
|
||||
const int theSecond,
|
||||
const bool theIsReversed);
|
||||
|
||||
//! Returns the point of index <I>.
|
||||
Standard_EXPORT const TopOpeBRepDS_Point& Point(const int I) const;
|
||||
|
||||
@@ -321,6 +344,7 @@ private:
|
||||
NCollection_DataMap<int, TopOpeBRepDS_SurfaceData> mySurfaces;
|
||||
int myNbCurves;
|
||||
NCollection_DataMap<int, TopOpeBRepDS_CurveData> myCurves;
|
||||
NCollection_FlatDataMap<int, int> myEquivalentCurvePoints;
|
||||
int myNbPoints;
|
||||
NCollection_DataMap<int, TopOpeBRepDS_PointData> myPoints;
|
||||
NCollection_IndexedDataMap<TopoDS_Shape, TopOpeBRepDS_ShapeData, TopTools_ShapeMapHasher>
|
||||
|
||||
Reference in New Issue
Block a user