#include <TopTools_DataMapOfShapeShape.hxx>
#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
#include <TopTools_DataMapIteratorOfDataMapOfShapeReal.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
#include <TColStd_ListIteratorOfListOfInteger.hxx>
#include <Standard_NotImplemented.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <BRepAdaptor_Curve2d.hxx>
-#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
#include <Geom_SphericalSurface.hxx>
#include <TopoDS_Wire.hxx>
#include <BRepTools_Substitution.hxx>
#include <IntTools_FClass2d.hxx>
#include <BRepLib_FindSurface.hxx>
+#include <BOPAlgo_PaveFiller.hxx>
+#include <BOPAlgo_Builder.hxx>
+#include <BOPAlgo_MakerVolume.hxx>
+
+#include <BOPCol_ListOfShape.hxx>
+#include <BOPCol_DataMapOfShapeShape.hxx>
+#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
+
+#include <BOPTools.hxx>
+#include <BOPTools_AlgoTools3D.hxx>
+#include <BOPTools_AlgoTools.hxx>
+
+#include <IntTools_Context.hxx>
+#include <IntTools_ShrunkRange.hxx>
+
+#include <CPnts_AbscissaPoint.hxx>
+
// POP for NT
#include <stdio.h>
#endif
-static void UpdateTolerance ( TopoDS_Shape& myShape,
- const TopTools_IndexedMapOfShape& myFaces);
-
-
-static Standard_Boolean FindParameter(const TopoDS_Vertex& V,
- const TopoDS_Edge& E,
- Standard_Real& U)
-{
- // Search the vertex in the edge
-
- Standard_Boolean rev = Standard_False;
- TopoDS_Shape VF;
- TopAbs_Orientation orient = TopAbs_INTERNAL;
-
- TopoDS_Iterator itv(E.Oriented(TopAbs_FORWARD));
-
- // if the edge has no vertices
- // and is degenerated use the vertex orientation
- // RLE, june 94
-
- if (!itv.More() && BRep_Tool::Degenerated(E)) {
- orient = V.Orientation();
- }
-
- while (itv.More()) {
- const TopoDS_Shape& Vcur = itv.Value();
- if (V.IsSame(Vcur)) {
- if (VF.IsNull()) {
- VF = Vcur;
- }
- else {
- rev = E.Orientation() == TopAbs_REVERSED;
- if (Vcur.Orientation() == V.Orientation()) {
- VF = Vcur;
- }
- }
- }
- itv.Next();
- }
-
- if (!VF.IsNull()) orient = VF.Orientation();
-
- Standard_Real f,l;
-
- if (orient == TopAbs_FORWARD) {
- BRep_Tool::Range(E,f,l);
- //return (rev) ? l : f;
- U = (rev) ? l : f;
- return Standard_True;
- }
-
- else if (orient == TopAbs_REVERSED) {
- BRep_Tool::Range(E,f,l);
- //return (rev) ? f : l;
- U = (rev) ? f : l;
- return Standard_True;
- }
-
- else {
- TopLoc_Location L;
- const Handle(Geom_Curve)& C = BRep_Tool::Curve(E,L,f,l);
- L = L.Predivided(V.Location());
- if (!C.IsNull() || BRep_Tool::Degenerated(E)) {
- BRep_ListIteratorOfListOfPointRepresentation itpr
- ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
-
- while (itpr.More()) {
- const Handle(BRep_PointRepresentation)& pr = itpr.Value();
- if (pr->IsPointOnCurve(C,L)) {
- Standard_Real p = pr->Parameter();
- Standard_Real res = p;// SVV 4 nov 99 - to avoid warnings on Linux
- if (!C.IsNull()) {
- // Closed curves RLE 16 june 94
- if (Precision::IsNegativeInfinite(f))
- {
- //return pr->Parameter();//p;
- U = pr->Parameter();
- return Standard_True;
- }
- if (Precision::IsPositiveInfinite(l))
- {
- //return pr->Parameter();//p;
- U = pr->Parameter();
- return Standard_True;
- }
- gp_Pnt Pf = C->Value(f).Transformed(L.Transformation());
- gp_Pnt Pl = C->Value(l).Transformed(L.Transformation());
- Standard_Real tol = BRep_Tool::Tolerance(V);
- if (Pf.Distance(Pl) < tol) {
- if (Pf.Distance(BRep_Tool::Pnt(V)) < tol) {
- if (V.Orientation() == TopAbs_FORWARD) res = f;//p = f;
- else res = l;//p = l;
- }
- }
- }
- //return res;//p;
- U = res;
- return Standard_True;
- }
- itpr.Next();
- }
- }
- else {
- // no 3d curve !!
- // let us try with the first pcurve
- Handle(Geom2d_Curve) PC;
- Handle(Geom_Surface) S;
- BRep_Tool::CurveOnSurface(E,PC,S,L,f,l);
- L = L.Predivided(V.Location());
- BRep_ListIteratorOfListOfPointRepresentation itpr
- ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
-
- while (itpr.More()) {
- const Handle(BRep_PointRepresentation)& pr = itpr.Value();
- if (pr->IsPointOnCurveOnSurface(PC,S,L)) {
- Standard_Real p = pr->Parameter();
- // Closed curves RLE 16 june 94
- if (PC->IsClosed()) {
- if ((p == PC->FirstParameter()) ||
- (p == PC->LastParameter())) {
- if (V.Orientation() == TopAbs_FORWARD) p = PC->FirstParameter();
- else p = PC->LastParameter();
- }
- }
- //return p;
- U = p;
- return Standard_True;
- }
- itpr.Next();
- }
- }
- }
-
- //Standard_NoSuchObject::Raise("BRep_Tool:: no parameter on edge");
- return Standard_False;
-}
-
//=======================================================================
-//function : GetEdgePoints
-//purpose : gets the first, last and middle points of the edge
+// static methods
//=======================================================================
-static void GetEdgePoints(const TopoDS_Edge& anEdge,
- const TopoDS_Face& aFace,
- gp_Pnt& fPnt, gp_Pnt& mPnt,
- gp_Pnt& lPnt)
-{
- Standard_Real f, l;
- Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( anEdge, aFace, f, l );
- gp_Pnt2d fPnt2d = theCurve->Value(f);
- gp_Pnt2d lPnt2d = theCurve->Value(l);
- gp_Pnt2d mPnt2d = theCurve->Value(0.5*(f + l));
- Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
- fPnt = aSurf->Value(fPnt2d.X(),fPnt2d.Y());
- lPnt = aSurf->Value(lPnt2d.X(),lPnt2d.Y());
- mPnt = aSurf->Value(mPnt2d.X(), mPnt2d.Y());
-}
+static
+ void UpdateTolerance(TopoDS_Shape& myShape,
+ const TopTools_IndexedMapOfShape& myFaces);
+
+static
+ Standard_Boolean FindParameter(const TopoDS_Vertex& V,
+ const TopoDS_Edge& E,
+ Standard_Real& U);
+
+static
+ void GetEdgePoints(const TopoDS_Edge& anEdge,
+ const TopoDS_Face& aFace,
+ gp_Pnt& fPnt, gp_Pnt& mPnt,
+ gp_Pnt& lPnt);
+
+static
+ void FillContours(const TopoDS_Shape& aShape,
+ const BRepOffset_Analyse& Analyser,
+ TopTools_DataMapOfShapeListOfShape& Contours,
+ TopTools_DataMapOfShapeShape& MapEF);
+
+static
+ void RemoveCorks(TopoDS_Shape& S,
+ TopTools_IndexedMapOfShape& Faces);
+
+static
+ Standard_Boolean IsConnectedShell(const TopoDS_Shape& S);
+
+static
+ void MakeList(TopTools_ListOfShape& OffsetFaces,
+ const BRepAlgo_Image& myInitOffsetFace,
+ const TopTools_IndexedMapOfShape& myFaces);
+
+static
+ void EvalMax(const TopoDS_Shape& S,
+ Standard_Real& Tol);
+
+static
+ void TrimEdge(TopoDS_Edge& NE,
+ const Handle(BRepAlgo_AsDes)& AsDes2d,
+ Handle(BRepAlgo_AsDes)& AsDes);
+
+static
+ void SortFaces(const TopTools_ListOfShape& theLIm,
+ TopTools_ListOfShape& theLFImages,
+ const Standard_Boolean bKeepFirst);
+
+static
+ Standard_Boolean FindShape(const TopoDS_Shape& theSWhat,
+ const TopoDS_Shape& theSWhere,
+ TopoDS_Shape& theRes);
+
+static
+ void UpdateOrigins(TopTools_IndexedDataMapOfShapeListOfShape& theOrigins,
+ BOPAlgo_Builder& theGF);
+
+static
+ Standard_Boolean IsMicroEdge(const TopoDS_Edge& theEdge,
+ const Handle(IntTools_Context)& theCtx,
+ Standard_Real& theFuzz);
+
+static
+ Standard_Boolean ComputeBiNormal(const TopoDS_Face& theF,
+ const TopoDS_Edge& theE,
+ gp_Dir& theDB);
+static
+ Standard_Boolean CheckBiNormals(const TopoDS_Face& aFIm,
+ const TopoDS_Face& aFOr,
+ const TopTools_IndexedDataMapOfShapeListOfShape& theOrigins,
+ const TopTools_MapOfShape& theMFence,
+ Standard_Boolean& bKeep,
+ Standard_Boolean& bRem);
+
+static
+ void CheckBiNormals(TopTools_ListOfShape& theLFImages,
+ const TopoDS_Face& theF,
+ const TopTools_IndexedDataMapOfShapeListOfShape& theOrigins,
+ TopTools_ListOfShape& theLFKeep);
+
+static
+ Standard_Boolean CheckNormals(const TopoDS_Face& theFIm,
+ const TopoDS_Face& theFOr);
+
+static
+ void UpdateInitOffset(BRepAlgo_Image& myInitOffset,
+ BRepAlgo_Image& myImageOffset,
+ const TopoDS_Shape& myOffsetShape,
+ const TopAbs_ShapeEnum &theShapeType);
//=======================================================================
-//function : FillContours
-//purpose : fills free boundary contours and faces connected (MapEF)
-//=======================================================================
-static void FillContours(const TopoDS_Shape& aShape,
- const BRepOffset_Analyse& Analyser,
- TopTools_DataMapOfShapeListOfShape& Contours,
- TopTools_DataMapOfShapeShape& MapEF)
-{
- TopTools_ListOfShape Edges;
-
- TopExp_Explorer Explo(aShape, TopAbs_FACE);
- BRepTools_WireExplorer Wexp;
-
- for (; Explo.More(); Explo.Next())
- {
- TopoDS_Face aFace = TopoDS::Face(Explo.Current());
- TopoDS_Iterator itf(aFace);
- for (; itf.More(); itf.Next())
- {
- TopoDS_Wire aWire = TopoDS::Wire(itf.Value());
- for (Wexp.Init(aWire, aFace); Wexp.More(); Wexp.Next())
- {
- TopoDS_Edge anEdge = Wexp.Current();
- if (BRep_Tool::Degenerated(anEdge))
- continue;
- const BRepOffset_ListOfInterval& Lint = Analyser.Type(anEdge);
- if (!Lint.IsEmpty() && Lint.First().Type() == BRepOffset_FreeBoundary)
- {
- MapEF.Bind(anEdge, aFace);
- Edges.Append(anEdge);
- }
- }
- }
- }
- TopTools_ListIteratorOfListOfShape itl;
- while (!Edges.IsEmpty())
- {
- TopoDS_Edge StartEdge = TopoDS::Edge(Edges.First());
- Edges.RemoveFirst();
- TopoDS_Vertex StartVertex, CurVertex;
- TopExp::Vertices(StartEdge, StartVertex, CurVertex, Standard_True);
- TopTools_ListOfShape aContour;
- aContour.Append(StartEdge);
- while (!CurVertex.IsSame(StartVertex))
- for (itl.Initialize(Edges); itl.More(); itl.Next())
- {
- TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
- TopoDS_Vertex V1, V2;
- TopExp::Vertices(anEdge, V1, V2);
- if (V1.IsSame(CurVertex) || V2.IsSame(CurVertex))
- {
- aContour.Append(anEdge);
- CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
- Edges.Remove(itl);
- break;
- }
- }
- Contours.Bind(StartVertex, aContour);
- }
-}
//=======================================================================
//function : BRepOffset_MakeOffset
//purpose :
//=======================================================================
-
BRepOffset_MakeOffset::BRepOffset_MakeOffset()
{
myAsDes = new BRepAlgo_AsDes();
}
-
//=======================================================================
//function : BRepOffset_MakeOffset
//purpose :
//=======================================================================
-
BRepOffset_MakeOffset::BRepOffset_MakeOffset(const TopoDS_Shape& S,
const Standard_Real Offset,
const Standard_Real Tol,
MakeOffsetShape();
}
-
//=======================================================================
//function : Initialize
//purpose :
//=======================================================================
-
void BRepOffset_MakeOffset::Initialize(const TopoDS_Shape& S,
const Standard_Real Offset,
const Standard_Real Tol,
Clear();
}
-
//=======================================================================
//function : Clear
//purpose :
//=======================================================================
-
void BRepOffset_MakeOffset::Clear()
{
myOffsetShape.Nullify();
//function : AddFace
//purpose :
//=======================================================================
-
void BRepOffset_MakeOffset::AddFace(const TopoDS_Face& F) {
myFaces.Add(F);
//-------------
//function : SetOffsetOnFace
//purpose :
//=======================================================================
-
void BRepOffset_MakeOffset::SetOffsetOnFace(const TopoDS_Face& F,
const Standard_Real Off)
{
}
//=======================================================================
-//function : RemoveCorks
+//function : MakeOffsetShape
//purpose :
//=======================================================================
-
-static void RemoveCorks (TopoDS_Shape& S,
- TopTools_IndexedMapOfShape& Faces)
-{
- TopoDS_Compound SS;
- BRep_Builder B;
- B.MakeCompound (SS);
- //-----------------------------------------------------
- // Construction of a shape without caps.
- // and Orientation of caps as in shape S.
- //-----------------------------------------------------
- TopExp_Explorer exp(S,TopAbs_FACE);
- for (; exp.More(); exp.Next()) {
- const TopoDS_Shape& Cork = exp.Current();
- if (!Faces.Contains(Cork)) {
- B.Add(SS,Cork);
- }
- else {
- //Faces.Remove (Cork);
- //begin instead of Remove//
- TopoDS_Shape LastShape = Faces(Faces.Extent());
- Faces.RemoveLast();
- if (Faces.FindIndex(Cork) != 0)
- Faces.Substitute(Faces.FindIndex(Cork), LastShape);
- //end instead of Remove //
- Faces.Add(Cork); // to reset it with proper orientation.
- }
- }
- S = SS;
-#ifdef DRAW
- if ( AffichOffC)
- DBRep::Set("myInit", SS);
-#endif
-
-}
-
-static Standard_Boolean IsConnectedShell( const TopoDS_Shape& S )
-{
- BRepTools_Quilt Glue;
- Glue.Add( S );
-
- TopoDS_Shape SS = Glue.Shells();
- TopExp_Explorer Explo( SS, TopAbs_SHELL );
- Explo.Next();
- if (Explo.More())
- return Standard_False;
-
- return Standard_True;
-}
-
-
-//=======================================================================
-//function : MakeList
-//purpose :
-//=======================================================================
-
-static void MakeList (TopTools_ListOfShape& OffsetFaces,
- const BRepAlgo_Image& myInitOffsetFace,
- const TopTools_IndexedMapOfShape& myFaces)
-{
- TopTools_ListIteratorOfListOfShape itLOF(myInitOffsetFace.Roots());
- for ( ; itLOF.More(); itLOF.Next()) {
- const TopoDS_Shape& Root = itLOF.Value();
- if (myInitOffsetFace.HasImage(Root)) {
- if (!myFaces.Contains(Root)) {
- OffsetFaces.Append(myInitOffsetFace.Image(Root).First());
- }
- }
- }
-}
-
-//=======================================================================
-//function : EvalMax
-//purpose :
-//=======================================================================
-
-static void EvalMax(const TopoDS_Shape& S, Standard_Real& Tol)
-{
- TopExp_Explorer exp;
- for (exp.Init(S,TopAbs_VERTEX); exp.More(); exp.Next()) {
- const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current());
- Standard_Real TolV = BRep_Tool::Tolerance(V);
- if (TolV > Tol) Tol = TolV;
- }
- //Patch
- Tol *= 5.;
-}
-
-//=======================================================================
-//function : MakeOffsetShape
-//purpose :
-//=======================================================================
-
-void BRepOffset_MakeOffset::MakeOffsetShape()
+void BRepOffset_MakeOffset::MakeOffsetShape()
{
myDone = Standard_False;
//------------------------------------------
myDone = Standard_True;
}
-
-
//=======================================================================
//function : MakeThickSolid
//purpose :
//=======================================================================
-
void BRepOffset_MakeOffset::MakeThickSolid()
{
//--------------------------------------------------------------
//function : IsDone
//purpose :
//=======================================================================
-
Standard_Boolean BRepOffset_MakeOffset::IsDone() const
{
return myDone;
//function : Error
//purpose :
//=======================================================================
-
BRepOffset_Error BRepOffset_MakeOffset::Error() const
{
return myError;
//function : Shape
//purpose :
//=======================================================================
-
const TopoDS_Shape& BRepOffset_MakeOffset::Shape() const
{
return myOffsetShape;
}
//=======================================================================
-//function : TrimEdge
-//purpose : Trim the edge of the largest of descendants in AsDes2d.
-// Order in AsDes two vertices that have trimmed the edge.
+//function : BuildOffsetByInter
+//purpose :
//=======================================================================
-
-static void TrimEdge (TopoDS_Edge& NE,
- const Handle(BRepAlgo_AsDes)& AsDes2d,
- Handle(BRepAlgo_AsDes)& AsDes)
+void BRepOffset_MakeOffset::BuildOffsetByInter()
{
- Standard_Real aSameParTol = Precision::Confusion();
-
- TopoDS_Vertex V1,V2;
- Standard_Real U = 0.;
- Standard_Real UMin = Precision::Infinite();
- Standard_Real UMax = -UMin;
-
- const TopTools_ListOfShape& LE = AsDes2d->Descendant(NE);
- //
- Standard_Boolean bTrim = Standard_False;
- //
- if (LE.Extent() > 1) {
- TopTools_ListIteratorOfListOfShape it (LE);
- for (; it.More(); it.Next()) {
- TopoDS_Vertex V = TopoDS::Vertex(it.Value());
- if (NE.Orientation() == TopAbs_REVERSED)
- V.Reverse();
- //V.Orientation(TopAbs_INTERNAL);
- if (!FindParameter(V, NE, U)) {
- Standard_Real f, l;
- Handle(Geom_Curve) theCurve = BRep_Tool::Curve(NE, f, l);
- gp_Pnt thePoint = BRep_Tool::Pnt(V);
- GeomAPI_ProjectPointOnCurve Projector(thePoint, theCurve);
- if (Projector.NbPoints() == 0)
- Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge no projection");
- U = Projector.LowerDistanceParameter();
- }
- if (U < UMin) {
- UMin = U; V1 = V;
- }
- if (U > UMax) {
- UMax = U; V2 = V;
- }
- }
- //
- if (V1.IsNull() || V2.IsNull()) {
- Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge");
- }
- if (!V1.IsSame(V2)) {
- NE.Free( Standard_True );
- BRep_Builder B;
- TopAbs_Orientation Or = NE.Orientation();
- NE.Orientation(TopAbs_FORWARD);
- TopoDS_Vertex VF,VL;
- TopExp::Vertices (NE,VF,VL);
- B.Remove(NE,VF);
- B.Remove(NE,VL);
- B.Add (NE,V1.Oriented(TopAbs_FORWARD));
- B.Add (NE,V2.Oriented(TopAbs_REVERSED));
- B.Range(NE,UMin,UMax);
- NE.Orientation(Or);
- AsDes->Add(NE,V1.Oriented(TopAbs_FORWARD));
- AsDes->Add(NE,V2.Oriented(TopAbs_REVERSED));
- BRepLib::SameParameter(NE, aSameParTol, Standard_True);
- //
- bTrim = Standard_True;
- }
+#ifdef OCCT_DEBUG
+ if ( ChronBuild) {
+ cout << " CONSTRUCTION OF OFFSETS :" << endl;
+ Clock.Reset();
+ Clock.Start();
}
- //
- if (!bTrim) {
- if (!BRep_Tool::Degenerated(NE)) {
- BRepAdaptor_Curve aBAC(NE);
- if (!aBAC.IsClosed()) {
- if (AsDes->HasAscendant(NE)) {
- AsDes->Remove(NE);
+#endif
+
+ BRepOffset_DataMapOfShapeOffset MapSF;
+ TopTools_MapOfShape Done;
+ Standard_Boolean OffsetOutside = (myOffset > 0.)? Standard_True : Standard_False;
+ //--------------------------------------------------------
+ // Construction of faces parallel to initial faces
+ //--------------------------------------------------------
+ TopExp_Explorer Exp;
+ TopTools_ListOfShape LF;
+ TopTools_ListIteratorOfListOfShape itLF;
+
+ BRepLib::SortFaces(myShape,LF);
+
+ TopTools_DataMapOfShapeShape ShapeTgt;
+ for (itLF.Initialize(LF); itLF.More(); itLF.Next()) {
+ const TopoDS_Face& F = TopoDS::Face(itLF.Value());
+ Standard_Real CurOffset = myOffset;
+ if (myFaceOffset.IsBound(F)) CurOffset = myFaceOffset(F);
+ BRepOffset_Offset OF(F,CurOffset,ShapeTgt,OffsetOutside,myJoin);
+ TopTools_ListOfShape Let;
+ myAnalyse.Edges(F,BRepOffset_Tangent,Let);
+ TopTools_ListIteratorOfListOfShape itl(Let);
+
+ for ( ; itl.More(); itl.Next()) {
+ const TopoDS_Edge& Cur = TopoDS::Edge(itl.Value());
+ if ( !ShapeTgt.IsBound(Cur)) {
+ TopoDS_Shape aLocalShape = OF.Generated(Cur);
+ const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape);
+// const TopoDS_Edge& OTE = TopoDS::Edge(OF.Generated(Cur));
+ ShapeTgt.Bind(Cur,OF.Generated(Cur));
+ TopoDS_Vertex V1,V2,OV1,OV2;
+ TopExp::Vertices (Cur,V1,V2);
+ TopExp::Vertices (OTE,OV1,OV2);
+ TopTools_ListOfShape LE;
+ if (!ShapeTgt.IsBound(V1)) {
+ myAnalyse.Edges(V1,BRepOffset_Tangent,LE);
+ const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V1);
+ if (LE.Extent() == LA.Extent())
+ ShapeTgt.Bind(V1,OV1);
+ }
+ if (!ShapeTgt.IsBound(V2)) {
+ LE.Clear();
+ myAnalyse.Edges(V2,BRepOffset_Tangent,LE);
+ const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V2);
+ if (LE.Extent() == LA.Extent())
+ ShapeTgt.Bind(V2,OV2);
}
}
}
+ MapSF.Bind(F,OF);
}
-}
+ //--------------------------------------------------------------------
+ // MES : Map of OffsetShape -> Extended Shapes.
+ // Build : Map of Initial SS -> OffsetShape build by Inter.
+ // can be an edge or a compound of edges
+ //---------------------------------------------------------------------
+ TopTools_DataMapOfShapeShape MES;
+ TopTools_DataMapOfShapeShape Build;
+ TopTools_ListOfShape Failed;
+ TopAbs_State Side = TopAbs_IN;
+ Handle(BRepAlgo_AsDes) AsDes = new BRepAlgo_AsDes();
+ //-------------------------------------------------------------------
+ // Extension of faces and calculation of new edges of intersection.
+ //-------------------------------------------------------------------
+ Standard_Boolean ExtentContext = 0;
+ if (myOffset > 0) ExtentContext = 1;
-#include <BOPCol_ListOfShape.hxx>
-#include <BOPAlgo_Builder.hxx>
-#include <BOPAlgo_MakerVolume.hxx>
-#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
-#include <BOPTools.hxx>
-#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
-#include <BOPAlgo_PaveFiller.hxx>
-#include <BOPDS_DS.hxx>
-#include <BOPDS_VectorOfInterfVE.hxx>
-#include <BOPCol_DataMapOfShapeShape.hxx>
-#include <BOPTools_AlgoTools3D.hxx>
-#include <IntTools_Context.hxx>
-#include <BOPTools_AlgoTools.hxx>
-#include <CPnts_AbscissaPoint.hxx>
-#include <IntTools_ShrunkRange.hxx>
+ BRepOffset_Inter3d Inter3 (AsDes,Side,myTol);
+ // Intersection between parallel faces
+ Inter3.ConnexIntByInt(myShape,MapSF,myAnalyse,MES,Build,Failed );
+ // Intersection with caps.
+ Inter3.ContextIntByInt(myFaces,ExtentContext,MapSF,myAnalyse,MES,Build,Failed );
-//=======================================================================
-//function : SortFaces
-//purpose :
-//=======================================================================
-static void SortFaces(const TopTools_ListOfShape& theLIm,
- TopTools_ListOfShape& theLFImages,
- const Standard_Boolean bKeepFirst)
-{
- Standard_Integer bKeep; // 1 - keep; -1 - remove
- Standard_Boolean bFlag;
- TopTools_IndexedDataMapOfShapeListOfShape aDMELF;
- TopTools_ListOfShape aLFKeep, aLFLeft, aLFTmp;
- TopTools_MapOfShape aMV;
- TopTools_ListIteratorOfListOfShape aItLF;
- TopExp_Explorer aExp;
- //
- aLFLeft = theLIm;
- //
- bKeep = bKeepFirst ? 1 : -1;
- for (;;) {
- aLFTmp = aLFLeft;
- //
- aLFLeft.Clear();
- aLFKeep.Clear();
- aDMELF.Clear();
- //
- // map list of images edge - faces
- aItLF.Initialize(aLFTmp);
- for (; aItLF.More(); aItLF.Next()) {
- const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
- TopExp::MapShapesAndAncestors(aFIm, TopAbs_EDGE, TopAbs_FACE, aDMELF);
- }
- //
- // find images that have edge attached to only one face
- aItLF.Initialize(aLFTmp);
- for (; aItLF.More(); aItLF.Next()) {
- const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
- aExp.Init(aFIm, TopAbs_EDGE);
- for (bFlag = Standard_False; aExp.More(); aExp.Next()) {
- const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
- const TopTools_ListOfShape& aLEF = aDMELF.FindFromKey(aE);
- if (aLEF.Extent() == 1) {
- TopoDS_Vertex aV1, aV2;
- TopExp::Vertices(aE, aV1, aV2);
- aMV.Add(aV1);
- aMV.Add(aV2);
- //
- bFlag = Standard_True;
- }
- }
- //
- if (bFlag) {
- aLFKeep.Append(aFIm);
- }
- else {
- aLFLeft.Append(aFIm);
- }
+
+ //---------------------------------------------------------------------------------
+ // Extension of neighbor edges of new edges and intersection between neighbors.
+ //--------------------------------------------------------------------------------
+ Handle(BRepAlgo_AsDes) AsDes2d = new BRepAlgo_AsDes();
+ for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
+ const TopoDS_Face& FI = TopoDS::Face(Exp.Current());
+// Modified by skv - Mon Jan 12 11:50:02 2004 OCC4455 Begin
+// BRepOffset_Inter2d::ConnexIntByInt (FI,MapSF(FI),MES,Build,AsDes2d,myTol);
+ BRepOffset_Inter2d::ConnexIntByInt (FI,MapSF(FI),MES,Build,AsDes,AsDes2d,myOffset, myTol);
+// Modified by skv - Mon Jan 12 11:50:03 2004 OCC4455 End
+ }
+ //-----------------------------------------------------------
+ // Great restriction of new edges and update of AsDes.
+ //------------------------------------------ ----------------
+ TopTools_IndexedMapOfShape NewEdges;
+ TopExp_Explorer Exp2,ExpC;
+ TopoDS_Shape NE;
+ TopoDS_Edge TNE;
+ TopoDS_Face NF;
+ TopTools_IndexedDataMapOfShapeListOfShape anOrigins;
+
+ for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
+ const TopoDS_Face& FI = TopoDS::Face(Exp.Current());
+ NF = MapSF(FI).Face();
+ if (MES.IsBound(NF)) {
+ NF = TopoDS::Face(MES(NF));
}
//
- // map shapes left for processing
- aDMELF.Clear();
- aLFTmp = aLFLeft;
- aLFLeft.Clear();
+ TopTools_MapOfShape View;
+ TopTools_IndexedMapOfShape VEmap;
+ Standard_Integer i, aNb;
//
- aItLF.Initialize(aLFTmp);
- for (; aItLF.More(); aItLF.Next()) {
- const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
- TopExp::MapShapesAndAncestors(aFIm, TopAbs_EDGE, TopAbs_FACE, aDMELF);
- }
+ TopExp::MapShapes(FI.Oriented(TopAbs_FORWARD), TopAbs_EDGE , VEmap);
+ TopExp::MapShapes(FI.Oriented(TopAbs_FORWARD), TopAbs_VERTEX, VEmap);
//
- // find outer edges and check if they touch the first part of edges
- aItLF.Initialize(aLFTmp);
- for (; aItLF.More(); aItLF.Next()) {
- const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
- aExp.Init(aFIm, TopAbs_EDGE);
- for (bFlag = Standard_False; aExp.More() && !bFlag; aExp.Next()) {
- const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
- const TopTools_ListOfShape& aLEF = aDMELF.FindFromKey(aE);
- if (aLEF.Extent() == 1) {
- TopoDS_Vertex aV1, aV2;
- TopExp::Vertices(aE, aV1, aV2);
+ aNb = VEmap.Extent();
+ for (i = 1; i <= aNb; ++i) {
+ const TopoDS_Shape& aS = VEmap(i);
+ if (!View.Add(aS)) {
+ continue;
+ }
+ //
+ if (Build.IsBound(aS)) {
+ NE = Build(aS);
+ if (NE.ShapeType() == TopAbs_EDGE) {
+ if (anOrigins.Contains(NE)) {
+ anOrigins.ChangeFromKey(NE).Append(aS);
+ }
+ else {
+ TopTools_ListOfShape aLSx;
+ aLSx.Append(aS);
+ anOrigins.Add(NE, aLSx);
+ }
//
- bFlag = aMV.Contains(aV1) || aMV.Contains(aV2);
+ if (NewEdges.Add(NE)) {
+ TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);
+ }
+ }
+ else {
+ //------------------------------------------------------------
+ // The Intersections are on several edges.
+ // The pieces without intersections with neighbors
+ // are removed from AsDes.
+ //------------------------------------------------------------
+ for (ExpC.Init(NE,TopAbs_EDGE); ExpC.More(); ExpC.Next()) {
+ TopoDS_Edge NEC = TopoDS::Edge(ExpC.Current());
+ if (NewEdges.Add(NEC)) {
+ NEC.Free(Standard_True);
+ if (anOrigins.Contains(NEC)) {
+ anOrigins.ChangeFromKey(NEC).Append(aS);
+ }
+ else {
+ TopTools_ListOfShape aLSx;
+ aLSx.Append(aS);
+ anOrigins.Add(NEC, aLSx);
+ }
+ //
+ if (!AsDes2d->Descendant(NEC).IsEmpty()) {
+ TrimEdge (NEC,AsDes2d,AsDes);
+ }
+ else {
+ if (AsDes->HasAscendant(NEC)) {
+ AsDes->Remove(NEC);
+ }
+ }
+ }
+ }
}
}
+ else {
+ if (aS.ShapeType() != TopAbs_EDGE) {
+ continue;
+ }
+ //
+ NE = MapSF(FI).Generated(aS);
+ //// modified by jgv, 19.12.03 for OCC4455 ////
+ NE.Orientation(aS.Orientation());
+ if (anOrigins.Contains(NE)) {
+ anOrigins.ChangeFromKey(NE).Append(aS);
+ }
+ else {
+ TopTools_ListOfShape aLSx;
+ aLSx.Append(aS);
+ anOrigins.Add(NE, aLSx);
+ }
+ //
+ if (MES.IsBound(NE)) {
+ NE = MES(NE);
+ NE.Orientation(aS.Orientation());
+ if (NewEdges.Add(NE)) {TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);}
+ }
+ AsDes->Add(NF,NE);
+ }
+ }
+ }
+
+ //---------------------------------
+ // Intersection 2D on //
+ //---------------------------------
+ TopTools_ListOfShape LFE;
+ BRepAlgo_Image IMOE;
+ for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
+ const TopoDS_Shape& FI = Exp.Current();
+ const TopoDS_Shape& OFI = MapSF(FI).Face();
+ if (MES.IsBound(OFI)) {
+ const TopoDS_Face& NF = TopoDS::Face(MES(OFI));
+ LFE.Append(NF);
+ IMOE.SetRoot(NF);
//
- if (bFlag) {
- aLFKeep.Append(aFIm);
+ if (anOrigins.Contains(NF)) {
+ anOrigins.ChangeFromKey(NF).Append(FI);
}
else {
- aLFLeft.Append(aFIm);
- }
- }
- //
- if (bKeep == 1) {
- // aLFKeep should be kept
- // aLFLeft left for further processing
- aItLF.Initialize(aLFKeep);
- for (; aItLF.More(); aItLF.Next()) {
- const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
- theLFImages.Append(aFIm);
+ TopTools_ListOfShape aLSx;
+ aLSx.Append(FI);
+ anOrigins.Add(NF, aLSx);
}
}
- //
- if (aLFLeft.IsEmpty()) {
- break;
- }
- //
- bKeep *= -1;
}
-}
-
-//=======================================================================
-//function : FindShape
-//purpose :
-//=======================================================================
-static Standard_Boolean FindShape(const TopoDS_Shape& theSWhat,
- const TopoDS_Shape& theSWhere,
- TopoDS_Shape& theRes)
-{
- Standard_Boolean bFound = Standard_False;
- TopAbs_ShapeEnum aType = theSWhat.ShapeType();
- TopExp_Explorer aExp(theSWhere, aType);
- for (; aExp.More(); aExp.Next()) {
- const TopoDS_Shape& aS = aExp.Current();
- if (aS.IsSame(theSWhat)) {
- theRes = aS;
- bFound = Standard_True;
- break;
- }
+
+ TopTools_ListIteratorOfListOfShape itLFE(LFE);
+ for (; itLFE.More(); itLFE.Next()) {
+ const TopoDS_Face& NEF = TopoDS::Face(itLFE.Value());
+ BRepOffset_Inter2d::Compute(AsDes,NEF,NewEdges,myTol);
+ }
+ //----------------------------------------------
+ // Intersections 2d on caps.
+ //----------------------------------------------
+ Standard_Integer i;
+ for (i = 1; i <= myFaces.Extent(); i++) {
+ const TopoDS_Face& Cork = TopoDS::Face(myFaces(i));
+ BRepOffset_Inter2d::Compute(AsDes,Cork,NewEdges,myTol);
}
- return bFound;
-}
-//=======================================================================
-//function : ComputeBiNormal
-//purpose :
-//=======================================================================
-static Standard_Boolean ComputeBiNormal(const TopoDS_Face& theF,
- const TopoDS_Edge& theE,
- gp_Dir& theDB)
-{
- Standard_Boolean bDone = Standard_False;
- Standard_Real aT1, aT2, aTm;
+ //-------------------------------
+ // Unwinding of extended Faces.
+ //-------------------------------
//
- const Handle(Geom2d_Curve)& aC2d =
- BRep_Tool::CurveOnSurface(theE, theF, aT1, aT2);
- if (aC2d.IsNull()) {
- return bDone;
+ if ((myJoin == GeomAbs_Intersection) && myInter) {
+ TopTools_ListOfShape aLFailed;
+ BuildSplitsOfFaces(LFE, AsDes, anOrigins, IMOE, aLFailed, Standard_False);
+ if (aLFailed.Extent()) {
+ myMakeLoops.Build(aLFailed, AsDes, IMOE);
+ }
+ }
+ else {
+ myMakeLoops.Build(LFE, AsDes, IMOE);
}
//
- gp_Pnt2d aP2dNear;
- gp_Pnt aP, aPNear;
- //
- const Handle(Geom_Curve)& aC3d =
- BRep_Tool::Curve(theE, aT1, aT2);
- //
- aTm = (aT1 + aT2) * 0.5;
- aP = aC3d->Value(aTm);
- //
- BOPTools_AlgoTools3D::PointNearEdge(theE, theF, aTm, 1.e-5, aP2dNear, aPNear);
- //
- gp_Vec aVB(aP, aPNear);
- theDB = gp_Dir(aVB);
- return !bDone;
-}
-
-//=======================================================================
-//function : UpdateOrigins
-//purpose :
-//=======================================================================
-static void UpdateOrigins(TopTools_IndexedDataMapOfShapeListOfShape& theOrigins,
- BOPAlgo_Builder& theGF)
-{
- TopTools_ListOfShape aLSTmp;
- TopTools_MapOfShape aMFence;
- BOPCol_ListIteratorOfListOfShape aItA;
- TopTools_ListIteratorOfListOfShape aIt, aIt1;
- //
- const BOPCol_ListOfShape& aLSU = theGF.Arguments();
- aItA.Initialize(aLSU);
- for (; aItA.More(); aItA.Next()) {
- const TopoDS_Shape& aS = aItA.Value();
- //
- if (!theOrigins.Contains(aS)) {
- continue;
- }
- //
- const TopTools_ListOfShape& aLSIm = theGF.Modified(aS);
- if (aLSIm.IsEmpty()) {
- continue;
- }
- //
- const TopTools_ListOfShape& aLS = theOrigins.FindFromKey(aS);
- //
- aIt.Initialize(aLSIm);
- for (; aIt.More(); aIt.Next()) {
- const TopoDS_Shape& aSIm = aIt.Value();
- //
- if (!theOrigins.Contains(aSIm)) {
- theOrigins.Add(aSIm, aLS);
- continue;
- }
- //
- aMFence.Clear();
- //
- TopTools_ListOfShape& aLS1 = theOrigins.ChangeFromKey(aSIm);
- aLSTmp.Assign(aLS1);
- //
- aLS1.Clear();
- aIt1.Initialize(aLSTmp);
- for (; aIt1.More(); aIt1.Next()) {
- const TopoDS_Shape& aS1 = aIt1.Value();
- if (aMFence.Add(aS1)) {
- aLS1.Append(aS1);
+#ifdef OCCT_DEBUG
+ TopTools_IndexedMapOfShape COES;
+#endif
+ //---------------------------
+ // MAJ SD. for faces //
+ //---------------------------
+ for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
+ const TopoDS_Shape& FI = Exp.Current();
+ myInitOffsetFace.SetRoot(FI);
+ TopoDS_Face OF = MapSF(FI).Face();
+ if (MES.IsBound(OF)) {
+ OF = TopoDS::Face(MES(OF));
+ if (IMOE.HasImage(OF)) {
+ const TopTools_ListOfShape& LOFE = IMOE.Image(OF);
+ myInitOffsetFace.Bind(FI,LOFE);
+ for (itLF.Initialize(LOFE); itLF.More(); itLF.Next()) {
+ const TopoDS_Shape& OFE = itLF.Value();
+ myImageOffset.SetRoot(OFE);
+#ifdef DRAW
+ if (AffichInt2d) {
+ sprintf(name,"AF_%d",NbAF++);
+ DBRep::Set(name,OFE);
+ }
+#endif
+ TopTools_MapOfShape View;
+ for (Exp2.Init(OFE.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
+ Exp2.More(); Exp2.Next()) {
+ const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current());
+
+ myAsDes->Add (OFE,COE);
+#ifdef DRAW
+ if (AffichInt2d) {
+ sprintf(name,"AE_%d",NbAE++);
+ DBRep::Set(name,COE);
+ COES.Add(COE);
+ }
+#endif
+ if (View.Add(COE)){
+ if (!myAsDes->HasDescendant(COE)) {
+ TopoDS_Vertex CV1,CV2;
+ TopExp::Vertices(COE,CV1,CV2);
+ if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
+ if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
+ }
+ }
+ }
}
}
- //
- aIt1.Initialize(aLS);
- for (; aIt1.More(); aIt1.Next()) {
- const TopoDS_Shape& aS1 = aIt1.Value();
- if (aMFence.Add(aS1)) {
- aLS1.Append(aS1);
+ else {
+ /*myInitOffsetFace.Bind(FI,OF);
+ myImageOffset.SetRoot(OF);
+#ifdef DRAW
+ if (AffichInt2d) {
+ sprintf(name,"AF_%d",NbAF++);
+ DBRep::Set(name,OF);
}
+#endif
+ const TopTools_ListOfShape& LE = AsDes->Descendant(OF);
+ for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) {
+ const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value());
+ if (IMOE.HasImage(OE)) {
+ const TopTools_ListOfShape& LOE = IMOE.Image(OE);
+ TopTools_ListIteratorOfListOfShape itLOE(LOE);
+ for (; itLOE.More(); itLOE.Next()) {
+ TopoDS_Shape aLocalShape = itLOE.Value().Oriented(OE.Orientation());
+ const TopoDS_Edge& COE = TopoDS::Edge(aLocalShape);
+// const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value().Oriented(OE.Orientation()));
+ myAsDes->Add(OF,COE);
+#ifdef DRAW
+ if (AffichInt2d) {
+ sprintf(name,"AE_%d",NbAE++);
+ DBRep::Set(name,COE);
+ COES.Add(COE);
+ }
+#endif
+
+ if (!myAsDes->HasDescendant(COE)) {
+ TopoDS_Vertex CV1,CV2;
+ TopExp::Vertices(COE,CV1,CV2);
+ if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
+ if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
+ }
+ }
+ }
+ else {
+ myAsDes->Add(OF,OE);
+#ifdef DRAW
+ if (AffichInt2d) {
+ sprintf(name,"AE_%d",NbAE++);
+ DBRep::Set(name,OE);
+ COES.Add(OE);
+ }
+#endif
+
+ const TopTools_ListOfShape& LV = AsDes->Descendant(OE);
+ myAsDes->Add(OE,LV);
+ }
+ }*/
}
}
- }
-}
+ else {
+ myInitOffsetFace.Bind(FI,OF);
+ myImageOffset.SetRoot(OF);
+ TopTools_MapOfShape View;
+ for (Exp2.Init(OF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
+ Exp2.More(); Exp2.Next()) {
-//=======================================================================
-//function : IsMicroEdge
-//purpose :
-//=======================================================================
-static Standard_Boolean IsMicroEdge (const TopoDS_Edge& theEdge,
- const Handle(IntTools_Context)& theCtx,
- Standard_Real& theFuzz)
-{
- TopoDS_Vertex aV1, aV2;
- TopExp::Vertices(theEdge, aV1, aV2);
- Standard_Boolean bNull = aV1.IsNull() || aV2.IsNull();
- if (bNull) {
- return Standard_False;
- }
- //
- Standard_Boolean bMicro;
- Standard_Real aT1, aT2;
- IntTools_ShrunkRange aSR;
- //
- BRepAdaptor_Curve aBAC(theEdge);
- //
- aT1 = BRep_Tool::Parameter(aV1, theEdge);
- aT2 = BRep_Tool::Parameter(aV2, theEdge);
- if (aT2 < aT1) {
- Standard_Real aTmp = aT1;
- aT1 = aT2;
- aT2 = aTmp;
- }
- //
- aSR.SetContext(theCtx);
- aSR.SetData(theEdge, aT1, aT2, aV1, aV2);
- aSR.Perform();
- bMicro = (aSR.ErrorStatus() != 0);
- if (!bMicro) {
- Standard_Real anEps, aTS1, aTS2, aTolV1, aTolV2;
- //
- aTolV1 = BRep_Tool::Tolerance(aV1);
- aTolV2 = BRep_Tool::Tolerance(aV2);
- //
- anEps = aBAC.Resolution(aTolV1 + aTolV2);
- if (anEps < 1.e-8) {
- anEps = 1.e-8;
- }
- //
- aSR.ShrunkRange(aTS1, aTS2);
- bMicro = (aTS2 - aTS1) <= anEps;
- }
- //
- if (bMicro) {
- Standard_Real aLen = CPnts_AbscissaPoint::Length(aBAC);
- if (aLen > theFuzz) {
- theFuzz = aLen;
+ const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current());
+ myAsDes->Add (OF,COE);
+#ifdef DRAW
+ if (AffichInt2d) {
+ sprintf(name,"AE_%d",NbAE++);
+ DBRep::Set(name,COE);
+ COES.Add(COE);
+ }
+#endif
+
+ if (View.Add(Exp2.Current())) {
+ if (!myAsDes->HasDescendant(COE)) {
+ TopoDS_Vertex CV1,CV2;
+ TopExp::Vertices(COE,CV1,CV2);
+ if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
+ if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
+ }
+ }
+ }
}
}
- //
- return bMicro;
-}
+ // Modified by skv - Tue Mar 15 16:20:43 2005
+ // Add methods for supporting history.
+ TopTools_MapOfShape aMapEdges;
-//=======================================================================
-//function : BuildSplitsOfFaces
-//purpose :
-//=======================================================================
-void BRepOffset_MakeOffset::BuildSplitsOfFaces
- (const TopTools_ListOfShape& theLF,
- const Handle(BRepAlgo_AsDes)& theAsDes,
- TopTools_IndexedDataMapOfShapeListOfShape& theOrigins,
- BRepAlgo_Image& theImage,
- TopTools_ListOfShape& theLFailed,
- const Standard_Boolean bLimited)
-{
- BOPCol_ListOfShape aLS;
- BOPCol_ListIteratorOfListOfShape aIt;
- TopTools_ListIteratorOfListOfShape aItLF, aItLE, aItLE1;
- TopTools_DataMapOfShapeListOfShape anEImages;
- BRep_Builder aBB;
- TopoDS_Compound aFaces;
- //
+ for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
+ const TopoDS_Shape& aFaceRef = Exp.Current();
+
+ Exp2.Init(aFaceRef.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
+
+ for (; Exp2.More(); Exp2.Next()) {
+ const TopoDS_Shape& anEdgeRef = Exp2.Current();
+
+ if (aMapEdges.Add(anEdgeRef)) {
+ myInitOffsetEdge.SetRoot(anEdgeRef);
+ if (Build.IsBound(anEdgeRef)) {
+ TopoDS_Shape aNewShape = Build(anEdgeRef);
+
+ if (aNewShape.ShapeType() == TopAbs_EDGE) {
+ if (IMOE.HasImage(aNewShape)) {
+ const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewShape);
+
+ myInitOffsetEdge.Bind (anEdgeRef, aListNewE);
+ } else
+ myInitOffsetEdge.Bind (anEdgeRef, aNewShape);
+ } else { // aNewShape != TopAbs_EDGE
+ TopTools_ListOfShape aListNewEdge;
+
+ for (ExpC.Init(aNewShape, TopAbs_EDGE); ExpC.More(); ExpC.Next()) {
+ const TopoDS_Shape &aResEdge = ExpC.Current();
+
+ if (IMOE.HasImage(aResEdge)) {
+ const TopTools_ListOfShape& aListNewE = IMOE.Image(aResEdge);
+ TopTools_ListIteratorOfListOfShape aNewEIter(aListNewE);
+
+ for (; aNewEIter.More(); aNewEIter.Next())
+ aListNewEdge.Append(aNewEIter.Value());
+ } else
+ aListNewEdge.Append(aResEdge);
+ }
+
+ myInitOffsetEdge.Bind (anEdgeRef, aListNewEdge);
+ }
+ }
+ else { // Free boundary.
+ TopoDS_Shape aNewEdge = MapSF(aFaceRef).Generated(anEdgeRef);
+
+ if (MES.IsBound(aNewEdge))
+ aNewEdge = MES(aNewEdge);
+
+ if (IMOE.HasImage(aNewEdge)) {
+ const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewEdge);
+
+ myInitOffsetEdge.Bind (anEdgeRef, aListNewE);
+ } else
+ myInitOffsetEdge.Bind (anEdgeRef, aNewEdge);
+ }
+ }
+ }
+ }
+// Modified by skv - Tue Mar 15 16:20:43 2005
+
+ //---------------------------
+ // MAJ SD. for caps
+ //---------------------------
+ //TopTools_MapOfShape View;
+ for (i = 1; i <= myFaces.Extent(); i++) {
+ const TopoDS_Shape& Cork = myFaces(i);
+ const TopTools_ListOfShape& LE = AsDes->Descendant(Cork);
+ for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) {
+ const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value());
+ if (IMOE.HasImage(OE)) {
+ const TopTools_ListOfShape& LOE = IMOE.Image(OE);
+ TopTools_ListIteratorOfListOfShape itLOE(LOE);
+ for (; itLOE.More(); itLOE.Next()) {
+ const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value());
+ myAsDes->Add(Cork,COE.Oriented(OE.Orientation())) ;
+#ifdef DRAW
+ if (AffichInt2d) {
+ sprintf(name,"AE_%d",NbAE++);
+ DBRep::Set(name,COE);
+ COES.Add(COE);
+ }
+#endif
+
+ if (!myAsDes->HasDescendant(COE)) {
+ TopoDS_Vertex CV1,CV2;
+ TopExp::Vertices(COE,CV1,CV2);
+ if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
+ if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
+ }
+ }
+ }
+ else {
+ myAsDes->Add(Cork,OE);
+ if (AsDes->HasDescendant(OE)) {
+ myAsDes->Add(OE,AsDes->Descendant(OE));
+ }
+#ifdef DRAW
+ if (AffichInt2d) {
+ sprintf(name,"AE_%d",NbAE++);
+ DBRep::Set(name,OE);
+ COES.Add(OE);
+ }
+#endif
+ }
+ }
+ }
+
+#ifdef OCCT_DEBUG
+ DEBVerticesControl (COES,myAsDes);
+ if ( ChronBuild) Clock.Show();
+#endif
+}
+
+//=======================================================================
+//function : BuildSplitsOfFaces
+//purpose :
+//=======================================================================
+void BRepOffset_MakeOffset::BuildSplitsOfFaces
+ (const TopTools_ListOfShape& theLF,
+ const Handle(BRepAlgo_AsDes)& theAsDes,
+ TopTools_IndexedDataMapOfShapeListOfShape& theOrigins,
+ BRepAlgo_Image& theImage,
+ TopTools_ListOfShape& theLFailed,
+ const Standard_Boolean bLimited)
+{
+ BOPCol_ListOfShape aLS;
+ BOPCol_ListIteratorOfListOfShape aIt;
+ TopTools_ListIteratorOfListOfShape aItLF, aItLE, aItLE1;
+ TopTools_DataMapOfShapeListOfShape anEImages;
+ BRep_Builder aBB;
+ TopoDS_Compound aFaces;
+ //
aBB.MakeCompound(aFaces);
//
// firstly it is necessary to fuse all the edges
}
}
//
- // check offset faces on the coincidence of the
- // bi-normal directions with the original faces
- //
UpdateOrigins(theOrigins, aGF);
//
- Standard_Real anAngle;
- Standard_Boolean bRem;
- TopTools_ListOfShape aLFKeep;
- //
- const TopoDS_Face& aFOr = *(TopoDS_Face*)&theOrigins.FindFromKey(aF).First();
- //
- aItLE.Initialize(aLFImages);
- for (; aItLE.More(); ) {
- const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLE.Value();
- const TopoDS_Wire& aWIm = BRepTools::OuterWire(aFIm);
+ if (aLFImages.Extent() > 1) {
+ TopTools_ListOfShape aLFKeep;
//
- bKeep = Standard_True;
- bRem = Standard_True;
+ // check offset faces on the coincidence of the
+ // bi-normal directions with the original faces
+ CheckBiNormals(aLFImages, aF, theOrigins, aLFKeep);
//
- TopExp_Explorer aExp(aWIm, TopAbs_EDGE);
- for (; aExp.More(); aExp.Next()) {
- const TopoDS_Edge& aEIm = *(TopoDS_Edge*)&aExp.Current();
- //
- if (BRep_Tool::Degenerated(aEIm)) {
- continue;
- }
- //
- if (!theOrigins.Contains(aEIm)) {
- continue;
- }
+ // limit the face
+ if (aLFImages.Extent() > 1) {
+ TopTools_ListOfShape aLFTmp = aLFImages;
+ aLFImages.Clear();
//
- const TopTools_ListOfShape& aLEOr = theOrigins.FindFromKey(aEIm);
- const TopoDS_Shape& aSOr = aLEOr.First();
- if (aSOr.ShapeType() != TopAbs_EDGE) {
- bRem = Standard_False;
- break;
+ SortFaces(aLFTmp, aLFImages, Standard_True);
+ }
+ //
+ if (aLFKeep.Extent()) {
+ TopTools_MapOfShape aMFence;
+ aItLE.Initialize(aLFImages);
+ for (; aItLE.More(); aItLE.Next()) {
+ const TopoDS_Shape& aFIm = aItLE.Value();
+ aMFence.Add(aFIm);
}
//
- if (aLEOr.Extent() > 1) {
- TopTools_MapOfShape aME, aMV;
- Standard_Integer aNbE, aNbV;
- //
- TopTools_ListIteratorOfListOfShape aItLS1(aLEOr);
- for (; aItLS1.More(); aItLS1.Next()) {
- const TopoDS_Edge& aEOr = *(TopoDS_Edge*)&aItLS1.Value();
- aME.Add(aEOr);
- //
- TopExp_Explorer aExpE(aEOr, TopAbs_VERTEX);
- for (; aExpE.More(); aExpE.Next()) {
- const TopoDS_Shape& aV = aExpE.Current();
- aMV.Add(aV);
- }
- }
- //
- aNbV = aMV.Extent();
- aNbE = aME.Extent();
- //
- if ((aNbE > 1) && (aNbV == 2*aNbE)) {
- continue;
+ aItLE.Initialize(aLFKeep);
+ for (; aItLE.More(); aItLE.Next()) {
+ const TopoDS_Shape& aFIm = aItLE.Value();
+ if (aMFence.Add(aFIm)) {
+ aLFImages.Append(aFIm);
}
}
- //
- const TopoDS_Shape& aEOr = *(TopoDS_Edge*)&aLEOr.First();
- TopoDS_Edge aEOrF;
- if (!FindShape(aEOr, aFOr, aEOrF)) {
- continue;
- }
- //
- // compute bi-normal for face aFIm on the edge aEIm
- gp_Dir aDB1;
- if (!ComputeBiNormal(aFIm, aEIm, aDB1)) {
- continue;
- }
- //
- // compute bi-normal for face aFOr on the edge aEOrF
- gp_Dir aDB2;
- if (!ComputeBiNormal(aFOr, aEOrF, aDB2)) {
- continue;
- }
- //
- // check coincidence of bi-normals
- anAngle = aDB1.Angle(aDB2);
- if (Abs(anAngle - M_PI) < Precision::Confusion()) {
- bKeep = Standard_False;
- bRem = bRem && Standard_True;
- }
- else {
- bRem = Standard_False;
- }
- //
- if (!bKeep && !bRem) {
- break;
- }
- }
- //
- if (bRem && !bKeep) {
- aLFImages.Remove(aItLE);
- }
- else {
- if (!bRem && bKeep) {
- aLFKeep.Append(aFIm);
- }
- aItLE.Next();
- }
- }
- //
- TopTools_ListOfShape aLFTmp = aLFImages;
- aLFImages.Clear();
- // limit the face
- SortFaces(aLFTmp, aLFImages, Standard_True);
- //
- TopTools_MapOfShape aMFence;
- aItLE.Initialize(aLFImages);
- for (; aItLE.More(); aItLE.Next()) {
- const TopoDS_Shape& aFIm = aItLE.Value();
- aMFence.Add(aFIm);
- }
- //
- aItLE.Initialize(aLFKeep);
- for (; aItLE.More(); aItLE.Next()) {
- const TopoDS_Shape& aFIm = aItLE.Value();
- if (aMFence.Add(aFIm)) {
- aLFImages.Append(aFIm);
}
}
}
}
//=======================================================================
-//function : BuildOffsetByInter
+//function : BuildOffsetByArc
//purpose :
//=======================================================================
-void BRepOffset_MakeOffset::BuildOffsetByInter()
+void BRepOffset_MakeOffset::BuildOffsetByArc()
{
#ifdef OCCT_DEBUG
if ( ChronBuild) {
BRepLib::SortFaces(myShape,LF);
- TopTools_DataMapOfShapeShape ShapeTgt;
+ TopTools_DataMapOfShapeShape EdgeTgt;
for (itLF.Initialize(LF); itLF.More(); itLF.Next()) {
const TopoDS_Face& F = TopoDS::Face(itLF.Value());
Standard_Real CurOffset = myOffset;
if (myFaceOffset.IsBound(F)) CurOffset = myFaceOffset(F);
- BRepOffset_Offset OF(F,CurOffset,ShapeTgt,OffsetOutside,myJoin);
+ BRepOffset_Offset OF(F,CurOffset,EdgeTgt,OffsetOutside,myJoin);
TopTools_ListOfShape Let;
myAnalyse.Edges(F,BRepOffset_Tangent,Let);
TopTools_ListIteratorOfListOfShape itl(Let);
for ( ; itl.More(); itl.Next()) {
const TopoDS_Edge& Cur = TopoDS::Edge(itl.Value());
- if ( !ShapeTgt.IsBound(Cur)) {
+ if ( !EdgeTgt.IsBound(Cur)) {
TopoDS_Shape aLocalShape = OF.Generated(Cur);
const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape);
// const TopoDS_Edge& OTE = TopoDS::Edge(OF.Generated(Cur));
- ShapeTgt.Bind(Cur,OF.Generated(Cur));
+ EdgeTgt.Bind(Cur,OF.Generated(Cur));
TopoDS_Vertex V1,V2,OV1,OV2;
TopExp::Vertices (Cur,V1,V2);
TopExp::Vertices (OTE,OV1,OV2);
TopTools_ListOfShape LE;
- if (!ShapeTgt.IsBound(V1)) {
+ if (!EdgeTgt.IsBound(V1)) {
myAnalyse.Edges(V1,BRepOffset_Tangent,LE);
const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V1);
if (LE.Extent() == LA.Extent())
- ShapeTgt.Bind(V1,OV1);
+ EdgeTgt.Bind(V1,OV1);
}
- if (!ShapeTgt.IsBound(V2)) {
+ if (!EdgeTgt.IsBound(V2)) {
LE.Clear();
myAnalyse.Edges(V2,BRepOffset_Tangent,LE);
const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V2);
if (LE.Extent() == LA.Extent())
- ShapeTgt.Bind(V2,OV2);
+ EdgeTgt.Bind(V2,OV2);
}
}
}
MapSF.Bind(F,OF);
}
- //--------------------------------------------------------------------
- // MES : Map of OffsetShape -> Extended Shapes.
- // Build : Map of Initial SS -> OffsetShape build by Inter.
- // can be an edge or a compound of edges
- //---------------------------------------------------------------------
- TopTools_DataMapOfShapeShape MES;
- TopTools_DataMapOfShapeShape Build;
- TopTools_ListOfShape Failed;
- TopAbs_State Side = TopAbs_IN;
- Handle(BRepAlgo_AsDes) AsDes = new BRepAlgo_AsDes();
-
- //-------------------------------------------------------------------
- // Extension of faces and calculation of new edges of intersection.
- //-------------------------------------------------------------------
- Standard_Boolean ExtentContext = 0;
- if (myOffset > 0) ExtentContext = 1;
-
- BRepOffset_Inter3d Inter3 (AsDes,Side,myTol);
- // Intersection between parallel faces
- Inter3.ConnexIntByInt(myShape,MapSF,myAnalyse,MES,Build,Failed );
- // Intersection with caps.
- Inter3.ContextIntByInt(myFaces,ExtentContext,MapSF,myAnalyse,MES,Build,Failed );
-
-
- //---------------------------------------------------------------------------------
- // Extension of neighbor edges of new edges and intersection between neighbors.
- //--------------------------------------------------------------------------------
- Handle(BRepAlgo_AsDes) AsDes2d = new BRepAlgo_AsDes();
- for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
- const TopoDS_Face& FI = TopoDS::Face(Exp.Current());
-// Modified by skv - Mon Jan 12 11:50:02 2004 OCC4455 Begin
-// BRepOffset_Inter2d::ConnexIntByInt (FI,MapSF(FI),MES,Build,AsDes2d,myTol);
- BRepOffset_Inter2d::ConnexIntByInt (FI,MapSF(FI),MES,Build,AsDes,AsDes2d,myOffset, myTol);
-// Modified by skv - Mon Jan 12 11:50:03 2004 OCC4455 End
- }
- //-----------------------------------------------------------
- // Great restriction of new edges and update of AsDes.
- //------------------------------------------ ----------------
- TopTools_IndexedMapOfShape NewEdges;
- TopExp_Explorer Exp2,ExpC;
- TopoDS_Shape NE;
- TopoDS_Edge TNE;
- TopoDS_Face NF;
- TopTools_IndexedDataMapOfShapeListOfShape anOrigins;
-
- for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
- const TopoDS_Face& FI = TopoDS::Face(Exp.Current());
- NF = MapSF(FI).Face();
- if (MES.IsBound(NF)) {
- NF = TopoDS::Face(MES(NF));
- }
- //
- TopTools_MapOfShape View;
- TopTools_IndexedMapOfShape VEmap;
- Standard_Integer i, aNb;
- //
- TopExp::MapShapes(FI.Oriented(TopAbs_FORWARD), TopAbs_EDGE , VEmap);
- TopExp::MapShapes(FI.Oriented(TopAbs_FORWARD), TopAbs_VERTEX, VEmap);
- //
- aNb = VEmap.Extent();
- for (i = 1; i <= aNb; ++i) {
- const TopoDS_Shape& aS = VEmap(i);
- if (!View.Add(aS)) {
- continue;
- }
- //
- if (Build.IsBound(aS)) {
- NE = Build(aS);
- if (NE.ShapeType() == TopAbs_EDGE) {
- if (anOrigins.Contains(NE)) {
- anOrigins.ChangeFromKey(NE).Append(aS);
- }
- else {
- TopTools_ListOfShape aLSx;
- aLSx.Append(aS);
- anOrigins.Add(NE, aLSx);
- }
- //
- if (NewEdges.Add(NE)) {
- TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);
+ //--------------------------------------------------------
+ // Construction of tubes on edge.
+ //--------------------------------------------------------
+ BRepOffset_Type OT = BRepOffset_Convex;
+ if (myOffset < 0.) OT = BRepOffset_Concave;
+
+ for (Exp.Init(myShape,TopAbs_EDGE); Exp.More(); Exp.Next()) {
+ const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
+ if (Done.Add(E)) {
+ const TopTools_ListOfShape& Anc = myAnalyse.Ancestors(E);
+ if (Anc.Extent() == 2) {
+ const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
+ if (!L.IsEmpty() && L.First().Type() == OT) {
+ Standard_Real CurOffset = myOffset;
+ if ( myFaceOffset.IsBound(Anc.First()))
+ CurOffset = myFaceOffset(Anc.First());
+ TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E);
+ TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape);
+ aLocalShape = MapSF(Anc.Last()).Generated(E);
+ TopoDS_Edge EOn2 = TopoDS::Edge(aLocalShape);
+// TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E));
+// TopoDS_Edge EOn2 = TopoDS::Edge(MapSF(Anc.Last()) .Generated(E));
+ // find if exits tangent edges in the original shape
+ TopoDS_Edge E1f, E1l;
+ TopoDS_Vertex V1f, V1l;
+ TopExp::Vertices(E,V1f,V1l);
+ TopTools_ListOfShape TangE;
+ myAnalyse.TangentEdges(E,V1f,TangE);
+ // find if the pipe on the tangent edges are soon created.
+ TopTools_ListIteratorOfListOfShape itl(TangE);
+ Standard_Boolean Find = Standard_False;
+ for ( ; itl.More() && !Find; itl.Next()) {
+ if ( MapSF.IsBound(itl.Value())) {
+ TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1f);
+ E1f = TopoDS::Edge(aLocalShape);
+// E1f = TopoDS::Edge(MapSF(itl.Value()).Generated(V1f));
+ Find = Standard_True;
+ }
}
- }
- else {
- //------------------------------------------------------------
- // The Intersections are on several edges.
- // The pieces without intersections with neighbors
- // are removed from AsDes.
- //------------------------------------------------------------
- for (ExpC.Init(NE,TopAbs_EDGE); ExpC.More(); ExpC.Next()) {
- TopoDS_Edge NEC = TopoDS::Edge(ExpC.Current());
- if (NewEdges.Add(NEC)) {
- NEC.Free(Standard_True);
- if (anOrigins.Contains(NEC)) {
- anOrigins.ChangeFromKey(NEC).Append(aS);
- }
- else {
- TopTools_ListOfShape aLSx;
- aLSx.Append(aS);
- anOrigins.Add(NEC, aLSx);
- }
- //
- if (!AsDes2d->Descendant(NEC).IsEmpty()) {
- TrimEdge (NEC,AsDes2d,AsDes);
- }
- else {
- if (AsDes->HasAscendant(NEC)) {
- AsDes->Remove(NEC);
- }
- }
+ TangE.Clear();
+ myAnalyse.TangentEdges(E,V1l,TangE);
+ // find if the pipe on the tangent edges are soon created.
+ itl.Initialize(TangE);
+ Find = Standard_False;
+ for ( ; itl.More() && !Find; itl.Next()) {
+ if ( MapSF.IsBound(itl.Value())) {
+ TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1l);
+ E1l = TopoDS::Edge(aLocalShape);
+// E1l = TopoDS::Edge(MapSF(itl.Value()).Generated(V1l));
+ Find = Standard_True;
}
}
+ BRepOffset_Offset OF (E,EOn1,EOn2,CurOffset,E1f, E1l);
+ MapSF.Bind(E,OF);
}
}
else {
- if (aS.ShapeType() != TopAbs_EDGE) {
- continue;
- }
- //
- NE = MapSF(FI).Generated(aS);
- //// modified by jgv, 19.12.03 for OCC4455 ////
- NE.Orientation(aS.Orientation());
- if (anOrigins.Contains(NE)) {
- anOrigins.ChangeFromKey(NE).Append(aS);
- }
- else {
- TopTools_ListOfShape aLSx;
- aLSx.Append(aS);
- anOrigins.Add(NE, aLSx);
- }
- //
- if (MES.IsBound(NE)) {
- NE = MES(NE);
- NE.Orientation(aS.Orientation());
- if (NewEdges.Add(NE)) {TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);}
- }
- AsDes->Add(NF,NE);
- }
+ // ----------------------
+ // free border.
+ // ----------------------
+ TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E);
+ TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape);
+/// TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E));
+ myInitOffsetEdge.SetRoot(E); // skv: supporting history.
+ myInitOffsetEdge.Bind (E,EOn1);
+ }
}
}
-
- //---------------------------------
- // Intersection 2D on //
- //---------------------------------
- TopTools_ListOfShape LFE;
- BRepAlgo_Image IMOE;
- for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
- const TopoDS_Shape& FI = Exp.Current();
- const TopoDS_Shape& OFI = MapSF(FI).Face();
- if (MES.IsBound(OFI)) {
- const TopoDS_Face& NF = TopoDS::Face(MES(OFI));
- LFE.Append(NF);
- IMOE.SetRoot(NF);
- //
- if (anOrigins.Contains(NF)) {
- anOrigins.ChangeFromKey(NF).Append(FI);
+
+ //--------------------------------------------------------
+ // Construction of spheres on vertex.
+ //--------------------------------------------------------
+ Done.Clear();
+ TopTools_ListIteratorOfListOfShape it;
+
+ for (Exp.Init(myShape,TopAbs_VERTEX); Exp.More(); Exp.Next()) {
+ const TopoDS_Vertex& V = TopoDS::Vertex (Exp.Current());
+ if (Done.Add(V)) {
+ const TopTools_ListOfShape& LA = myAnalyse.Ancestors(V);
+ TopTools_ListOfShape LE;
+ myAnalyse.Edges(V,OT,LE);
+
+ if (LE.Extent() >= 3 && LE.Extent() == LA.Extent()) {
+ TopTools_ListOfShape LOE;
+ //--------------------------------------------------------
+ // Return connected edges on tubes.
+ //--------------------------------------------------------
+ for (it.Initialize(LE) ; it.More(); it.Next()) {
+ LOE.Append(MapSF(it.Value()).Generated(V).Reversed());
+ }
+ //----------------------
+ // construction sphere.
+ //-----------------------
+ const TopTools_ListOfShape& LLA = myAnalyse.Ancestors(LA.First());
+ const TopoDS_Shape& FF = LLA.First();
+ Standard_Real CurOffset = myOffset;
+ if ( myFaceOffset.IsBound(FF))
+ CurOffset = myFaceOffset(FF);
+
+ BRepOffset_Offset OF(V,LOE,CurOffset);
+ MapSF.Bind(V,OF);
}
- else {
- TopTools_ListOfShape aLSx;
- aLSx.Append(FI);
- anOrigins.Add(NF, aLSx);
+ //--------------------------------------------------------------
+ // Particular processing if V is at least a free border.
+ //-------------------------------------------------------------
+ TopTools_ListOfShape LBF;
+ myAnalyse.Edges(V,BRepOffset_FreeBoundary,LBF);
+ if (!LBF.IsEmpty()) {
+ Standard_Boolean First = Standard_True;
+ for (it.Initialize(LE) ; it.More(); it.Next()) {
+ if (First) {
+ myInitOffsetEdge.SetRoot(V); // skv: supporting history.
+ myInitOffsetEdge.Bind(V,MapSF(it.Value()).Generated(V));
+ First = Standard_False;
+ }
+ else {
+ myInitOffsetEdge.Add(V,MapSF(it.Value()).Generated(V));
+ }
+ }
}
}
}
-
- TopTools_ListIteratorOfListOfShape itLFE(LFE);
- for (; itLFE.More(); itLFE.Next()) {
- const TopoDS_Face& NEF = TopoDS::Face(itLFE.Value());
- BRepOffset_Inter2d::Compute(AsDes,NEF,NewEdges,myTol);
- }
- //----------------------------------------------
- // Intersections 2d on caps.
- //----------------------------------------------
- Standard_Integer i;
- for (i = 1; i <= myFaces.Extent(); i++) {
- const TopoDS_Face& Cork = TopoDS::Face(myFaces(i));
- BRepOffset_Inter2d::Compute(AsDes,Cork,NewEdges,myTol);
- }
- //-------------------------------
- // Unwinding of extended Faces.
- //-------------------------------
- //
- if ((myJoin == GeomAbs_Intersection) && myInter) {
- TopTools_ListOfShape aLFailed;
- BuildSplitsOfFaces(LFE, AsDes, anOrigins, IMOE, aLFailed, Standard_False);
- if (aLFailed.Extent()) {
- myMakeLoops.Build(aLFailed, AsDes, IMOE);
- }
- }
- else {
- myMakeLoops.Build(LFE, AsDes, IMOE);
- }
- //
-#ifdef OCCT_DEBUG
- TopTools_IndexedMapOfShape COES;
-#endif
- //---------------------------
- // MAJ SD. for faces //
- //---------------------------
- for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
- const TopoDS_Shape& FI = Exp.Current();
- myInitOffsetFace.SetRoot(FI);
- TopoDS_Face OF = MapSF(FI).Face();
- if (MES.IsBound(OF)) {
- OF = TopoDS::Face(MES(OF));
- if (IMOE.HasImage(OF)) {
- const TopTools_ListOfShape& LOFE = IMOE.Image(OF);
- myInitOffsetFace.Bind(FI,LOFE);
- for (itLF.Initialize(LOFE); itLF.More(); itLF.Next()) {
- const TopoDS_Shape& OFE = itLF.Value();
- myImageOffset.SetRoot(OFE);
-#ifdef DRAW
- if (AffichInt2d) {
- sprintf(name,"AF_%d",NbAF++);
- DBRep::Set(name,OFE);
- }
-#endif
- TopTools_MapOfShape View;
- for (Exp2.Init(OFE.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
- Exp2.More(); Exp2.Next()) {
- const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current());
-
- myAsDes->Add (OFE,COE);
-#ifdef DRAW
- if (AffichInt2d) {
- sprintf(name,"AE_%d",NbAE++);
- DBRep::Set(name,COE);
- COES.Add(COE);
- }
-#endif
- if (View.Add(COE)){
- if (!myAsDes->HasDescendant(COE)) {
- TopoDS_Vertex CV1,CV2;
- TopExp::Vertices(COE,CV1,CV2);
- if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
- if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
- }
- }
- }
- }
- }
- else {
- /*myInitOffsetFace.Bind(FI,OF);
- myImageOffset.SetRoot(OF);
-#ifdef DRAW
- if (AffichInt2d) {
- sprintf(name,"AF_%d",NbAF++);
- DBRep::Set(name,OF);
- }
-#endif
- const TopTools_ListOfShape& LE = AsDes->Descendant(OF);
- for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) {
- const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value());
- if (IMOE.HasImage(OE)) {
- const TopTools_ListOfShape& LOE = IMOE.Image(OE);
- TopTools_ListIteratorOfListOfShape itLOE(LOE);
- for (; itLOE.More(); itLOE.Next()) {
- TopoDS_Shape aLocalShape = itLOE.Value().Oriented(OE.Orientation());
- const TopoDS_Edge& COE = TopoDS::Edge(aLocalShape);
-// const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value().Oriented(OE.Orientation()));
- myAsDes->Add(OF,COE);
-#ifdef DRAW
- if (AffichInt2d) {
- sprintf(name,"AE_%d",NbAE++);
- DBRep::Set(name,COE);
- COES.Add(COE);
- }
-#endif
-
- if (!myAsDes->HasDescendant(COE)) {
- TopoDS_Vertex CV1,CV2;
- TopExp::Vertices(COE,CV1,CV2);
- if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
- if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
- }
- }
- }
- else {
- myAsDes->Add(OF,OE);
-#ifdef DRAW
- if (AffichInt2d) {
- sprintf(name,"AE_%d",NbAE++);
- DBRep::Set(name,OE);
- COES.Add(OE);
- }
-#endif
-
- const TopTools_ListOfShape& LV = AsDes->Descendant(OE);
- myAsDes->Add(OE,LV);
- }
- }*/
- }
- }
- else {
- myInitOffsetFace.Bind(FI,OF);
- myImageOffset.SetRoot(OF);
- TopTools_MapOfShape View;
- for (Exp2.Init(OF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
- Exp2.More(); Exp2.Next()) {
-
- const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current());
- myAsDes->Add (OF,COE);
-#ifdef DRAW
- if (AffichInt2d) {
- sprintf(name,"AE_%d",NbAE++);
- DBRep::Set(name,COE);
- COES.Add(COE);
- }
-#endif
-
- if (View.Add(Exp2.Current())) {
- if (!myAsDes->HasDescendant(COE)) {
- TopoDS_Vertex CV1,CV2;
- TopExp::Vertices(COE,CV1,CV2);
- if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
- if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
- }
- }
- }
- }
- }
- // Modified by skv - Tue Mar 15 16:20:43 2005
- // Add methods for supporting history.
- TopTools_MapOfShape aMapEdges;
-
- for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
- const TopoDS_Shape& aFaceRef = Exp.Current();
-
- Exp2.Init(aFaceRef.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
-
- for (; Exp2.More(); Exp2.Next()) {
- const TopoDS_Shape& anEdgeRef = Exp2.Current();
-
- if (aMapEdges.Add(anEdgeRef)) {
- myInitOffsetEdge.SetRoot(anEdgeRef);
- if (Build.IsBound(anEdgeRef)) {
- TopoDS_Shape aNewShape = Build(anEdgeRef);
-
- if (aNewShape.ShapeType() == TopAbs_EDGE) {
- if (IMOE.HasImage(aNewShape)) {
- const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewShape);
-
- myInitOffsetEdge.Bind (anEdgeRef, aListNewE);
- } else
- myInitOffsetEdge.Bind (anEdgeRef, aNewShape);
- } else { // aNewShape != TopAbs_EDGE
- TopTools_ListOfShape aListNewEdge;
-
- for (ExpC.Init(aNewShape, TopAbs_EDGE); ExpC.More(); ExpC.Next()) {
- const TopoDS_Shape &aResEdge = ExpC.Current();
-
- if (IMOE.HasImage(aResEdge)) {
- const TopTools_ListOfShape& aListNewE = IMOE.Image(aResEdge);
- TopTools_ListIteratorOfListOfShape aNewEIter(aListNewE);
-
- for (; aNewEIter.More(); aNewEIter.Next())
- aListNewEdge.Append(aNewEIter.Value());
- } else
- aListNewEdge.Append(aResEdge);
- }
-
- myInitOffsetEdge.Bind (anEdgeRef, aListNewEdge);
- }
- }
- else { // Free boundary.
- TopoDS_Shape aNewEdge = MapSF(aFaceRef).Generated(anEdgeRef);
-
- if (MES.IsBound(aNewEdge))
- aNewEdge = MES(aNewEdge);
+ //------------------------------------------------------------
+ // Extension of parallel faces to the context.
+ // Extended faces are ordered in DS and removed from MapSF.
+ //------------------------------------------------------------
+ if (!myFaces.IsEmpty()) ToContext (MapSF);
- if (IMOE.HasImage(aNewEdge)) {
- const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewEdge);
+ //------------------------------------------------------
+ // MAJ SD.
+ //------------------------------------------------------
+ BRepOffset_Type RT = BRepOffset_Concave;
+ if (myOffset < 0.) RT = BRepOffset_Convex;
+ BRepOffset_DataMapIteratorOfDataMapOfShapeOffset It(MapSF);
+ for ( ; It.More(); It.Next()) {
+ const TopoDS_Shape& SI = It.Key();
+ const BRepOffset_Offset& SF = It.Value();
+ if (SF.Status() == BRepOffset_Reversed ||
+ SF.Status() == BRepOffset_Degenerated ) {
+ //------------------------------------------------
+ // Degenerated or returned faces are not stored.
+ //------------------------------------------------
+ continue;
+ }
- myInitOffsetEdge.Bind (anEdgeRef, aListNewE);
- } else
- myInitOffsetEdge.Bind (anEdgeRef, aNewEdge);
+ const TopoDS_Face& OF = It.Value().Face();
+ myInitOffsetFace.Bind (SI,OF);
+ myInitOffsetFace.SetRoot (SI); // Initial<-> Offset
+ myImageOffset.SetRoot (OF); // FaceOffset root of images
+
+ if (SI.ShapeType() == TopAbs_FACE) {
+ for (Exp.Init(SI.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
+ Exp.More(); Exp.Next()) {
+ //--------------------------------------------------------------------
+ // To each face are associatedthe edges that restrict that
+ // The edges that do not generate tubes or are not tangent
+ // to two faces are removed.
+ //--------------------------------------------------------------------
+ const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
+ const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
+ if (!L.IsEmpty() && L.First().Type() != RT) {
+ TopAbs_Orientation OO = E.Orientation();
+ TopoDS_Shape aLocalShape = It.Value().Generated(E);
+ TopoDS_Edge OE = TopoDS::Edge(aLocalShape);
+// TopoDS_Edge OE = TopoDS::Edge(It.Value().Generated(E));
+ myAsDes->Add (OF,OE.Oriented(OO));
}
}
}
- }
-// Modified by skv - Tue Mar 15 16:20:43 2005
-
- //---------------------------
- // MAJ SD. for caps
- //---------------------------
- //TopTools_MapOfShape View;
- for (i = 1; i <= myFaces.Extent(); i++) {
- const TopoDS_Shape& Cork = myFaces(i);
- const TopTools_ListOfShape& LE = AsDes->Descendant(Cork);
- for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) {
- const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value());
- if (IMOE.HasImage(OE)) {
- const TopTools_ListOfShape& LOE = IMOE.Image(OE);
- TopTools_ListIteratorOfListOfShape itLOE(LOE);
- for (; itLOE.More(); itLOE.Next()) {
- const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value());
- myAsDes->Add(Cork,COE.Oriented(OE.Orientation())) ;
-#ifdef DRAW
- if (AffichInt2d) {
- sprintf(name,"AE_%d",NbAE++);
- DBRep::Set(name,COE);
- COES.Add(COE);
- }
-#endif
-
- if (!myAsDes->HasDescendant(COE)) {
- TopoDS_Vertex CV1,CV2;
- TopExp::Vertices(COE,CV1,CV2);
- if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
- if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));
- }
- }
- }
- else {
- myAsDes->Add(Cork,OE);
- if (AsDes->HasDescendant(OE)) {
- myAsDes->Add(OE,AsDes->Descendant(OE));
- }
-#ifdef DRAW
- if (AffichInt2d) {
- sprintf(name,"AE_%d",NbAE++);
- DBRep::Set(name,OE);
- COES.Add(OE);
- }
-#endif
+ else {
+ for (Exp.Init(OF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
+ Exp.More(); Exp.Next()) {
+ myAsDes->Add (OF,Exp.Current());
}
}
}
-
+
#ifdef OCCT_DEBUG
- DEBVerticesControl (COES,myAsDes);
if ( ChronBuild) Clock.Show();
#endif
}
-
//=======================================================================
-//function : BuildOffsetByArc
+//function : SelfInter
//purpose :
//=======================================================================
-void BRepOffset_MakeOffset::BuildOffsetByArc()
-{
-#ifdef OCCT_DEBUG
- if ( ChronBuild) {
- cout << " CONSTRUCTION OF OFFSETS :" << endl;
- Clock.Reset();
- Clock.Start();
- }
-#endif
-
- BRepOffset_DataMapOfShapeOffset MapSF;
- TopTools_MapOfShape Done;
- Standard_Boolean OffsetOutside = (myOffset > 0.)? Standard_True : Standard_False;
- //--------------------------------------------------------
- // Construction of faces parallel to initial faces
- //--------------------------------------------------------
- TopExp_Explorer Exp;
- TopTools_ListOfShape LF;
- TopTools_ListIteratorOfListOfShape itLF;
-
- BRepLib::SortFaces(myShape,LF);
-
- TopTools_DataMapOfShapeShape EdgeTgt;
- for (itLF.Initialize(LF); itLF.More(); itLF.Next()) {
- const TopoDS_Face& F = TopoDS::Face(itLF.Value());
- Standard_Real CurOffset = myOffset;
- if (myFaceOffset.IsBound(F)) CurOffset = myFaceOffset(F);
- BRepOffset_Offset OF(F,CurOffset,EdgeTgt,OffsetOutside,myJoin);
- TopTools_ListOfShape Let;
- myAnalyse.Edges(F,BRepOffset_Tangent,Let);
- TopTools_ListIteratorOfListOfShape itl(Let);
-
- for ( ; itl.More(); itl.Next()) {
- const TopoDS_Edge& Cur = TopoDS::Edge(itl.Value());
- if ( !EdgeTgt.IsBound(Cur)) {
- TopoDS_Shape aLocalShape = OF.Generated(Cur);
- const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape);
-// const TopoDS_Edge& OTE = TopoDS::Edge(OF.Generated(Cur));
- EdgeTgt.Bind(Cur,OF.Generated(Cur));
- TopoDS_Vertex V1,V2,OV1,OV2;
- TopExp::Vertices (Cur,V1,V2);
- TopExp::Vertices (OTE,OV1,OV2);
- TopTools_ListOfShape LE;
- if (!EdgeTgt.IsBound(V1)) {
- myAnalyse.Edges(V1,BRepOffset_Tangent,LE);
- const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V1);
- if (LE.Extent() == LA.Extent())
- EdgeTgt.Bind(V1,OV1);
- }
- if (!EdgeTgt.IsBound(V2)) {
- LE.Clear();
- myAnalyse.Edges(V2,BRepOffset_Tangent,LE);
- const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V2);
- if (LE.Extent() == LA.Extent())
- EdgeTgt.Bind(V2,OV2);
- }
- }
- }
- MapSF.Bind(F,OF);
- }
- //--------------------------------------------------------
- // Construction of tubes on edge.
- //--------------------------------------------------------
- BRepOffset_Type OT = BRepOffset_Convex;
- if (myOffset < 0.) OT = BRepOffset_Concave;
-
- for (Exp.Init(myShape,TopAbs_EDGE); Exp.More(); Exp.Next()) {
- const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
- if (Done.Add(E)) {
- const TopTools_ListOfShape& Anc = myAnalyse.Ancestors(E);
- if (Anc.Extent() == 2) {
- const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
- if (!L.IsEmpty() && L.First().Type() == OT) {
- Standard_Real CurOffset = myOffset;
- if ( myFaceOffset.IsBound(Anc.First()))
- CurOffset = myFaceOffset(Anc.First());
- TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E);
- TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape);
- aLocalShape = MapSF(Anc.Last()).Generated(E);
- TopoDS_Edge EOn2 = TopoDS::Edge(aLocalShape);
-// TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E));
-// TopoDS_Edge EOn2 = TopoDS::Edge(MapSF(Anc.Last()) .Generated(E));
- // find if exits tangent edges in the original shape
- TopoDS_Edge E1f, E1l;
- TopoDS_Vertex V1f, V1l;
- TopExp::Vertices(E,V1f,V1l);
- TopTools_ListOfShape TangE;
- myAnalyse.TangentEdges(E,V1f,TangE);
- // find if the pipe on the tangent edges are soon created.
- TopTools_ListIteratorOfListOfShape itl(TangE);
- Standard_Boolean Find = Standard_False;
- for ( ; itl.More() && !Find; itl.Next()) {
- if ( MapSF.IsBound(itl.Value())) {
- TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1f);
- E1f = TopoDS::Edge(aLocalShape);
-// E1f = TopoDS::Edge(MapSF(itl.Value()).Generated(V1f));
- Find = Standard_True;
- }
- }
- TangE.Clear();
- myAnalyse.TangentEdges(E,V1l,TangE);
- // find if the pipe on the tangent edges are soon created.
- itl.Initialize(TangE);
- Find = Standard_False;
- for ( ; itl.More() && !Find; itl.Next()) {
- if ( MapSF.IsBound(itl.Value())) {
- TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1l);
- E1l = TopoDS::Edge(aLocalShape);
-// E1l = TopoDS::Edge(MapSF(itl.Value()).Generated(V1l));
- Find = Standard_True;
- }
- }
- BRepOffset_Offset OF (E,EOn1,EOn2,CurOffset,E1f, E1l);
- MapSF.Bind(E,OF);
- }
- }
- else {
- // ----------------------
- // free border.
- // ----------------------
- TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E);
- TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape);
-/// TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E));
- myInitOffsetEdge.SetRoot(E); // skv: supporting history.
- myInitOffsetEdge.Bind (E,EOn1);
- }
- }
- }
-
- //--------------------------------------------------------
- // Construction of spheres on vertex.
- //--------------------------------------------------------
- Done.Clear();
- TopTools_ListIteratorOfListOfShape it;
-
- for (Exp.Init(myShape,TopAbs_VERTEX); Exp.More(); Exp.Next()) {
- const TopoDS_Vertex& V = TopoDS::Vertex (Exp.Current());
- if (Done.Add(V)) {
- const TopTools_ListOfShape& LA = myAnalyse.Ancestors(V);
- TopTools_ListOfShape LE;
- myAnalyse.Edges(V,OT,LE);
-
- if (LE.Extent() >= 3 && LE.Extent() == LA.Extent()) {
- TopTools_ListOfShape LOE;
- //--------------------------------------------------------
- // Return connected edges on tubes.
- //--------------------------------------------------------
- for (it.Initialize(LE) ; it.More(); it.Next()) {
- LOE.Append(MapSF(it.Value()).Generated(V).Reversed());
- }
- //----------------------
- // construction sphere.
- //-----------------------
- const TopTools_ListOfShape& LLA = myAnalyse.Ancestors(LA.First());
- const TopoDS_Shape& FF = LLA.First();
- Standard_Real CurOffset = myOffset;
- if ( myFaceOffset.IsBound(FF))
- CurOffset = myFaceOffset(FF);
-
- BRepOffset_Offset OF(V,LOE,CurOffset);
- MapSF.Bind(V,OF);
- }
- //--------------------------------------------------------------
- // Particular processing if V is at least a free border.
- //-------------------------------------------------------------
- TopTools_ListOfShape LBF;
- myAnalyse.Edges(V,BRepOffset_FreeBoundary,LBF);
- if (!LBF.IsEmpty()) {
- Standard_Boolean First = Standard_True;
- for (it.Initialize(LE) ; it.More(); it.Next()) {
- if (First) {
- myInitOffsetEdge.SetRoot(V); // skv: supporting history.
- myInitOffsetEdge.Bind(V,MapSF(it.Value()).Generated(V));
- First = Standard_False;
- }
- else {
- myInitOffsetEdge.Add(V,MapSF(it.Value()).Generated(V));
- }
- }
- }
- }
- }
-
- //------------------------------------------------------------
- // Extension of parallel faces to the context.
- // Extended faces are ordered in DS and removed from MapSF.
- //------------------------------------------------------------
- if (!myFaces.IsEmpty()) ToContext (MapSF);
-
- //------------------------------------------------------
- // MAJ SD.
- //------------------------------------------------------
- BRepOffset_Type RT = BRepOffset_Concave;
- if (myOffset < 0.) RT = BRepOffset_Convex;
- BRepOffset_DataMapIteratorOfDataMapOfShapeOffset It(MapSF);
- for ( ; It.More(); It.Next()) {
- const TopoDS_Shape& SI = It.Key();
- const BRepOffset_Offset& SF = It.Value();
- if (SF.Status() == BRepOffset_Reversed ||
- SF.Status() == BRepOffset_Degenerated ) {
- //------------------------------------------------
- // Degenerated or returned faces are not stored.
- //------------------------------------------------
- continue;
- }
-
- const TopoDS_Face& OF = It.Value().Face();
- myInitOffsetFace.Bind (SI,OF);
- myInitOffsetFace.SetRoot (SI); // Initial<-> Offset
- myImageOffset.SetRoot (OF); // FaceOffset root of images
-
- if (SI.ShapeType() == TopAbs_FACE) {
- for (Exp.Init(SI.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
- Exp.More(); Exp.Next()) {
- //--------------------------------------------------------------------
- // To each face are associatedthe edges that restrict that
- // The edges that do not generate tubes or are not tangent
- // to two faces are removed.
- //--------------------------------------------------------------------
- const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
- const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
- if (!L.IsEmpty() && L.First().Type() != RT) {
- TopAbs_Orientation OO = E.Orientation();
- TopoDS_Shape aLocalShape = It.Value().Generated(E);
- TopoDS_Edge OE = TopoDS::Edge(aLocalShape);
-// TopoDS_Edge OE = TopoDS::Edge(It.Value().Generated(E));
- myAsDes->Add (OF,OE.Oriented(OO));
- }
- }
- }
- else {
- for (Exp.Init(OF.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
- Exp.More(); Exp.Next()) {
- myAsDes->Add (OF,Exp.Current());
- }
- }
- }
-
-#ifdef OCCT_DEBUG
- if ( ChronBuild) Clock.Show();
-#endif
-}
-
-
-
-//=======================================================================
-//function : SelfInter
-//purpose :
-//=======================================================================
-
void BRepOffset_MakeOffset::SelfInter(TopTools_MapOfShape& /*Modif*/)
{
#ifdef OCCT_DEBUG
#endif
}
-
//=======================================================================
//function : ToContext
//purpose :
//=======================================================================
-
void BRepOffset_MakeOffset::ToContext (BRepOffset_DataMapOfShapeOffset& MapSF)
{
TopTools_DataMapOfShapeShape Created;
}
}
-
//=======================================================================
//function : UpdateFaceOffset
//purpose :
//=======================================================================
-
void BRepOffset_MakeOffset::UpdateFaceOffset()
{
TopTools_MapOfShape M;
//function : CorrectConicalFaces
//purpose :
//=======================================================================
-
void BRepOffset_MakeOffset::CorrectConicalFaces()
{
TopTools_SequenceOfShape Cones;
#endif
}
-
//=======================================================================
//function : MakeLoops
//purpose :
//=======================================================================
-
void BRepOffset_MakeOffset::MakeLoops(TopTools_IndexedMapOfShape& Modif)
{
#ifdef OCCT_DEBUG
//purpose : Reconstruction of topologically unchanged faces that
// share edges that were reconstructed.
//=======================================================================
-
void BRepOffset_MakeOffset::MakeFaces(TopTools_IndexedMapOfShape& /*Modif*/)
{
#ifdef OCCT_DEBUG
#endif
}
-//=======================================================================
-//function : UpdateInitOffset
-//purpose : Update and cleaning of myInitOffset
-//=======================================================================
-
-static void UpdateInitOffset (BRepAlgo_Image& myInitOffset,
- BRepAlgo_Image& myImageOffset,
- const TopoDS_Shape& myOffsetShape,
- const TopAbs_ShapeEnum &theShapeType) // skv
-{
- BRepAlgo_Image NIOF;
- const TopTools_ListOfShape& Roots = myInitOffset.Roots();
- TopTools_ListIteratorOfListOfShape it(Roots);
- for (; it.More(); it.Next()) {
- NIOF.SetRoot (it.Value());
- }
- for (it.Initialize(Roots); it.More(); it.Next()) {
- const TopoDS_Shape& SI = it.Value();
- TopTools_ListOfShape LI;
- TopTools_ListOfShape L1;
- myInitOffset.LastImage(SI,L1);
- TopTools_ListIteratorOfListOfShape itL1(L1);
- for (; itL1.More(); itL1.Next()) {
- const TopoDS_Shape& O1 = itL1.Value();
- TopTools_ListOfShape L2;
- myImageOffset.LastImage(O1,L2);
- LI.Append(L2);
- }
- NIOF.Bind(SI,LI);
- }
-// Modified by skv - Mon Apr 4 18:17:27 2005 Begin
-// Supporting history.
-// NIOF.Filter(myOffsetShape,TopAbs_FACE);
- NIOF.Filter(myOffsetShape, theShapeType);
-// Modified by skv - Mon Apr 4 18:17:27 2005 End
- myInitOffset = NIOF;
-}
-
//=======================================================================
//function : MakeMissingWalls
//purpose :
//=======================================================================
-
void BRepOffset_MakeOffset::MakeMissingWalls ()
{
TopTools_DataMapOfShapeListOfShape Contours; //Start vertex + list of connected edges (free boundary)
}
}
-//=======================================================================
-//function : CheckNormals
-//purpose :
-//=======================================================================
-static Standard_Boolean CheckNormals(const TopoDS_Face& theFIm,
- const TopoDS_Face& theFOr)
-{
-
- Standard_Real aUMin, aUMax, aVMin, aVMax, aU, aV, anAngle;
- gp_Pnt aP;
- gp_Vec aVecU, aVecV, aVNIm, aVNOr;
- Standard_Boolean bIsCollinear;
- //
- BRepAdaptor_Surface aSFIm(theFIm), aSFOr(theFOr);
- //
- aUMin = aSFIm.FirstUParameter();
- aUMax = aSFIm.LastUParameter();
- aVMin = aSFIm.FirstVParameter();
- aVMax = aSFIm.LastVParameter();
- //
- aU = (aUMin + aUMax) * 0.5;
- if (Precision::IsInfinite(aUMin) &&
- Precision::IsInfinite(aUMax)) {
- aU = 0.;
- }
- else if (Precision::IsInfinite(aUMin) &&
- !Precision::IsInfinite(aUMax)) {
- aU = aUMax;
- }
- else if (!Precision::IsInfinite(aUMin) &&
- Precision::IsInfinite(aUMax)) {
- aU = aUMin;
- }
- //
- aV = (aVMin + aVMax) * 0.5;
- if (Precision::IsInfinite(aVMin) &&
- Precision::IsInfinite(aVMax)) {
- aV = 0.;
- }
- else if (Precision::IsInfinite(aVMin) &&
- !Precision::IsInfinite(aVMax)) {
- aV = aVMax;
- }
- else if (!Precision::IsInfinite(aVMin) &&
- Precision::IsInfinite(aVMax)) {
- aV = aVMin;
- }
- //
- aSFIm.D1(aU, aV, aP, aVecU, aVecV);
- aVNIm = aVecU.Crossed(aVecV);
- if (theFIm.Orientation() == TopAbs_REVERSED) {
- aVNIm.Reverse();
- }
- //
- aSFOr.D1(aU, aV, aP, aVecU, aVecV);
- aVNOr = aVecU.Crossed(aVecV);
- if (theFOr.Orientation() == TopAbs_REVERSED) {
- aVNOr.Reverse();
- }
- //
- anAngle = aVNIm.Angle(aVNOr);
- bIsCollinear = (anAngle < Precision::Confusion());
- return bIsCollinear;
-}
-
//=======================================================================
//function : MakeShells
//purpose :
aBB.Add(aCSF, aF);
}
//
- bDone = (myOffset > 0);
+ bDone = ((myOffset > 0) || !bFaces);
if (bDone) {
UpdateOrigins(anOrigins, aGF);
//
//
if (bDone) {
for (i = 1; i <= aNb; ++i) {
- const TopoDS_Shape& aFx = aMFS.FindKey(i);
const BOPCol_ListOfShape& aLSx = aMFS(i);
if (aLSx.Extent() == 1) {
- // check orientation
- const TopoDS_Face& aF = *(TopoDS_Face*)&aFx;
- if (!anOrigins.Contains(aF)) {
- aLSF2.Append(aFx);
- continue;
- }
- //
- const TopTools_ListOfShape& aLFOr = anOrigins.FindFromKey(aFx);
- aItLS.Initialize(aLFOr);
- for (; aItLS.More(); aItLS.Next()) {
- const TopoDS_Face& aFOr = *(TopoDS_Face*)&aItLS.Value();
- //
- if (CheckNormals(aF, aFOr)) {
- aLSF2.Append(aFx);
- break;
- }
- }
+ const TopoDS_Shape& aFx = aMFS.FindKey(i);
+ aLSF2.Append(aFx);
}
}
//
- // make solid containing most outer faces
+ // make solids from the new list
BOPAlgo_MakerVolume aMV2;
//
aMV2.SetArguments(aLSF2);
bDone = (aMV2.ErrorStatus() == 0);
if (bDone) {
aResult = aMV2.Shape();
+ if (aResult.ShapeType() == TopAbs_COMPOUND) {
+ BOPCol_ListOfShape aLSF3;
+ //
+ aExp.Init(aResult, TopAbs_FACE);
+ for (; aExp.More(); aExp.Next()) {
+ const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current();
+ //
+ // check orientation
+ if (!anOrigins.Contains(aF)) {
+ aLSF3.Append(aF);
+ continue;
+ }
+ //
+ const TopTools_ListOfShape& aLFOr = anOrigins.FindFromKey(aF);
+ aItLS.Initialize(aLFOr);
+ for (; aItLS.More(); aItLS.Next()) {
+ const TopoDS_Face& aFOr = *(TopoDS_Face*)&aItLS.Value();
+ //
+ if (CheckNormals(aF, aFOr)) {
+ aLSF3.Append(aF);
+ break;
+ }
+ }
+ }
+ //
+ // make solid containing most outer faces
+ BOPAlgo_MakerVolume aMV3;
+ //
+ aMV3.SetArguments(aLSF3);
+ aMV3.SetIntersect(Standard_False);
+ //
+ aMV3.Perform();
+ bDone = (aMV3.ErrorStatus() == 0);
+ if (bDone) {
+ aResult = aMV3.Shape();
+ }
+ }
}
}
}
}
}
}
- //
- if (!bDone) {
- BRepTools_Quilt Glue;
- BOPCol_ListIteratorOfListOfShape aItLS;
- //
- aItLS.Initialize(aLSF);
- for (; aItLS.More(); aItLS.Next()) {
- const TopoDS_Shape& aF = aItLS.Value();
- Glue.Add(aF);
- }
- myOffsetShape = Glue.Shells();
- }
+ //
+ if (!bDone) {
+ BRepTools_Quilt Glue;
+ BOPCol_ListIteratorOfListOfShape aItLS;
+ //
+ aItLS.Initialize(aLSF);
+ for (; aItLS.More(); aItLS.Next()) {
+ const TopoDS_Shape& aF = aItLS.Value();
+ Glue.Add(aF);
+ }
+ myOffsetShape = Glue.Shells();
+ }
+}
+
+//=======================================================================
+//function : MakeSolid
+//purpose :
+//=======================================================================
+void BRepOffset_MakeOffset::MakeSolid ()
+{
+ if (myOffsetShape.IsNull()) return;
+
+// Modified by skv - Mon Apr 4 18:17:27 2005 Begin
+// Supporting history.
+ UpdateInitOffset (myInitOffsetFace,myImageOffset,myOffsetShape, TopAbs_FACE);
+ UpdateInitOffset (myInitOffsetEdge,myImageOffset,myOffsetShape, TopAbs_EDGE);
+// Modified by skv - Mon Apr 4 18:17:27 2005 End
+ TopExp_Explorer exp;
+ BRep_Builder B;
+ Standard_Integer NbShell = 0;
+ TopoDS_Compound NC;
+ TopoDS_Shape S1;
+ B.MakeCompound (NC);
+
+ for (exp.Init(myOffsetShape,TopAbs_SHELL); exp.More(); exp.Next()) {
+ TopoDS_Shell Sh = TopoDS::Shell(exp.Current());
+ if (myThickening && myOffset > 0.)
+ Sh.Reverse();
+ NbShell++;
+ if (Sh.Closed()) {
+ TopoDS_Solid Sol;
+ B.MakeSolid (Sol);
+ B.Add (Sol,Sh);
+ Sol.Closed(Standard_True);
+ B.Add (NC,Sol);
+ if (NbShell == 1) S1 = Sol;
+ }
+ else {
+ B.Add (NC,Sh);
+ if (NbShell == 1) S1 = Sh;
+ }
+ }
+ if (NbShell == 1) myOffsetShape = S1;
+ else myOffsetShape = NC;
+}
+
+//=======================================================================
+//function : SelectShells
+//purpose :
+//=======================================================================
+void BRepOffset_MakeOffset::SelectShells ()
+{
+ TopTools_MapOfShape FreeEdges;
+ TopExp_Explorer exp(myShape,TopAbs_EDGE);
+ //-------------------------------------------------------------
+ // FreeEdges all edges that can have free border in the
+ // parallel shell
+ // 1 - free borders of myShape .
+ //-------------------------------------------------------------
+ for ( ; exp.More(); exp.Next()) {
+ const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
+ const TopTools_ListOfShape& LA = myAnalyse.Ancestors(E);
+ if (LA.Extent() < 2) {
+ if (myAnalyse.Type(E).First().Type() == BRepOffset_FreeBoundary) {
+ FreeEdges.Add(E);
+ }
+ }
+ }
+ // myShape has free borders and there are no caps
+ // no unwinding 3d.
+ if (!FreeEdges.IsEmpty() && myFaces.IsEmpty()) return;
+
+ myOffsetShape = BRepOffset_Tool::Deboucle3D(myOffsetShape,FreeEdges);
+}
+
+//=======================================================================
+//function : OffsetFacesFromShapes
+//purpose :
+//=======================================================================
+const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetFacesFromShapes() const
+{
+ return myInitOffsetFace;
+}
+
+// Modified by skv - Tue Mar 15 16:20:43 2005 Begin
+
+//=======================================================================
+//function : GetJoinType
+//purpose : Query offset join type.
+//=======================================================================
+GeomAbs_JoinType BRepOffset_MakeOffset::GetJoinType() const
+{
+ return myJoin;
+}
+
+//=======================================================================
+//function : OffsetEdgesFromShapes
+//purpose :
+//=======================================================================
+const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetEdgesFromShapes() const
+{
+ return myInitOffsetEdge;
+}
+
+// Modified by skv - Tue Mar 15 16:20:43 2005 End
+
+//=======================================================================
+//function : ClosingFaces
+//purpose :
+//=======================================================================
+const TopTools_IndexedMapOfShape& BRepOffset_MakeOffset::ClosingFaces () const
+{
+ return myFaces;
+}
+
+//=======================================================================
+//function : EncodeRegularity
+//purpose :
+//=======================================================================
+void BRepOffset_MakeOffset::EncodeRegularity ()
+{
+#ifdef OCCT_DEBUG
+ if (ChronBuild) {
+ cout << " CODING OF REGULARITIES:" << endl;
+ Clock.Reset();
+ Clock.Start();
+ }
+#endif
+
+ if (myOffsetShape.IsNull()) return;
+ // find edges G1 in the result
+ TopExp_Explorer exp(myOffsetShape,TopAbs_EDGE);
+
+ BRep_Builder B;
+ TopTools_MapOfShape MS;
+
+ for ( ; exp.More(); exp.Next()) {
+ TopoDS_Edge OE = TopoDS::Edge(exp.Current());
+ BRepLib::BuildCurve3d(OE,myTol);
+ TopoDS_Edge ROE = OE;
+
+ if ( !MS.Add(OE)) continue;
+
+ if ( myImageOffset.IsImage(OE))
+ ROE = TopoDS::Edge(myImageOffset.Root(OE));
+
+ const TopTools_ListOfShape& LofOF = myAsDes->Ascendant(ROE);
+
+ if (LofOF.Extent() != 2) {
+#ifdef OCCT_DEBUG_VERB
+ cout << " Edge shared by " << LofOF.Extent() << " Faces" << endl;
+#endif
+ continue;
+ }
+
+ const TopoDS_Face& F1 = TopoDS::Face(LofOF.First());
+ const TopoDS_Face& F2 = TopoDS::Face(LofOF.Last() );
+
+ if ( F1.IsNull() || F2.IsNull())
+ continue;
+
+ const TopoDS_Shape& Root1 = myInitOffsetFace.Root(F1);
+ const TopoDS_Shape& Root2 = myInitOffsetFace.Root(F2);
+
+ TopAbs_ShapeEnum Type1 = Root1.ShapeType();
+ TopAbs_ShapeEnum Type2 = Root2.ShapeType();
+
+ if (F1.IsSame(F2)) {
+ if (BRep_Tool::IsClosed(OE,F1)) {
+ // Temporary Debug for the Bench.
+ // Check with YFR.
+ // In mode intersection, the edges are not coded in myInitOffsetEdge
+ // so, manage case by case
+ // Note DUB; for Hidden parts, it is NECESSARY to code CN
+ // Analytic Surfaces.
+ if (myJoin == GeomAbs_Intersection) {
+ BRepAdaptor_Surface BS(F1,Standard_False);
+ GeomAbs_SurfaceType SType = BS.GetType();
+ if (SType == GeomAbs_Cylinder ||
+ SType == GeomAbs_Cone ||
+ SType == GeomAbs_Sphere ||
+ SType == GeomAbs_Torus ) {
+ B.Continuity(OE,F1,F1,GeomAbs_CN);
+ }
+ else {
+ // See YFR : MaJ of myInitOffsetFace
+ }
+ }
+ else if (myInitOffsetEdge.IsImage(ROE)) {
+ if ( Type1 == TopAbs_FACE && Type2 == TopAbs_FACE) {
+ const TopoDS_Face& FRoot = TopoDS::Face(Root1);
+ const TopoDS_Edge& EI = TopoDS::Edge(myInitOffsetEdge.ImageFrom(ROE));
+ GeomAbs_Shape Conti = BRep_Tool::Continuity(EI,FRoot,FRoot);
+ if (Conti == GeomAbs_CN) {
+ B.Continuity(OE,F1,F1,GeomAbs_CN);
+ }
+ else if ( Conti > GeomAbs_C0) {
+ B.Continuity(OE,F1,F1,GeomAbs_G1);
+ }
+ }
+ }
+ }
+ continue;
+ }
+
+
+ // code regularities G1 between :
+ // - sphere and tube : one root is a vertex, the other is an edge
+ // and the vertex is included in the edge
+ // - face and tube : one root is a face, the other an edge
+ // and the edge is included in the face
+ // - face and face : if two root faces are tangent in
+ // the initial shape, they will be tangent in the offset shape
+ // - tube and tube : if 2 edges generating tubes are
+ // tangents, the 2 will be tangent either.
+ if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_VERTEX) {
+ TopoDS_Vertex V1,V2;
+ TopExp::Vertices(TopoDS::Edge(Root1), V1, V2);
+ if ( V1.IsSame(Root2) || V2.IsSame(Root2)) {
+ B.Continuity(OE,F1,F2,GeomAbs_G1);
+ }
+ }
+ else if ( Type1 == TopAbs_VERTEX && Type2 == TopAbs_EDGE) {
+ TopoDS_Vertex V1,V2;
+ TopExp::Vertices(TopoDS::Edge(Root2), V1, V2);
+ if ( V1.IsSame(Root1) || V2.IsSame(Root1)) {
+ B.Continuity(OE,F1,F2,GeomAbs_G1);
+ }
+ }
+ else if ( Type1 == TopAbs_FACE && Type2 == TopAbs_EDGE) {
+ TopExp_Explorer exp2(Root1,TopAbs_EDGE);
+ for ( ; exp2.More(); exp2.Next()) {
+ if ( exp2.Current().IsSame(Root2)) {
+ B.Continuity(OE,F1,F2,GeomAbs_G1);
+ break;
+ }
+ }
+ }
+ else if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_FACE) {
+ TopExp_Explorer exp2(Root2,TopAbs_EDGE);
+ for ( ; exp2.More(); exp2.Next()) {
+ if ( exp2.Current().IsSame(Root1)) {
+ B.Continuity(OE,F1,F2,GeomAbs_G1);
+ break;
+ }
+ }
+ }
+ else if ( Type1 == TopAbs_FACE && Type2 == TopAbs_FACE) {
+ // if two root faces are tangent in
+ // the initial shape, they will be tangent in the offset shape
+ TopTools_ListOfShape LE,LV;
+ BRepOffset_Tool::HasCommonShapes(TopoDS::Face(Root1),
+ TopoDS::Face(Root2),
+ LE,LV);
+ if ( LE.Extent() == 1) {
+ const TopoDS_Edge& Ed = TopoDS::Edge(LE.First());
+ if ( myAnalyse.HasAncestor(Ed)) {
+ const BRepOffset_ListOfInterval& LI = myAnalyse.Type(Ed);
+ if (LI.Extent() == 1 &&
+ LI.First().Type() == BRepOffset_Tangent) {
+ B.Continuity(OE,F1,F2,GeomAbs_G1);
+ }
+ }
+ }
+ }
+ else if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_EDGE) {
+ TopTools_ListOfShape LV;
+ TopExp_Explorer exp1,exp2;
+ for (exp1.Init(Root1,TopAbs_VERTEX); exp1.More(); exp1.Next()) {
+ TopExp_Explorer exp2(F2,TopAbs_EDGE);
+ for (exp2.Init(Root2,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
+ if (exp1.Current().IsSame(exp2.Current())) {
+ LV.Append(exp1.Current());
+ }
+ }
+ }
+ if ( LV.Extent() == 1) {
+ TopTools_ListOfShape LEdTg;
+ myAnalyse.TangentEdges(TopoDS::Edge(Root1),
+ TopoDS::Vertex(LV.First()),
+ LEdTg);
+ TopTools_ListIteratorOfListOfShape it(LEdTg);
+ for (; it.More(); it.Next()) {
+ if ( it.Value().IsSame(Root2)) {
+ B.Continuity(OE,F1,F2,GeomAbs_G1);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+#ifdef OCCT_DEBUG
+ if ( ChronBuild) Clock.Show();
+#endif
+}
+
+
+//=======================================================================
+// static methods implementation
+//=======================================================================
+
+//=======================================================================
+//function : UpDateTolerance
+//purpose :
+//=======================================================================
+void UpdateTolerance (TopoDS_Shape& S,
+ const TopTools_IndexedMapOfShape& Faces)
+{
+ BRep_Builder B;
+ TopTools_MapOfShape View;
+ TopoDS_Vertex V[2];
+
+ // The edges of caps are not modified.
+ Standard_Integer j;
+ for (j = 1; j <= Faces.Extent(); j++) {
+ const TopoDS_Shape& F = Faces(j);
+ TopExp_Explorer Exp;
+ for (Exp.Init(F,TopAbs_EDGE); Exp.More(); Exp.Next()) {
+ View.Add(Exp.Current());
+ }
+ }
+
+ TopExp_Explorer Exp;
+ for (Exp.Init(S,TopAbs_EDGE); Exp.More(); Exp.Next()) {
+ TopoDS_Edge E = TopoDS::Edge(Exp.Current());
+ if (View.Add(E)) {
+ Handle(BRepCheck_Edge) EdgeCorrector = new BRepCheck_Edge(E);
+ Standard_Real Tol = EdgeCorrector->Tolerance();
+ B.UpdateEdge (E,Tol);
+
+ // Update the vertices.
+ TopExp::Vertices(E,V[0],V[1]);
+
+ for (Standard_Integer i = 0 ; i <=1 ; i++) {
+ if (View.Add(V[i])) {
+ Handle(BRep_TVertex) TV = Handle(BRep_TVertex)::DownCast(V[i].TShape());
+ TV->Tolerance(0.);
+ Handle(BRepCheck_Vertex) VertexCorrector = new BRepCheck_Vertex(V[i]);
+ B.UpdateVertex (V[i],VertexCorrector->Tolerance());
+ // use the occasion to clean the vertices.
+ (TV->ChangePoints()).Clear();
+ }
+ B.UpdateVertex(V[i],Tol);
+ }
+ }
+ }
+}
+
+//=======================================================================
+//function : FindParameter
+//purpose :
+//=======================================================================
+Standard_Boolean FindParameter(const TopoDS_Vertex& V,
+ const TopoDS_Edge& E,
+ Standard_Real& U)
+{
+ // Search the vertex in the edge
+
+ Standard_Boolean rev = Standard_False;
+ TopoDS_Shape VF;
+ TopAbs_Orientation orient = TopAbs_INTERNAL;
+
+ TopoDS_Iterator itv(E.Oriented(TopAbs_FORWARD));
+
+ // if the edge has no vertices
+ // and is degenerated use the vertex orientation
+ // RLE, june 94
+
+ if (!itv.More() && BRep_Tool::Degenerated(E)) {
+ orient = V.Orientation();
+ }
+
+ while (itv.More()) {
+ const TopoDS_Shape& Vcur = itv.Value();
+ if (V.IsSame(Vcur)) {
+ if (VF.IsNull()) {
+ VF = Vcur;
+ }
+ else {
+ rev = E.Orientation() == TopAbs_REVERSED;
+ if (Vcur.Orientation() == V.Orientation()) {
+ VF = Vcur;
+ }
+ }
+ }
+ itv.Next();
+ }
+
+ if (!VF.IsNull()) orient = VF.Orientation();
+
+ Standard_Real f,l;
+
+ if (orient == TopAbs_FORWARD) {
+ BRep_Tool::Range(E,f,l);
+ //return (rev) ? l : f;
+ U = (rev) ? l : f;
+ return Standard_True;
+ }
+
+ else if (orient == TopAbs_REVERSED) {
+ BRep_Tool::Range(E,f,l);
+ //return (rev) ? f : l;
+ U = (rev) ? f : l;
+ return Standard_True;
+ }
+
+ else {
+ TopLoc_Location L;
+ const Handle(Geom_Curve)& C = BRep_Tool::Curve(E,L,f,l);
+ L = L.Predivided(V.Location());
+ if (!C.IsNull() || BRep_Tool::Degenerated(E)) {
+ BRep_ListIteratorOfListOfPointRepresentation itpr
+ ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
+
+ while (itpr.More()) {
+ const Handle(BRep_PointRepresentation)& pr = itpr.Value();
+ if (pr->IsPointOnCurve(C,L)) {
+ Standard_Real p = pr->Parameter();
+ Standard_Real res = p;// SVV 4 nov 99 - to avoid warnings on Linux
+ if (!C.IsNull()) {
+ // Closed curves RLE 16 june 94
+ if (Precision::IsNegativeInfinite(f))
+ {
+ //return pr->Parameter();//p;
+ U = pr->Parameter();
+ return Standard_True;
+ }
+ if (Precision::IsPositiveInfinite(l))
+ {
+ //return pr->Parameter();//p;
+ U = pr->Parameter();
+ return Standard_True;
+ }
+ gp_Pnt Pf = C->Value(f).Transformed(L.Transformation());
+ gp_Pnt Pl = C->Value(l).Transformed(L.Transformation());
+ Standard_Real tol = BRep_Tool::Tolerance(V);
+ if (Pf.Distance(Pl) < tol) {
+ if (Pf.Distance(BRep_Tool::Pnt(V)) < tol) {
+ if (V.Orientation() == TopAbs_FORWARD) res = f;//p = f;
+ else res = l;//p = l;
+ }
+ }
+ }
+ //return res;//p;
+ U = res;
+ return Standard_True;
+ }
+ itpr.Next();
+ }
+ }
+ else {
+ // no 3d curve !!
+ // let us try with the first pcurve
+ Handle(Geom2d_Curve) PC;
+ Handle(Geom_Surface) S;
+ BRep_Tool::CurveOnSurface(E,PC,S,L,f,l);
+ L = L.Predivided(V.Location());
+ BRep_ListIteratorOfListOfPointRepresentation itpr
+ ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
+
+ while (itpr.More()) {
+ const Handle(BRep_PointRepresentation)& pr = itpr.Value();
+ if (pr->IsPointOnCurveOnSurface(PC,S,L)) {
+ Standard_Real p = pr->Parameter();
+ // Closed curves RLE 16 june 94
+ if (PC->IsClosed()) {
+ if ((p == PC->FirstParameter()) ||
+ (p == PC->LastParameter())) {
+ if (V.Orientation() == TopAbs_FORWARD) p = PC->FirstParameter();
+ else p = PC->LastParameter();
+ }
+ }
+ //return p;
+ U = p;
+ return Standard_True;
+ }
+ itpr.Next();
+ }
+ }
+ }
+
+ //Standard_NoSuchObject::Raise("BRep_Tool:: no parameter on edge");
+ return Standard_False;
+}
+
+//=======================================================================
+//function : GetEdgePoints
+//purpose : gets the first, last and middle points of the edge
+//=======================================================================
+void GetEdgePoints(const TopoDS_Edge& anEdge,
+ const TopoDS_Face& aFace,
+ gp_Pnt& fPnt, gp_Pnt& mPnt,
+ gp_Pnt& lPnt)
+{
+ Standard_Real f, l;
+ Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( anEdge, aFace, f, l );
+ gp_Pnt2d fPnt2d = theCurve->Value(f);
+ gp_Pnt2d lPnt2d = theCurve->Value(l);
+ gp_Pnt2d mPnt2d = theCurve->Value(0.5*(f + l));
+ Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
+ fPnt = aSurf->Value(fPnt2d.X(),fPnt2d.Y());
+ lPnt = aSurf->Value(lPnt2d.X(),lPnt2d.Y());
+ mPnt = aSurf->Value(mPnt2d.X(), mPnt2d.Y());
+}
+
+//=======================================================================
+//function : FillContours
+//purpose : fills free boundary contours and faces connected (MapEF)
+//=======================================================================
+void FillContours(const TopoDS_Shape& aShape,
+ const BRepOffset_Analyse& Analyser,
+ TopTools_DataMapOfShapeListOfShape& Contours,
+ TopTools_DataMapOfShapeShape& MapEF)
+{
+ TopTools_ListOfShape Edges;
+
+ TopExp_Explorer Explo(aShape, TopAbs_FACE);
+ BRepTools_WireExplorer Wexp;
+
+ for (; Explo.More(); Explo.Next())
+ {
+ TopoDS_Face aFace = TopoDS::Face(Explo.Current());
+ TopoDS_Iterator itf(aFace);
+ for (; itf.More(); itf.Next())
+ {
+ TopoDS_Wire aWire = TopoDS::Wire(itf.Value());
+ for (Wexp.Init(aWire, aFace); Wexp.More(); Wexp.Next())
+ {
+ TopoDS_Edge anEdge = Wexp.Current();
+ if (BRep_Tool::Degenerated(anEdge))
+ continue;
+ const BRepOffset_ListOfInterval& Lint = Analyser.Type(anEdge);
+ if (!Lint.IsEmpty() && Lint.First().Type() == BRepOffset_FreeBoundary)
+ {
+ MapEF.Bind(anEdge, aFace);
+ Edges.Append(anEdge);
+ }
+ }
+ }
+ }
+
+ TopTools_ListIteratorOfListOfShape itl;
+ while (!Edges.IsEmpty())
+ {
+ TopoDS_Edge StartEdge = TopoDS::Edge(Edges.First());
+ Edges.RemoveFirst();
+ TopoDS_Vertex StartVertex, CurVertex;
+ TopExp::Vertices(StartEdge, StartVertex, CurVertex, Standard_True);
+ TopTools_ListOfShape aContour;
+ aContour.Append(StartEdge);
+ while (!CurVertex.IsSame(StartVertex))
+ for (itl.Initialize(Edges); itl.More(); itl.Next())
+ {
+ TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
+ TopoDS_Vertex V1, V2;
+ TopExp::Vertices(anEdge, V1, V2);
+ if (V1.IsSame(CurVertex) || V2.IsSame(CurVertex))
+ {
+ aContour.Append(anEdge);
+ CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
+ Edges.Remove(itl);
+ break;
+ }
+ }
+ Contours.Bind(StartVertex, aContour);
+ }
+}
+
+//=======================================================================
+//function : RemoveCorks
+//purpose :
+//=======================================================================
+void RemoveCorks (TopoDS_Shape& S,
+ TopTools_IndexedMapOfShape& Faces)
+{
+ TopoDS_Compound SS;
+ BRep_Builder B;
+ B.MakeCompound (SS);
+ //-----------------------------------------------------
+ // Construction of a shape without caps.
+ // and Orientation of caps as in shape S.
+ //-----------------------------------------------------
+ TopExp_Explorer exp(S,TopAbs_FACE);
+ for (; exp.More(); exp.Next()) {
+ const TopoDS_Shape& Cork = exp.Current();
+ if (!Faces.Contains(Cork)) {
+ B.Add(SS,Cork);
+ }
+ else {
+ //Faces.Remove (Cork);
+ //begin instead of Remove//
+ TopoDS_Shape LastShape = Faces(Faces.Extent());
+ Faces.RemoveLast();
+ if (Faces.FindIndex(Cork) != 0)
+ Faces.Substitute(Faces.FindIndex(Cork), LastShape);
+ //end instead of Remove //
+ Faces.Add(Cork); // to reset it with proper orientation.
+ }
+ }
+ S = SS;
+#ifdef DRAW
+ if ( AffichOffC)
+ DBRep::Set("myInit", SS);
+#endif
+
+}
+
+//=======================================================================
+//function : IsConnectedShell
+//purpose :
+//=======================================================================
+Standard_Boolean IsConnectedShell( const TopoDS_Shape& S )
+{
+ BRepTools_Quilt Glue;
+ Glue.Add( S );
+
+ TopoDS_Shape SS = Glue.Shells();
+ TopExp_Explorer Explo( SS, TopAbs_SHELL );
+ Explo.Next();
+ if (Explo.More())
+ return Standard_False;
+
+ return Standard_True;
+}
+
+//=======================================================================
+//function : MakeList
+//purpose :
+//=======================================================================
+void MakeList (TopTools_ListOfShape& OffsetFaces,
+ const BRepAlgo_Image& myInitOffsetFace,
+ const TopTools_IndexedMapOfShape& myFaces)
+{
+ TopTools_ListIteratorOfListOfShape itLOF(myInitOffsetFace.Roots());
+ for ( ; itLOF.More(); itLOF.Next()) {
+ const TopoDS_Shape& Root = itLOF.Value();
+ if (myInitOffsetFace.HasImage(Root)) {
+ if (!myFaces.Contains(Root)) {
+ OffsetFaces.Append(myInitOffsetFace.Image(Root).First());
+ }
+ }
+ }
}
//=======================================================================
-//function : MakeSolid
+//function : EvalMax
//purpose :
//=======================================================================
-
-void BRepOffset_MakeOffset::MakeSolid ()
+void EvalMax(const TopoDS_Shape& S,
+ Standard_Real& Tol)
{
- if (myOffsetShape.IsNull()) return;
+ TopExp_Explorer exp;
+ for (exp.Init(S,TopAbs_VERTEX); exp.More(); exp.Next()) {
+ const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current());
+ Standard_Real TolV = BRep_Tool::Tolerance(V);
+ if (TolV > Tol) Tol = TolV;
+ }
+ //Patch
+ Tol *= 5.;
+}
-// Modified by skv - Mon Apr 4 18:17:27 2005 Begin
-// Supporting history.
- UpdateInitOffset (myInitOffsetFace,myImageOffset,myOffsetShape, TopAbs_FACE);
- UpdateInitOffset (myInitOffsetEdge,myImageOffset,myOffsetShape, TopAbs_EDGE);
-// Modified by skv - Mon Apr 4 18:17:27 2005 End
- TopExp_Explorer exp;
- BRep_Builder B;
- Standard_Integer NbShell = 0;
- TopoDS_Compound NC;
- TopoDS_Shape S1;
- B.MakeCompound (NC);
+//=======================================================================
+//function : TrimEdge
+//purpose : Trim the edge of the largest of descendants in AsDes2d.
+// Order in AsDes two vertices that have trimmed the edge.
+//=======================================================================
+void TrimEdge(TopoDS_Edge& NE,
+ const Handle(BRepAlgo_AsDes)& AsDes2d,
+ Handle(BRepAlgo_AsDes)& AsDes)
+{
+ Standard_Real aSameParTol = Precision::Confusion();
+
+ TopoDS_Vertex V1,V2;
+ Standard_Real U = 0.;
+ Standard_Real UMin = Precision::Infinite();
+ Standard_Real UMax = -UMin;
- for (exp.Init(myOffsetShape,TopAbs_SHELL); exp.More(); exp.Next()) {
- TopoDS_Shell Sh = TopoDS::Shell(exp.Current());
- if (myThickening && myOffset > 0.)
- Sh.Reverse();
- NbShell++;
- if (Sh.Closed()) {
- TopoDS_Solid Sol;
- B.MakeSolid (Sol);
- B.Add (Sol,Sh);
- Sol.Closed(Standard_True);
- B.Add (NC,Sol);
- if (NbShell == 1) S1 = Sol;
+ const TopTools_ListOfShape& LE = AsDes2d->Descendant(NE);
+ //
+ Standard_Boolean bTrim = Standard_False;
+ //
+ if (LE.Extent() > 1) {
+ TopTools_ListIteratorOfListOfShape it (LE);
+ for (; it.More(); it.Next()) {
+ TopoDS_Vertex V = TopoDS::Vertex(it.Value());
+ if (NE.Orientation() == TopAbs_REVERSED)
+ V.Reverse();
+ //V.Orientation(TopAbs_INTERNAL);
+ if (!FindParameter(V, NE, U)) {
+ Standard_Real f, l;
+ Handle(Geom_Curve) theCurve = BRep_Tool::Curve(NE, f, l);
+ gp_Pnt thePoint = BRep_Tool::Pnt(V);
+ GeomAPI_ProjectPointOnCurve Projector(thePoint, theCurve);
+ if (Projector.NbPoints() == 0)
+ Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge no projection");
+ U = Projector.LowerDistanceParameter();
+ }
+ if (U < UMin) {
+ UMin = U; V1 = V;
+ }
+ if (U > UMax) {
+ UMax = U; V2 = V;
+ }
}
- else {
- B.Add (NC,Sh);
- if (NbShell == 1) S1 = Sh;
+ //
+ if (V1.IsNull() || V2.IsNull()) {
+ Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge");
+ }
+ if (!V1.IsSame(V2)) {
+ NE.Free( Standard_True );
+ BRep_Builder B;
+ TopAbs_Orientation Or = NE.Orientation();
+ NE.Orientation(TopAbs_FORWARD);
+ TopoDS_Vertex VF,VL;
+ TopExp::Vertices (NE,VF,VL);
+ B.Remove(NE,VF);
+ B.Remove(NE,VL);
+ B.Add (NE,V1.Oriented(TopAbs_FORWARD));
+ B.Add (NE,V2.Oriented(TopAbs_REVERSED));
+ B.Range(NE,UMin,UMax);
+ NE.Orientation(Or);
+ AsDes->Add(NE,V1.Oriented(TopAbs_FORWARD));
+ AsDes->Add(NE,V2.Oriented(TopAbs_REVERSED));
+ BRepLib::SameParameter(NE, aSameParTol, Standard_True);
+ //
+ bTrim = Standard_True;
+ }
+ }
+ //
+ if (!bTrim) {
+ if (!BRep_Tool::Degenerated(NE)) {
+ BRepAdaptor_Curve aBAC(NE);
+ if (!aBAC.IsClosed()) {
+ if (AsDes->HasAscendant(NE)) {
+ AsDes->Remove(NE);
+ }
+ }
}
}
- if (NbShell == 1) myOffsetShape = S1;
- else myOffsetShape = NC;
}
//=======================================================================
-//function : SelectShells
+//function : SortFaces
//purpose :
//=======================================================================
-
-void BRepOffset_MakeOffset::SelectShells ()
-{
- TopTools_MapOfShape FreeEdges;
- TopExp_Explorer exp(myShape,TopAbs_EDGE);
- //-------------------------------------------------------------
- // FreeEdges all edges that can have free border in the
- // parallel shell
- // 1 - free borders of myShape .
- //-------------------------------------------------------------
- for ( ; exp.More(); exp.Next()) {
- const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
- const TopTools_ListOfShape& LA = myAnalyse.Ancestors(E);
- if (LA.Extent() < 2) {
- if (myAnalyse.Type(E).First().Type() == BRepOffset_FreeBoundary) {
- FreeEdges.Add(E);
+void SortFaces(const TopTools_ListOfShape& theLIm,
+ TopTools_ListOfShape& theLFImages,
+ const Standard_Boolean bKeepFirst)
+{
+ Standard_Integer bKeep; // 1 - keep; -1 - remove
+ Standard_Boolean bFlag;
+ TopTools_IndexedDataMapOfShapeListOfShape aDMELF;
+ TopTools_ListOfShape aLFKeep, aLFLeft, aLFTmp;
+ TopTools_MapOfShape aMV;
+ TopTools_ListIteratorOfListOfShape aItLF;
+ TopExp_Explorer aExp;
+ //
+ aLFLeft = theLIm;
+ //
+ bKeep = bKeepFirst ? 1 : -1;
+ for (;;) {
+ aLFTmp = aLFLeft;
+ //
+ aLFLeft.Clear();
+ aLFKeep.Clear();
+ aDMELF.Clear();
+ //
+ // map list of images edge - faces
+ aItLF.Initialize(aLFTmp);
+ for (; aItLF.More(); aItLF.Next()) {
+ const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
+ TopExp::MapShapesAndAncestors(aFIm, TopAbs_EDGE, TopAbs_FACE, aDMELF);
+ }
+ //
+ // find images that have edge attached to only one face
+ aItLF.Initialize(aLFTmp);
+ for (; aItLF.More(); aItLF.Next()) {
+ const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
+ aExp.Init(aFIm, TopAbs_EDGE);
+ for (bFlag = Standard_False; aExp.More(); aExp.Next()) {
+ const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
+ const TopTools_ListOfShape& aLEF = aDMELF.FindFromKey(aE);
+ if (aLEF.Extent() == 1) {
+ TopoDS_Vertex aV1, aV2;
+ TopExp::Vertices(aE, aV1, aV2);
+ aMV.Add(aV1);
+ aMV.Add(aV2);
+ //
+ bFlag = Standard_True;
+ }
}
- }
+ //
+ if (bFlag) {
+ aLFKeep.Append(aFIm);
+ }
+ else {
+ aLFLeft.Append(aFIm);
+ }
+ }
+ //
+ // map shapes left for processing
+ aDMELF.Clear();
+ aLFTmp = aLFLeft;
+ aLFLeft.Clear();
+ //
+ aItLF.Initialize(aLFTmp);
+ for (; aItLF.More(); aItLF.Next()) {
+ const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
+ TopExp::MapShapesAndAncestors(aFIm, TopAbs_EDGE, TopAbs_FACE, aDMELF);
+ }
+ //
+ // find outer edges and check if they touch the first part of edges
+ aItLF.Initialize(aLFTmp);
+ for (; aItLF.More(); aItLF.Next()) {
+ const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
+ aExp.Init(aFIm, TopAbs_EDGE);
+ for (bFlag = Standard_False; aExp.More() && !bFlag; aExp.Next()) {
+ const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
+ const TopTools_ListOfShape& aLEF = aDMELF.FindFromKey(aE);
+ if (aLEF.Extent() == 1) {
+ TopoDS_Vertex aV1, aV2;
+ TopExp::Vertices(aE, aV1, aV2);
+ //
+ bFlag = aMV.Contains(aV1) || aMV.Contains(aV2);
+ }
+ }
+ //
+ if (bFlag) {
+ aLFKeep.Append(aFIm);
+ }
+ else {
+ aLFLeft.Append(aFIm);
+ }
+ }
+ //
+ if (bKeep == 1) {
+ // aLFKeep should be kept
+ // aLFLeft left for further processing
+ aItLF.Initialize(aLFKeep);
+ for (; aItLF.More(); aItLF.Next()) {
+ const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
+ theLFImages.Append(aFIm);
+ }
+ }
+ //
+ if (aLFLeft.IsEmpty()) {
+ break;
+ }
+ //
+ bKeep *= -1;
}
- // myShape has free borders and there are no caps
- // no unwinding 3d.
- if (!FreeEdges.IsEmpty() && myFaces.IsEmpty()) return;
-
- myOffsetShape = BRepOffset_Tool::Deboucle3D(myOffsetShape,FreeEdges);
}
//=======================================================================
-//function : OffsetFacesFromShapes
+//function : FindShape
//purpose :
//=======================================================================
-
-const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetFacesFromShapes() const
+Standard_Boolean FindShape(const TopoDS_Shape& theSWhat,
+ const TopoDS_Shape& theSWhere,
+ TopoDS_Shape& theRes)
{
- return myInitOffsetFace;
+ Standard_Boolean bFound = Standard_False;
+ TopAbs_ShapeEnum aType = theSWhat.ShapeType();
+ TopExp_Explorer aExp(theSWhere, aType);
+ for (; aExp.More(); aExp.Next()) {
+ const TopoDS_Shape& aS = aExp.Current();
+ if (aS.IsSame(theSWhat)) {
+ theRes = aS;
+ bFound = Standard_True;
+ break;
+ }
+ }
+ return bFound;
}
-// Modified by skv - Tue Mar 15 16:20:43 2005 Begin
-
//=======================================================================
-//function : GetJoinType
-//purpose : Query offset join type.
+//function : UpdateOrigins
+//purpose :
//=======================================================================
-
-GeomAbs_JoinType BRepOffset_MakeOffset::GetJoinType() const
+void UpdateOrigins(TopTools_IndexedDataMapOfShapeListOfShape& theOrigins,
+ BOPAlgo_Builder& theGF)
{
- return myJoin;
+ TopTools_ListOfShape aLSTmp;
+ TopTools_MapOfShape aMFence;
+ BOPCol_ListIteratorOfListOfShape aItA;
+ TopTools_ListIteratorOfListOfShape aIt, aIt1;
+ //
+ const BOPCol_ListOfShape& aLSU = theGF.Arguments();
+ aItA.Initialize(aLSU);
+ for (; aItA.More(); aItA.Next()) {
+ const TopoDS_Shape& aS = aItA.Value();
+ //
+ if (!theOrigins.Contains(aS)) {
+ continue;
+ }
+ //
+ const TopTools_ListOfShape& aLSIm = theGF.Modified(aS);
+ if (aLSIm.IsEmpty()) {
+ continue;
+ }
+ //
+ const TopTools_ListOfShape& aLS = theOrigins.FindFromKey(aS);
+ //
+ aIt.Initialize(aLSIm);
+ for (; aIt.More(); aIt.Next()) {
+ const TopoDS_Shape& aSIm = aIt.Value();
+ //
+ if (!theOrigins.Contains(aSIm)) {
+ theOrigins.Add(aSIm, aLS);
+ continue;
+ }
+ //
+ aMFence.Clear();
+ //
+ TopTools_ListOfShape& aLS1 = theOrigins.ChangeFromKey(aSIm);
+ aLSTmp.Assign(aLS1);
+ //
+ aLS1.Clear();
+ aIt1.Initialize(aLSTmp);
+ for (; aIt1.More(); aIt1.Next()) {
+ const TopoDS_Shape& aS1 = aIt1.Value();
+ if (aMFence.Add(aS1)) {
+ aLS1.Append(aS1);
+ }
+ }
+ //
+ aIt1.Initialize(aLS);
+ for (; aIt1.More(); aIt1.Next()) {
+ const TopoDS_Shape& aS1 = aIt1.Value();
+ if (aMFence.Add(aS1)) {
+ aLS1.Append(aS1);
+ }
+ }
+ }
+ }
}
//=======================================================================
-//function : OffsetEdgesFromShapes
+//function : IsMicroEdge
//purpose :
//=======================================================================
-
-const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetEdgesFromShapes() const
+Standard_Boolean IsMicroEdge(const TopoDS_Edge& theEdge,
+ const Handle(IntTools_Context)& theCtx,
+ Standard_Real& theFuzz)
{
- return myInitOffsetEdge;
+ TopoDS_Vertex aV1, aV2;
+ TopExp::Vertices(theEdge, aV1, aV2);
+ Standard_Boolean bNull = aV1.IsNull() || aV2.IsNull();
+ if (bNull) {
+ return Standard_False;
+ }
+ //
+ Standard_Boolean bMicro;
+ Standard_Real aT1, aT2;
+ IntTools_ShrunkRange aSR;
+ //
+ BRepAdaptor_Curve aBAC(theEdge);
+ //
+ aT1 = BRep_Tool::Parameter(aV1, theEdge);
+ aT2 = BRep_Tool::Parameter(aV2, theEdge);
+ if (aT2 < aT1) {
+ Standard_Real aTmp = aT1;
+ aT1 = aT2;
+ aT2 = aTmp;
+ }
+ //
+ aSR.SetContext(theCtx);
+ aSR.SetData(theEdge, aT1, aT2, aV1, aV2);
+ aSR.Perform();
+ bMicro = (aSR.ErrorStatus() != 0);
+ if (!bMicro) {
+ Standard_Real anEps, aTS1, aTS2, aTolV1, aTolV2;
+ //
+ aTolV1 = BRep_Tool::Tolerance(aV1);
+ aTolV2 = BRep_Tool::Tolerance(aV2);
+ //
+ anEps = aBAC.Resolution(aTolV1 + aTolV2);
+ if (anEps < 1.e-8) {
+ anEps = 1.e-8;
+ }
+ //
+ aSR.ShrunkRange(aTS1, aTS2);
+ bMicro = (aTS2 - aTS1) <= anEps;
+ }
+ //
+ if (bMicro) {
+ Standard_Real aLen = CPnts_AbscissaPoint::Length(aBAC);
+ if (aLen > theFuzz) {
+ theFuzz = aLen;
+ }
+ }
+ //
+ return bMicro;
}
-// Modified by skv - Tue Mar 15 16:20:43 2005 End
-
//=======================================================================
-//function : ClosingFaces
+//function : ComputeBiNormal
//purpose :
//=======================================================================
-
-const TopTools_IndexedMapOfShape& BRepOffset_MakeOffset::ClosingFaces () const
+Standard_Boolean ComputeBiNormal(const TopoDS_Face& theF,
+ const TopoDS_Edge& theE,
+ gp_Dir& theDB)
{
- return myFaces;
+ Standard_Boolean bDone = Standard_False;
+ Standard_Real aT1, aT2, aTm;
+ //
+ const Handle(Geom2d_Curve)& aC2d =
+ BRep_Tool::CurveOnSurface(theE, theF, aT1, aT2);
+ if (aC2d.IsNull()) {
+ return bDone;
+ }
+ //
+ gp_Pnt2d aP2dNear;
+ gp_Pnt aP, aPNear;
+ //
+ const Handle(Geom_Curve)& aC3d =
+ BRep_Tool::Curve(theE, aT1, aT2);
+ //
+ aTm = (aT1 + aT2) * 0.5;
+ aP = aC3d->Value(aTm);
+ //
+ BOPTools_AlgoTools3D::PointNearEdge(theE, theF, aTm, 1.e-5, aP2dNear, aPNear);
+ //
+ gp_Vec aVB(aP, aPNear);
+ theDB = gp_Dir(aVB);
+ return !bDone;
}
-
-
//=======================================================================
-//function : EncodeRegularity
+//function : CheckBiNormals
//purpose :
//=======================================================================
-
-void BRepOffset_MakeOffset::EncodeRegularity ()
+Standard_Boolean CheckBiNormals
+ (const TopoDS_Face& aFIm,
+ const TopoDS_Face& aFOr,
+ const TopTools_IndexedDataMapOfShapeListOfShape& theOrigins,
+ const TopTools_MapOfShape& theMFence,
+ Standard_Boolean& bKeep,
+ Standard_Boolean& bRem)
{
-#ifdef OCCT_DEBUG
- if (ChronBuild) {
- cout << " CODING OF REGULARITIES:" << endl;
- Clock.Reset();
- Clock.Start();
- }
-#endif
-
- if (myOffsetShape.IsNull()) return;
- // find edges G1 in the result
- TopExp_Explorer exp(myOffsetShape,TopAbs_EDGE);
-
- BRep_Builder B;
- TopTools_MapOfShape MS;
-
- for ( ; exp.More(); exp.Next()) {
- TopoDS_Edge OE = TopoDS::Edge(exp.Current());
- BRepLib::BuildCurve3d(OE,myTol);
- TopoDS_Edge ROE = OE;
-
- if ( !MS.Add(OE)) continue;
-
- if ( myImageOffset.IsImage(OE))
- ROE = TopoDS::Edge(myImageOffset.Root(OE));
-
- const TopTools_ListOfShape& LofOF = myAsDes->Ascendant(ROE);
-
- if (LofOF.Extent() != 2) {
-#ifdef OCCT_DEBUG_VERB
- cout << " Edge shared by " << LofOF.Extent() << " Faces" << endl;
-#endif
- continue;
- }
-
- const TopoDS_Face& F1 = TopoDS::Face(LofOF.First());
- const TopoDS_Face& F2 = TopoDS::Face(LofOF.Last() );
-
- if ( F1.IsNull() || F2.IsNull())
- continue;
-
- const TopoDS_Shape& Root1 = myInitOffsetFace.Root(F1);
- const TopoDS_Shape& Root2 = myInitOffsetFace.Root(F2);
-
- TopAbs_ShapeEnum Type1 = Root1.ShapeType();
- TopAbs_ShapeEnum Type2 = Root2.ShapeType();
-
- if (F1.IsSame(F2)) {
- if (BRep_Tool::IsClosed(OE,F1)) {
- // Temporary Debug for the Bench.
- // Check with YFR.
- // In mode intersection, the edges are not coded in myInitOffsetEdge
- // so, manage case by case
- // Note DUB; for Hidden parts, it is NECESSARY to code CN
- // Analytic Surfaces.
- if (myJoin == GeomAbs_Intersection) {
- BRepAdaptor_Surface BS(F1,Standard_False);
- GeomAbs_SurfaceType SType = BS.GetType();
- if (SType == GeomAbs_Cylinder ||
- SType == GeomAbs_Cone ||
- SType == GeomAbs_Sphere ||
- SType == GeomAbs_Torus ) {
- B.Continuity(OE,F1,F1,GeomAbs_CN);
- }
- else {
- // See YFR : MaJ of myInitOffsetFace
- }
- }
- else if (myInitOffsetEdge.IsImage(ROE)) {
- if ( Type1 == TopAbs_FACE && Type2 == TopAbs_FACE) {
- const TopoDS_Face& FRoot = TopoDS::Face(Root1);
- const TopoDS_Edge& EI = TopoDS::Edge(myInitOffsetEdge.ImageFrom(ROE));
- GeomAbs_Shape Conti = BRep_Tool::Continuity(EI,FRoot,FRoot);
- if (Conti == GeomAbs_CN) {
- B.Continuity(OE,F1,F1,GeomAbs_CN);
- }
- else if ( Conti > GeomAbs_C0) {
- B.Continuity(OE,F1,F1,GeomAbs_G1);
- }
- }
- }
- }
+ Standard_Boolean bChecked;
+ Standard_Real anAngle;
+ //
+ bKeep = Standard_False;
+ bRem = Standard_True;
+ bChecked = Standard_False;
+ //
+ const TopoDS_Wire& aWIm = BRepTools::OuterWire(aFIm);
+ //
+ TopExp_Explorer aExp(aWIm, TopAbs_EDGE);
+ for (; aExp.More(); aExp.Next()) {
+ const TopoDS_Edge& aEIm = *(TopoDS_Edge*)&aExp.Current();
+ //
+ if (BRep_Tool::Degenerated(aEIm)) {
continue;
}
-
-
- // code regularities G1 between :
- // - sphere and tube : one root is a vertex, the other is an edge
- // and the vertex is included in the edge
- // - face and tube : one root is a face, the other an edge
- // and the edge is included in the face
- // - face and face : if two root faces are tangent in
- // the initial shape, they will be tangent in the offset shape
- // - tube and tube : if 2 edges generating tubes are
- // tangents, the 2 will be tangent either.
- if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_VERTEX) {
- TopoDS_Vertex V1,V2;
- TopExp::Vertices(TopoDS::Edge(Root1), V1, V2);
- if ( V1.IsSame(Root2) || V2.IsSame(Root2)) {
- B.Continuity(OE,F1,F2,GeomAbs_G1);
- }
+ //
+ if (!theOrigins.Contains(aEIm)) {
+ continue;
}
- else if ( Type1 == TopAbs_VERTEX && Type2 == TopAbs_EDGE) {
- TopoDS_Vertex V1,V2;
- TopExp::Vertices(TopoDS::Edge(Root2), V1, V2);
- if ( V1.IsSame(Root1) || V2.IsSame(Root1)) {
- B.Continuity(OE,F1,F2,GeomAbs_G1);
- }
+ //
+ const TopTools_ListOfShape& aLEOr = theOrigins.FindFromKey(aEIm);
+ const TopoDS_Shape& aSOr = aLEOr.First();
+ if (aSOr.ShapeType() != TopAbs_EDGE) {
+ bRem = Standard_False;
+ continue;
}
- else if ( Type1 == TopAbs_FACE && Type2 == TopAbs_EDGE) {
- TopExp_Explorer exp2(Root1,TopAbs_EDGE);
- for ( ; exp2.More(); exp2.Next()) {
- if ( exp2.Current().IsSame(Root2)) {
- B.Continuity(OE,F1,F2,GeomAbs_G1);
- break;
+ //
+ if (aLEOr.Extent() > 1) {
+ TopTools_MapOfShape aME, aMV;
+ Standard_Integer aNbE, aNbV;
+ //
+ TopTools_ListIteratorOfListOfShape aItLS(aLEOr);
+ for (; aItLS.More(); aItLS.Next()) {
+ const TopoDS_Edge& aEOr = *(TopoDS_Edge*)&aItLS.Value();
+ aME.Add(aEOr);
+ //
+ TopExp_Explorer aExpE(aEOr, TopAbs_VERTEX);
+ for (; aExpE.More(); aExpE.Next()) {
+ const TopoDS_Shape& aV = aExpE.Current();
+ aMV.Add(aV);
}
}
- }
- else if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_FACE) {
- TopExp_Explorer exp2(Root2,TopAbs_EDGE);
- for ( ; exp2.More(); exp2.Next()) {
- if ( exp2.Current().IsSame(Root1)) {
- B.Continuity(OE,F1,F2,GeomAbs_G1);
- break;
- }
+ //
+ aNbV = aMV.Extent();
+ aNbE = aME.Extent();
+ //
+ if ((aNbE > 1) && (aNbV == 2*aNbE)) {
+ continue;
}
}
- else if ( Type1 == TopAbs_FACE && Type2 == TopAbs_FACE) {
- // if two root faces are tangent in
- // the initial shape, they will be tangent in the offset shape
- TopTools_ListOfShape LE,LV;
- BRepOffset_Tool::HasCommonShapes(TopoDS::Face(Root1),
- TopoDS::Face(Root2),
- LE,LV);
- if ( LE.Extent() == 1) {
- const TopoDS_Edge& Ed = TopoDS::Edge(LE.First());
- if ( myAnalyse.HasAncestor(Ed)) {
- const BRepOffset_ListOfInterval& LI = myAnalyse.Type(Ed);
- if (LI.Extent() == 1 &&
- LI.First().Type() == BRepOffset_Tangent) {
- B.Continuity(OE,F1,F2,GeomAbs_G1);
- }
- }
- }
+ //
+ if (theMFence.Contains(aEIm)) {
+ bChecked = Standard_True;
+ bKeep = Standard_True;
+ bRem = Standard_False;
+ break;
+ }
+ //
+ const TopoDS_Edge& aEOr = *(TopoDS_Edge*)&aLEOr.First();
+ //
+ TopoDS_Edge aEOrF;
+ if (!FindShape(aEOr, aFOr, aEOrF)) {
+ continue;
}
- else if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_EDGE) {
- TopTools_ListOfShape LV;
- TopExp_Explorer exp1,exp2;
- for (exp1.Init(Root1,TopAbs_VERTEX); exp1.More(); exp1.Next()) {
- TopExp_Explorer exp2(F2,TopAbs_EDGE);
- for (exp2.Init(Root2,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
- if (exp1.Current().IsSame(exp2.Current())) {
- LV.Append(exp1.Current());
- }
- }
- }
- if ( LV.Extent() == 1) {
- TopTools_ListOfShape LEdTg;
- myAnalyse.TangentEdges(TopoDS::Edge(Root1),
- TopoDS::Vertex(LV.First()),
- LEdTg);
- TopTools_ListIteratorOfListOfShape it(LEdTg);
- for (; it.More(); it.Next()) {
- if ( it.Value().IsSame(Root2)) {
- B.Continuity(OE,F1,F2,GeomAbs_G1);
- break;
- }
- }
- }
+ //
+ // compute bi-normal for face aFIm on the edge aEIm
+ gp_Dir aDB1;
+ if (!ComputeBiNormal(aFIm, aEIm, aDB1)) {
+ continue;
+ }
+ //
+ // compute bi-normal for face aFOr on the edge aEOrF
+ gp_Dir aDB2;
+ if (!ComputeBiNormal(aFOr, aEOrF, aDB2)) {
+ continue;
+ }
+ //
+ bChecked = Standard_True;
+ // check coincidence of bi-normals
+ anAngle = aDB1.Angle(aDB2);
+ if (Abs(anAngle - M_PI) < Precision::Confusion()) {
+ bRem = bRem && Standard_True;
+ }
+ else {
+ bRem = Standard_False;
+ bKeep = Standard_True;
+ break;
}
}
-
-#ifdef OCCT_DEBUG
- if ( ChronBuild) Clock.Show();
-#endif
+ //
+ return bChecked;
}
-
-
//=======================================================================
-//function : UpDateTolerance
+//function : CheckBiNormals
//purpose :
//=======================================================================
-
-static void UpdateTolerance (TopoDS_Shape& S,
- const TopTools_IndexedMapOfShape& Faces)
+void CheckBiNormals
+ (TopTools_ListOfShape& theLFImages,
+ const TopoDS_Face& theF,
+ const TopTools_IndexedDataMapOfShapeListOfShape& theOrigins,
+ TopTools_ListOfShape& theLFKeep)
{
- BRep_Builder B;
- TopTools_MapOfShape View;
- TopoDS_Vertex V[2];
-
- // The edges of caps are not modified.
- Standard_Integer j;
- for (j = 1; j <= Faces.Extent(); j++) {
- const TopoDS_Shape& F = Faces(j);
- TopExp_Explorer Exp;
- for (Exp.Init(F,TopAbs_EDGE); Exp.More(); Exp.Next()) {
- View.Add(Exp.Current());
+ Standard_Boolean bChecked, bKeep, bRem;
+ Standard_Integer i, aNb;
+ TopTools_ListOfShape aLFKeep;
+ TopTools_MapOfShape aMEToKeep;
+ TopTools_IndexedDataMapOfShapeListOfShape aDMELF;
+ TopTools_ListIteratorOfListOfShape aItLF;
+ //
+ // collect outer edges
+ aItLF.Initialize(theLFImages);
+ for (; aItLF.More(); aItLF.Next()) {
+ const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
+ TopExp::MapShapesAndAncestors(aFIm, TopAbs_EDGE, TopAbs_FACE, aDMELF);
+ }
+ //
+ aNb = aDMELF.Extent();
+ for (i = 1; i <= aNb; ++i) {
+ const TopTools_ListOfShape& aLF = aDMELF(i);
+ if (aLF.Extent() == 1) {
+ const TopoDS_Shape& aE = aDMELF.FindKey(i);
+ aMEToKeep.Add(aE);
}
}
-
- TopExp_Explorer Exp;
- for (Exp.Init(S,TopAbs_EDGE); Exp.More(); Exp.Next()) {
- TopoDS_Edge E = TopoDS::Edge(Exp.Current());
- if (View.Add(E)) {
- Handle(BRepCheck_Edge) EdgeCorrector = new BRepCheck_Edge(E);
- Standard_Real Tol = EdgeCorrector->Tolerance();
- B.UpdateEdge (E,Tol);
-
- // Update the vertices.
- TopExp::Vertices(E,V[0],V[1]);
-
- for (Standard_Integer i = 0 ; i <=1 ; i++) {
- if (View.Add(V[i])) {
- Handle(BRep_TVertex) TV = Handle(BRep_TVertex)::DownCast(V[i].TShape());
- TV->Tolerance(0.);
- Handle(BRepCheck_Vertex) VertexCorrector = new BRepCheck_Vertex(V[i]);
- B.UpdateVertex (V[i],VertexCorrector->Tolerance());
- // use the occasion to clean the vertices.
- (TV->ChangePoints()).Clear();
+ //
+ const TopoDS_Face& aFOr = *(TopoDS_Face*)&theOrigins.FindFromKey(theF).First();
+ //
+ aItLF.Initialize(theLFImages);
+ for (; aItLF.More(); ) {
+ const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value();
+ //
+ bChecked = CheckBiNormals(aFIm, aFOr, theOrigins, aMEToKeep, bKeep, bRem);
+ //
+ if (bChecked) {
+ if (bRem) {
+ theLFImages.Remove(aItLF);
+ }
+ else {
+ if (bKeep) {
+ theLFKeep.Append(aFIm);
}
- B.UpdateVertex(V[i],Tol);
+ aItLF.Next();
}
}
+ else {
+ aItLF.Next();
+ }
+ }
+}
+
+//=======================================================================
+//function : CheckNormals
+//purpose :
+//=======================================================================
+Standard_Boolean CheckNormals(const TopoDS_Face& theFIm,
+ const TopoDS_Face& theFOr)
+{
+
+ Standard_Real aUMin, aUMax, aVMin, aVMax, aU, aV, anAngle;
+ gp_Pnt aP;
+ gp_Vec aVecU, aVecV, aVNIm, aVNOr;
+ Standard_Boolean bIsCollinear;
+ //
+ BRepAdaptor_Surface aSFIm(theFIm), aSFOr(theFOr);
+ //
+ aUMin = aSFIm.FirstUParameter();
+ aUMax = aSFIm.LastUParameter();
+ aVMin = aSFIm.FirstVParameter();
+ aVMax = aSFIm.LastVParameter();
+ //
+ aU = (aUMin + aUMax) * 0.5;
+ if (Precision::IsInfinite(aUMin) &&
+ Precision::IsInfinite(aUMax)) {
+ aU = 0.;
+ }
+ else if (Precision::IsInfinite(aUMin) &&
+ !Precision::IsInfinite(aUMax)) {
+ aU = aUMax;
+ }
+ else if (!Precision::IsInfinite(aUMin) &&
+ Precision::IsInfinite(aUMax)) {
+ aU = aUMin;
+ }
+ //
+ aV = (aVMin + aVMax) * 0.5;
+ if (Precision::IsInfinite(aVMin) &&
+ Precision::IsInfinite(aVMax)) {
+ aV = 0.;
+ }
+ else if (Precision::IsInfinite(aVMin) &&
+ !Precision::IsInfinite(aVMax)) {
+ aV = aVMax;
+ }
+ else if (!Precision::IsInfinite(aVMin) &&
+ Precision::IsInfinite(aVMax)) {
+ aV = aVMin;
}
+ //
+ aSFIm.D1(aU, aV, aP, aVecU, aVecV);
+ aVNIm = aVecU.Crossed(aVecV);
+ if (theFIm.Orientation() == TopAbs_REVERSED) {
+ aVNIm.Reverse();
+ }
+ //
+ aSFOr.D1(aU, aV, aP, aVecU, aVecV);
+ aVNOr = aVecU.Crossed(aVecV);
+ if (theFOr.Orientation() == TopAbs_REVERSED) {
+ aVNOr.Reverse();
+ }
+ //
+ anAngle = aVNIm.Angle(aVNOr);
+ bIsCollinear = (anAngle < Precision::Confusion());
+ return bIsCollinear;
}
+//=======================================================================
+//function : UpdateInitOffset
+//purpose : Update and cleaning of myInitOffset
+//=======================================================================
+void UpdateInitOffset(BRepAlgo_Image& myInitOffset,
+ BRepAlgo_Image& myImageOffset,
+ const TopoDS_Shape& myOffsetShape,
+ const TopAbs_ShapeEnum &theShapeType) // skv
+{
+ BRepAlgo_Image NIOF;
+ const TopTools_ListOfShape& Roots = myInitOffset.Roots();
+ TopTools_ListIteratorOfListOfShape it(Roots);
+ for (; it.More(); it.Next()) {
+ NIOF.SetRoot (it.Value());
+ }
+ for (it.Initialize(Roots); it.More(); it.Next()) {
+ const TopoDS_Shape& SI = it.Value();
+ TopTools_ListOfShape LI;
+ TopTools_ListOfShape L1;
+ myInitOffset.LastImage(SI,L1);
+ TopTools_ListIteratorOfListOfShape itL1(L1);
+ for (; itL1.More(); itL1.Next()) {
+ const TopoDS_Shape& O1 = itL1.Value();
+ TopTools_ListOfShape L2;
+ myImageOffset.LastImage(O1,L2);
+ LI.Append(L2);
+ }
+ NIOF.Bind(SI,LI);
+ }
+// Modified by skv - Mon Apr 4 18:17:27 2005 Begin
+// Supporting history.
+// NIOF.Filter(myOffsetShape,TopAbs_FACE);
+ NIOF.Filter(myOffsetShape, theShapeType);
+// Modified by skv - Mon Apr 4 18:17:27 2005 End
+ myInitOffset = NIOF;
+}