Loading files
// Created on: 1994-10-04
// Created by: Yves FRICAUD
// Copyright (c) 1994-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepLib.hxx>
#include <BRepMAT2d_Explorer.hxx>
#include <BRepTools_WireExplorer.hxx>
#include <GC_MakeSegment2d.hxx>
#include <Geom2d_BezierCurve.hxx>
#include <Geom2d_BoundedCurve.hxx>
#include <Geom2d_Circle.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom2d_Ellipse.hxx>
#include <Geom2d_Hyperbola.hxx>
#include <Geom2d_Line.hxx>
#include <Geom2d_OffsetCurve.hxx>
#include <Geom2d_Parabola.hxx>
#include <Geom2d_TrimmedCurve.hxx>
#include <Geom2dConvert.hxx>
#include <GeomAbs_CurveType.hxx>
#include <NCollection_Sequence.hxx>
#include <Precision.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Wire.hxx>
#include <TopTools_ShapeMapHasher.hxx>
#include <NCollection_IndexedDataMap.hxx>
//
// Modified by Sergey KHROMOV - Thu Dec 5 10:38:14 2002 Begin
static TopoDS_Edge MakeEdge(const occ::handle<Geom2d_Curve>& theCurve,
const TopoDS_Face& theFace,
const TopoDS_Vertex& theVFirst,
const TopoDS_Vertex& theVLast);
// Modified by Sergey KHROMOV - Thu Dec 5 10:38:16 2002 End
//
static GeomAbs_CurveType GetCurveType(const occ::handle<Geom2d_Curve>& theC2d);
static occ::handle<Geom2d_TrimmedCurve> AdjustCurveEnd(
const occ::handle<Geom2d_BoundedCurve>& theC2d,
const gp_Pnt2d theP,
const bool isFirst);
//
//=================================================================================================
BRepMAT2d_Explorer::BRepMAT2d_Explorer()
{
Clear();
}
//=================================================================================================
BRepMAT2d_Explorer::BRepMAT2d_Explorer(const TopoDS_Face& aFace)
{
Perform(aFace);
}
//=================================================================================================
void BRepMAT2d_Explorer::Perform(const TopoDS_Face& aFace)
{
Clear();
myShape = aFace;
TopoDS_Face F = TopoDS::Face(aFace);
F.Orientation(TopAbs_FORWARD);
TopExp_Explorer Exp(F, TopAbs_WIRE);
// Modified by Sergey KHROMOV - Tue Nov 26 16:10:37 2002 Begin
occ::handle<Geom_Surface> aSurf = BRep_Tool::Surface(F);
TopoDS_Face aNewF = BRepBuilderAPI_MakeFace(aSurf, Precision::Confusion());
while (Exp.More())
{
Add(TopoDS::Wire(Exp.Current()), F, aNewF);
Exp.Next();
}
BRepLib::BuildCurves3d(aNewF);
myModifShapes.Add(aFace, aNewF);
// CheckConnection();
// Modified by Sergey KHROMOV - Tue Nov 26 16:10:38 2002 End
}
//=================================================================================================
void BRepMAT2d_Explorer::Add(const TopoDS_Wire& Spine,
const TopoDS_Face& aFace,
TopoDS_Face& aNewFace)
{
// Modified by skv - Wed Jun 23 12:23:01 2004 Integration Begin
// Taking into account side of bisecting loci construction.
// TopoDS_Wire aWFwd = TopoDS::Wire(Spine.Oriented(TopAbs_FORWARD));
// BRepTools_WireExplorer anExp(aWFwd, aFace);
BRepTools_WireExplorer anExp(Spine, aFace);
// Modified by skv - Wed Jun 23 12:23:02 2004 Integration End
NCollection_IndexedDataMap<TopoDS_Shape, TopoDS_Shape, TopTools_ShapeMapHasher> anOldNewE;
if (!anExp.More())
{
return;
}
// Modified by Sergey KHROMOV - Tue Nov 26 14:25:46 2002 Begin
// This method is totally rewroted to include check
// of connection and creation of a new spine.
NewContour();
myIsClosed(currentContour) = Spine.Closed();
TopoDS_Edge aFirstEdge = anExp.Current();
TopoDS_Edge aPrevEdge = aFirstEdge;
double UFirst, ULast, aD;
occ::handle<Geom2d_Curve> C2d;
occ::handle<Geom2d_TrimmedCurve> CT2d;
occ::handle<Geom2d_TrimmedCurve> aFirstCurve;
gp_Pnt2d aPFirst;
gp_Pnt2d aPLast;
gp_Pnt2d aPCurFirst;
// Modified by skv - Mon Jul 11 19:00:25 2005 Integration Begin
// Set the confusion tolerance in accordance with the further algo
// double aTolConf = Precision::Confusion();
double aTolConf = 1.e-8;
// Modified by skv - Mon Jul 11 19:00:25 2005 Integration End
bool isModif = false;
// Treatment of the first edge of a wire.
anOldNewE.Add(aFirstEdge, aFirstEdge);
C2d = BRep_Tool::CurveOnSurface(aFirstEdge, aFace, UFirst, ULast);
CT2d = new Geom2d_TrimmedCurve(C2d, UFirst, ULast);
if (aFirstEdge.Orientation() == TopAbs_REVERSED)
{
CT2d->Reverse();
}
aPFirst = CT2d->Value(CT2d->FirstParameter());
aPLast = CT2d->Value(CT2d->LastParameter());
Add(CT2d);
aFirstCurve = CT2d;
anExp.Next();
// Treatment of the next edges:
for (; anExp.More(); anExp.Next())
{
const TopoDS_Edge& anEdge = anExp.Current();
anOldNewE.Add(anEdge, anEdge);
C2d = BRep_Tool::CurveOnSurface(anEdge, aFace, UFirst, ULast);
CT2d = new Geom2d_TrimmedCurve(C2d, UFirst, ULast);
if (anEdge.Orientation() == TopAbs_REVERSED)
{
CT2d->Reverse();
}
aPCurFirst = CT2d->Value(CT2d->FirstParameter());
//
aD = aPLast.Distance(aPCurFirst);
if (aD > aTolConf)
{
// There are two ways how to fill holes:
// First, to create a line between these two points.
// Second, create a BSpline curve and to add the last point of the previous
// curve as the first pole of the current one. Second method which
// is worse was performed before and leaved here. Otherwise too much
// code should be rewritten.
isModif = true;
//
int aNbC = theCurves.Value(currentContour).Length();
occ::handle<Geom2d_BoundedCurve> CPrev = occ::down_cast<Geom2d_BoundedCurve>(
theCurves.ChangeValue(currentContour).ChangeValue(aNbC));
//
GeomAbs_CurveType TCPrev = GetCurveType(CPrev);
GeomAbs_CurveType TCCurr = GetCurveType(CT2d);
//
if (TCCurr <= TCPrev)
{
CT2d = AdjustCurveEnd(CT2d, aPLast, true);
// Creation of new edge.
TopoDS_Edge aNewEdge;
TopoDS_Vertex aVf = TopExp::FirstVertex(anEdge);
TopoDS_Vertex aVl = TopExp::LastVertex(anEdge);
if (anEdge.Orientation() == TopAbs_FORWARD)
{
aNewEdge = MakeEdge(CT2d, aNewFace, aVf, aVl);
}
else
{
aNewEdge = MakeEdge(CT2d->Reversed(), aNewFace, aVf, aVl);
}
aNewEdge.Orientation(anEdge.Orientation());
anOldNewE.ChangeFromKey(anEdge) = aNewEdge;
}
else
{
gp_Pnt2d aP = CT2d->Value(CT2d->FirstParameter());
CPrev = AdjustCurveEnd(CPrev, aP, false);
theCurves.ChangeValue(currentContour).ChangeValue(aNbC) = CPrev;
// Change previous edge
TopoDS_Edge aNewEdge;
TopoDS_Vertex aVf = TopExp::FirstVertex(aPrevEdge);
TopoDS_Vertex aVl = TopExp::LastVertex(aPrevEdge);
if (aPrevEdge.Orientation() == TopAbs_FORWARD)
{
aNewEdge = MakeEdge(CPrev, aNewFace, aVf, aVl);
}
else
{
aNewEdge = MakeEdge(CPrev->Reversed(), aNewFace, aVf, aVl);
}
aNewEdge.Orientation(aPrevEdge.Orientation());
anOldNewE.ChangeFromKey(aPrevEdge) = aNewEdge;
}
}
aPLast = CT2d->Value(CT2d->LastParameter());
Add(CT2d);
aPrevEdge = anEdge;
}
// Check of the distance between the first and the last point of wire
// if the wire is closed.
if (myIsClosed(currentContour) && aPLast.Distance(aPFirst) > aTolConf)
{
isModif = true;
//
int aNbC = theCurves.Value(currentContour).Length();
occ::handle<Geom2d_BoundedCurve> CPrev =
occ::down_cast<Geom2d_BoundedCurve>(theCurves.ChangeValue(currentContour).ChangeValue(aNbC));
//
GeomAbs_CurveType TCPrev = GetCurveType(CPrev);
GeomAbs_CurveType TCCurr = GetCurveType(aFirstCurve);
//
if (TCCurr <= TCPrev)
{
aFirstCurve = AdjustCurveEnd(aFirstCurve, aPLast, true);
theCurves.ChangeValue(currentContour).ChangeValue(1) = aFirstCurve;
// Creation of new edge.
TopoDS_Edge aNewEdge;
TopoDS_Vertex aVf = TopExp::FirstVertex(aFirstEdge);
TopoDS_Vertex aVl = TopExp::LastVertex(aFirstEdge);
if (aFirstEdge.Orientation() == TopAbs_FORWARD)
{
aNewEdge = MakeEdge(aFirstCurve, aNewFace, aVf, aVl);
}
else
{
aNewEdge = MakeEdge(aFirstCurve->Reversed(), aNewFace, aVf, aVl);
}
aNewEdge.Orientation(aFirstEdge.Orientation());
anOldNewE.ChangeFromKey(aFirstEdge) = aNewEdge;
}
else
{
gp_Pnt2d aP = aFirstCurve->Value(aFirstCurve->FirstParameter());
CPrev = AdjustCurveEnd(CPrev, aP, false);
theCurves.ChangeValue(currentContour).ChangeValue(aNbC) = CPrev;
// Change previous edge
TopoDS_Edge aNewEdge;
TopoDS_Vertex aVf = TopExp::FirstVertex(aPrevEdge);
TopoDS_Vertex aVl = TopExp::LastVertex(aPrevEdge);
if (aPrevEdge.Orientation() == TopAbs_FORWARD)
{
aNewEdge = MakeEdge(CPrev, aNewFace, aVf, aVl);
}
else
{
aNewEdge = MakeEdge(CPrev->Reversed(), aNewFace, aVf, aVl);
}
aNewEdge.Orientation(aPrevEdge.Orientation());
anOldNewE.ChangeFromKey(aPrevEdge) = aNewEdge;
}
}
TopoDS_Wire aNewWire;
BRep_Builder aBuilder;
if (isModif)
{
int i;
int aNbEdges = anOldNewE.Extent();
aBuilder.MakeWire(aNewWire);
for (i = 1; i <= aNbEdges; i++)
{
const TopoDS_Shape& aKey = anOldNewE.FindKey(i);
const TopoDS_Shape& aNewEdge = anOldNewE.FindFromIndex(i);
aBuilder.Add(aNewWire, aNewEdge);
myModifShapes.Add(aKey, aNewEdge);
}
if (myIsClosed(currentContour))
{
aNewWire.Closed(true);
}
// Modified by skv - Fri Nov 12 17:22:12 2004 Integration Begin
// The orientation of wire is already taken into account.
// aNewWire.Orientation(Spine.Orientation());
// Modified by skv - Fri Nov 12 17:22:12 2004 Integration End
myModifShapes.Add(Spine, aNewWire);
}
else
{
aNewWire = Spine;
}
aBuilder.Add(aNewFace, aNewWire);
// Modified by Sergey KHROMOV - Tue Nov 26 14:25:53 2002 End
}
//=================================================================================================
// Modified by Sergey KHROMOV - Tue Nov 26 17:21:44 2002 Begin
// void BRepMAT2d_Explorer::CheckConnection()
// {
// for (int i = 1; i <= theCurves.Length(); i++)
// for (int j = 2; j <= theCurves(i).Length(); j++)
// {
// gp_Pnt2d P1 = theCurves(i)(j-1)->Value( theCurves(i)(j-1)->LastParameter() );
// gp_Pnt2d P2 = theCurves(i)(j)->Value( theCurves(i)(j)->FirstParameter() );
// if (P1.Distance( P2 ) > Precision::Confusion())
// {
// Handle( Geom2d_BSplineCurve ) BCurve;
// if (theCurves(i)(j)->DynamicType() != STANDARD_TYPE(Geom2d_BSplineCurve))
// BCurve = Geom2dConvert::CurveToBSplineCurve( theCurves(i)(j) );
// else
// BCurve = Handle( Geom2d_BSplineCurve )::DownCast( theCurves(i)(j) );
// BCurve->SetPole( 1, P1 );
// theCurves(i)(j) = new Geom2d_TrimmedCurve( BCurve, BCurve->FirstParameter(),
// BCurve->LastParameter() );
// }
// }
// }
// Modified by Sergey KHROMOV - Tue Nov 26 17:21:29 2002 End
//=================================================================================================
void BRepMAT2d_Explorer::Clear()
{
theCurves.Clear();
currentContour = 0;
// Modified by Sergey KHROMOV - Wed Mar 6 16:07:55 2002 Begin
myIsClosed.Clear();
myModifShapes.Clear();
// Modified by Sergey KHROMOV - Wed Mar 6 16:07:55 2002 End
}
//=================================================================================================
void BRepMAT2d_Explorer::NewContour()
{
NCollection_Sequence<occ::handle<Geom2d_Curve>> Contour;
theCurves.Append(Contour);
// Modified by Sergey KHROMOV - Wed Mar 6 16:12:05 2002 Begin
myIsClosed.Append(false);
// Modified by Sergey KHROMOV - Wed Mar 6 16:12:05 2002 End
currentContour++;
}
//=================================================================================================
void BRepMAT2d_Explorer::Add(const occ::handle<Geom2d_Curve>& aCurve)
{
theCurves.ChangeValue(currentContour).Append(aCurve);
}
//=================================================================================================
int BRepMAT2d_Explorer::NumberOfContours() const
{
return theCurves.Length();
}
//=================================================================================================
int BRepMAT2d_Explorer::NumberOfCurves(const int IndexContour) const
{
return theCurves.Value(IndexContour).Length();
}
//=================================================================================================
void BRepMAT2d_Explorer::Init(const int IndexContour)
{
currentContour = IndexContour;
current = 1;
}
//=================================================================================================
bool BRepMAT2d_Explorer::More() const
{
return (current <= NumberOfCurves(currentContour));
}
//=================================================================================================
void BRepMAT2d_Explorer::Next()
{
current++;
}
//=================================================================================================
occ::handle<Geom2d_Curve> BRepMAT2d_Explorer::Value() const
{
return theCurves.Value(currentContour).Value(current);
}
//=================================================================================================
TopoDS_Shape BRepMAT2d_Explorer::Shape() const
{
return myShape;
}
//=================================================================================================
const NCollection_Sequence<occ::handle<Geom2d_Curve>>& BRepMAT2d_Explorer::Contour(
const int IC) const
{
return theCurves.Value(IC);
}
// Modified by Sergey KHROMOV - Wed Mar 6 17:40:07 2002 Begin
//=================================================================================================
bool BRepMAT2d_Explorer::IsModified(const TopoDS_Shape& aShape) const
{
if (myModifShapes.Contains(aShape))
{
const TopoDS_Shape& aNewShape = myModifShapes.FindFromKey(aShape);
const bool isSame = aNewShape.IsSame(aShape);
return !isSame;
}
return false;
}
//=================================================================================================
TopoDS_Shape BRepMAT2d_Explorer::ModifiedShape(const TopoDS_Shape& aShape) const
{
if (myModifShapes.Contains(aShape))
{
const TopoDS_Shape& aNewShape = myModifShapes.FindFromKey(aShape);
return aNewShape;
}
return aShape;
}
//=================================================================================================
const NCollection_Sequence<bool>& BRepMAT2d_Explorer::GetIsClosed() const
{
return myIsClosed;
}
//=======================================================================
// function : MakeEdge
// purpose : Creation of an edge by 2d curve, face and two vertices.
//=======================================================================
TopoDS_Edge MakeEdge(const occ::handle<Geom2d_Curve>& theCurve,
const TopoDS_Face& theFace,
const TopoDS_Vertex& theVFirst,
const TopoDS_Vertex& theVLast)
{
TopoDS_Edge aNewEdge;
BRep_Builder aBuilder;
constexpr double aTol = Precision::Confusion();
double aFPar = theCurve->FirstParameter();
double aLPar = theCurve->LastParameter();
aBuilder.MakeEdge(aNewEdge);
aBuilder.UpdateEdge(aNewEdge, theCurve, theFace, aTol);
aBuilder.Add(aNewEdge, theVFirst.Oriented(TopAbs_FORWARD));
aBuilder.Add(aNewEdge, theVLast.Oriented(TopAbs_REVERSED));
aBuilder.Range(aNewEdge, aFPar, aLPar);
return aNewEdge;
}
// Modified by Sergey KHROMOV - Wed Mar 6 17:40:14 2002 End
//
//=================================================================================================
GeomAbs_CurveType GetCurveType(const occ::handle<Geom2d_Curve>& theC2d)
{
GeomAbs_CurveType aTypeCurve = GeomAbs_OtherCurve;
occ::handle<Standard_Type> TheType = theC2d->DynamicType();
if (TheType == STANDARD_TYPE(Geom2d_TrimmedCurve))
{
TheType = occ::down_cast<Geom2d_TrimmedCurve>(theC2d)->BasisCurve()->DynamicType();
}
if (TheType == STANDARD_TYPE(Geom2d_Circle))
{
aTypeCurve = GeomAbs_Circle;
}
else if (TheType == STANDARD_TYPE(Geom2d_Line))
{
aTypeCurve = GeomAbs_Line;
}
else if (TheType == STANDARD_TYPE(Geom2d_Ellipse))
{
aTypeCurve = GeomAbs_Ellipse;
}
else if (TheType == STANDARD_TYPE(Geom2d_Parabola))
{
aTypeCurve = GeomAbs_Parabola;
}
else if (TheType == STANDARD_TYPE(Geom2d_Hyperbola))
{
aTypeCurve = GeomAbs_Hyperbola;
}
else if (TheType == STANDARD_TYPE(Geom2d_BezierCurve))
{
aTypeCurve = GeomAbs_BezierCurve;
}
else if (TheType == STANDARD_TYPE(Geom2d_BSplineCurve))
{
aTypeCurve = GeomAbs_BSplineCurve;
}
else if (TheType == STANDARD_TYPE(Geom2d_OffsetCurve))
{
aTypeCurve = GeomAbs_OffsetCurve;
}
else
{
aTypeCurve = GeomAbs_OtherCurve;
}
return aTypeCurve;
}
//=================================================================================================
occ::handle<Geom2d_TrimmedCurve> AdjustCurveEnd(const occ::handle<Geom2d_BoundedCurve>& theC2d,
const gp_Pnt2d theP,
const bool isFirst)
{
GeomAbs_CurveType aType = GetCurveType(theC2d);
if (aType == GeomAbs_Line)
{
// create new line
if (isFirst)
{
gp_Pnt2d aP = theC2d->Value(theC2d->LastParameter());
return GC_MakeSegment2d(theP, aP);
}
else
{
gp_Pnt2d aP = theC2d->Value(theC2d->FirstParameter());
return GC_MakeSegment2d(aP, theP);
}
}
else
{
// Convert to BSpline and adjust first pole
occ::handle<Geom2d_BSplineCurve> BCurve =
Geom2dConvert::CurveToBSplineCurve(theC2d, Convert_QuasiAngular);
if (isFirst)
{
BCurve->SetPole(1, theP);
return new Geom2d_TrimmedCurve(BCurve, BCurve->FirstParameter(), BCurve->LastParameter());
}
else
{
BCurve->SetPole(BCurve->NbPoles(), theP);
return new Geom2d_TrimmedCurve(BCurve, BCurve->FirstParameter(), BCurve->LastParameter());
}
}
}
f2929057eThis file is pinned to the selected release. Download the original to open it in your design tool.