+++ /dev/null
-// Created on: 2015-04-24
-// Created by: NIKOLAI BUKHALOV
-// Copyright (c) 2015 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#include <BRepBuilderAPI_FastSewing.hxx>
-
-#include <BRepTools_Quilt.hxx>
-#include <Bnd_Box.hxx>
-
-#include <Geom2d_Line.hxx>
-#include <Geom2d_TrimmedCurve.hxx>
-#include <Geom_Curve.hxx>
-#include <Geom_RectangularTrimmedSurface.hxx>
-#include <Geom_Surface.hxx>
-
-#include <Precision.hxx>
-
-#include <Standard_NullObject.hxx>
-
-#include <TopExp_Explorer.hxx>
-#include <TopoDS.hxx>
-#include <TopTools_MapOfShape.hxx>
-
-IMPLEMENT_STANDARD_HANDLE(BRepBuilderAPI_FastSewing, Standard_Transient)
-IMPLEMENT_STANDARD_RTTIEXT(BRepBuilderAPI_FastSewing, Standard_Transient)
-
-//=======================================================================
-//function : IntersetctionOfSets
-//purpose : Returns minimal value of intersection result
-//=======================================================================
-static Standard_Integer
- IntersectionOfSets( const NCollection_List<Standard_Integer>& theSet1,
- const NCollection_List<Standard_Integer>& theSet2)
-{
- const Standard_Integer anIntMax = IntegerLast();
- Standard_Integer aRetVal = anIntMax;
- for(NCollection_List<Standard_Integer>::Iterator
- anIt1 = theSet1.begin().Iterator();
- anIt1.More(); anIt1.Next())
- {
- const Standard_Integer aVal1 = anIt1.Value();
- for(NCollection_List<Standard_Integer>::Iterator
- anIt2 = theSet2.begin().Iterator();
- anIt2.More(); anIt2.Next())
- {
- const Standard_Integer aVal2 = anIt2.Value();
- if(aVal1 == aVal2)
- {
- //theIntersectionResult.Append(aVal1);
- if(aVal1 < aRetVal)
- aRetVal = aVal1;
- }
- }
- }
-
- if(aRetVal == anIntMax)
- return -1;
-
- return aRetVal;
-}
-
-//=======================================================================
-//function : Get2DCurve
-//purpose :
-//=======================================================================
-static Handle(Geom2d_Curve)
- Get2DCurve( const Standard_Integer theIndex,
- const Standard_Real theUfirst,
- const Standard_Real theUlast,
- const Standard_Real theVfirst,
- const Standard_Real theVlast,
- const Standard_Boolean theIsReverse = Standard_False)
-{
- if((theIndex < 0) || (theIndex > 3))
- Standard_OutOfRange::Raise("BRepBuilderAPI_FastSewing.cxx, Get2DCurve(): OUT of Range");
-
- Handle(Geom2d_Curve) a2dCurv;
-
- if(!theIsReverse)
- {
- switch(theIndex)
- {
- case 0:
- a2dCurv =
- new Geom2d_TrimmedCurve(new Geom2d_Line(
- gp_Pnt2d(0.0, theVfirst), gp_Dir2d(1.0,0.0)),
- theUfirst, theUlast);
- break;
- case 1:
- a2dCurv =
- new Geom2d_TrimmedCurve(new Geom2d_Line(
- gp_Pnt2d(theUlast, 0.0), gp_Dir2d(0.0,1.0)),
- theVfirst, theVlast);
- break;
- case 2:
- a2dCurv =
- new Geom2d_TrimmedCurve(new Geom2d_Line(
- gp_Pnt2d(0.0, theVlast), gp_Dir2d(1.0,0.0)),
- theUfirst, theUlast);
- break;
- case 3:
- a2dCurv =
- new Geom2d_TrimmedCurve(new Geom2d_Line(
- gp_Pnt2d(theUfirst, 0.0), gp_Dir2d(0.0,1.0)),
- theVfirst, theVlast);
- break;
- default:
- break;
- }
- }
- else
- {
- switch(theIndex)
- {
- case 0:
- a2dCurv =
- new Geom2d_TrimmedCurve(new Geom2d_Line(
- gp_Pnt2d(theUfirst+theUlast, theVfirst),
- gp_Dir2d(-1.0,0.0)),
- theUfirst, theUlast);
- break;
- case 1:
- a2dCurv =
- new Geom2d_TrimmedCurve(new Geom2d_Line(
- gp_Pnt2d(theUlast, theVfirst+theVlast),
- gp_Dir2d(0.0,-1.0)),
- theVfirst, theVlast);
- break;
- case 2:
- a2dCurv =
- new Geom2d_TrimmedCurve(new Geom2d_Line(
- gp_Pnt2d(theUfirst+theUlast, theVlast),
- gp_Dir2d(-1.0,0.0)),
- theUfirst, theUlast);
- break;
- case 3:
- a2dCurv =
- new Geom2d_TrimmedCurve(new Geom2d_Line(
- gp_Pnt2d(theUfirst, theVfirst+theVlast),
- gp_Dir2d(0.0,-1.0)),
- theVfirst, theVlast);
- break;
- default:
- break;
- }
- }
-
- return a2dCurv;
-}
-
-//=======================================================================
-//function : Constructor
-//purpose :
-//=======================================================================
-BRepBuilderAPI_FastSewing::
- BRepBuilderAPI_FastSewing( const Standard_Real theTol):
- myTolerance(theTol),
- myStatusList(0)
-{
-}
-
-//=======================================================================
-//function : Add
-//purpose :
-//=======================================================================
-Standard_Boolean BRepBuilderAPI_FastSewing::Add(const TopoDS_Shape& theShape)
-{
- Standard_Boolean aResult = Standard_False;
- if(theShape.IsNull())
- {
- SetStatus(FS_EmptyInput);
- return aResult;
- }
-
- TopTools_MapOfShape aMS;
- //aMS.Add(theShape);
- TopExp_Explorer aFExp(theShape,TopAbs_FACE);
- for (; aFExp.More(); aFExp.Next())
- {
- const TopoDS_Face& aFace = TopoDS::Face(aFExp.Current());
- if(aMS.Add(aFace))
- {
- Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
- if(aSurf.IsNull())
- {
- SetStatus(FS_FaceWithNullSurface);
- continue;
- }
-
- if(aSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
- {
- SetStatus(FS_NotNaturalBoundsFace);
- continue;
- }
-
- Standard_Real aUf = 0.0, aUl = 0.0, aVf = 0.0, aVl = 0.0;
- aSurf->Bounds(aUf, aUl, aVf, aVl);
-
- if(Precision::IsInfinite(aUf) || Precision::IsInfinite(aUl) ||
- Precision::IsInfinite(aVf) || Precision::IsInfinite(aVl))
- {
- SetStatus(FS_InfiniteSurface);
- continue;
- }
-
- FS_Face aFFace;
- aFFace.mySrcFace = aFace;
- aFFace.myID = myFaceVec.Length();//because start index is 0
- myFaceVec.Append(aFFace);
- aResult = Standard_True;
- }
- }
-
- return aResult;
-}
-
-//=======================================================================
-//function : Add
-//purpose :
-//=======================================================================
-Standard_Boolean BRepBuilderAPI_FastSewing::Add(const Handle(Geom_Surface)& theSurface)
-{
- if(theSurface.IsNull())
- {
- SetStatus(FS_FaceWithNullSurface);
- return Standard_False;
- }
-
- if(theSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
- {
- SetStatus(FS_NotNaturalBoundsFace);
- return Standard_False;
- }
-
- Standard_Real aUf = 0.0, aUl = 0.0, aVf = 0.0, aVl = 0.0;
- theSurface->Bounds(aUf, aUl, aVf, aVl);
-
- if(Precision::IsInfinite(aUf) || Precision::IsInfinite(aUl) ||
- Precision::IsInfinite(aVf) || Precision::IsInfinite(aVl))
- {
- SetStatus(FS_InfiniteSurface);
- return Standard_False;
- }
-
- FS_Face aFace;
-
- BRep_Builder aBuilder;
- aBuilder.MakeFace(aFace.mySrcFace);
- aBuilder.MakeFace(aFace.mySrcFace, theSurface, myTolerance);
- aBuilder.NaturalRestriction(aFace.mySrcFace, Standard_True);
-
- aFace.myID = myFaceVec.Length();//because start index is 0
- myFaceVec.Append(aFace);
-
- return Standard_True;
-}
-
-
-//=======================================================================
-//function : Perform
-//purpose :
-//=======================================================================
-void BRepBuilderAPI_FastSewing::Perform(void)
-{
- if(myFaceVec.IsEmpty())
- {
- SetStatus(FS_EmptyInput);
- return;
- }
-
- try
- {
- {
- // create vertices having unique coordinates
- Standard_Real aRange = Compute3DRange();
- Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
- NCollection_CellFilter<NodeInspector>
- aCells(Max(myTolerance, aRange/IntegerLast()), anAlloc);
-
- for(Standard_Integer i = myFaceVec.Lower(); i <= myFaceVec.Upper(); i++)
- {
- FindVertexes(i, aCells);
- }
- }
-
- for(Standard_Integer i = myFaceVec.Lower(); i <= myFaceVec.Upper(); i++)
- {
- FindEdges(i);
- }
-
- //Create topological structures
-
- for(Standard_Integer i = myVertexVec.Lower(); i <= myVertexVec.Upper(); i++)
- {
- myVertexVec.ChangeValue(i).CreateTopologicalVertex(myTolerance);
- }
-
- //Edges
- for(Standard_Integer i = myEdgeVec.Lower(); i <= myEdgeVec.Upper(); i++)
- {
- myEdgeVec.ChangeValue(i).CreateTopologicalEdge(myVertexVec, myFaceVec, myTolerance);
- }
-
- //Shell
- BRepTools_Quilt aQuilt;
-
- //Faces
- for(Standard_Integer i = myFaceVec.Lower(); i <= myFaceVec.Upper(); i++)
- {
- FS_Face& aFace = myFaceVec.ChangeValue(i);
- aFace.CreateTopologicalWire(myEdgeVec, myTolerance);
- aFace.CreateTopologicalFace();
- aQuilt.Add(aFace.myRetFace);
- }
-
- myResShape = aQuilt.Shells();
- }
- catch(Standard_Failure)
- {
- SetStatus(FS_Exception);
-#ifdef OCCT_DEBUG
- //Standard_Failure::Caught()->Print(cout);
-#endif
- return;
- }
-}
-
-//=======================================================================
-//function : UpdateEdgeInfo
-//purpose :
-//=======================================================================
-void BRepBuilderAPI_FastSewing::UpdateEdgeInfo( const Standard_Integer theIDPrevVertex,
- const Standard_Integer theIDCurrVertex,
- const Standard_Integer theFaceID,
- const Standard_Integer theIDCurvOnFace)
-{
- //Indeed, two vertices combine into one edge only.
- const Standard_Integer anEdgeID =
- IntersectionOfSets(myVertexVec.Value(theIDPrevVertex).myEdges,
- myVertexVec.Value(theIDCurrVertex).myEdges);
-
- //For DEBUG mode only
- Standard_ProgramError_Raise_if(anEdgeID < 0,
- "BRepBuilderAPI_FastSewing::UpdateEdgeInfo: Update not existing edge.");
-
- FS_Edge& anEdge = myEdgeVec.ChangeValue(anEdgeID);
- anEdge.myFaces.Append(theFaceID);
- FS_Face& aFace = myFaceVec.ChangeValue(theFaceID);
- aFace.SetEdge(theIDCurvOnFace, anEdge.myID);
-}
-
-//=======================================================================
-//function : CreateNewEdge
-//purpose : Creates FS_Edge
-//=======================================================================
-void BRepBuilderAPI_FastSewing::CreateNewEdge(const Standard_Integer theIDPrevVertex,
- const Standard_Integer theIDCurrVertex,
- const Standard_Integer theFaceID,
- const Standard_Integer theIDCurvOnFace)
-{
- FS_Edge anEdge(theIDPrevVertex, theIDCurrVertex);
- anEdge.myID = myEdgeVec.Length(); //because start index is 0
-
-
- anEdge.myFaces.Append(theFaceID);
- FS_Face& aFace = myFaceVec.ChangeValue(theFaceID);
- aFace.SetEdge(theIDCurvOnFace, anEdge.myID);
-
- myVertexVec.ChangeValue(theIDPrevVertex).myEdges.Append(anEdge.myID);
-
- if(theIDPrevVertex == theIDCurrVertex)
- {//the Edge is degenerated
- SetStatus(FS_Degenerated);
- }
- else
- {
- myVertexVec.ChangeValue(theIDCurrVertex).myEdges.Append(anEdge.myID);
- }
-
- myEdgeVec.Append(anEdge);
-}
-
-//=======================================================================
-//function : FindVertexes
-//purpose :
-//=======================================================================
-void BRepBuilderAPI_FastSewing::
- FindVertexes(const Standard_Integer theSurfID,
- NCollection_CellFilter<NodeInspector>& theCells)
-{
- const Standard_Integer aNbPoints = 4;
- FS_Face& aFace = myFaceVec.ChangeValue(theSurfID);
- const Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace.mySrcFace);
- Standard_Real aUf = 0.0, aUl = 0.0, aVf = 0.0, aVl = 0.0;
- aSurf->Bounds(aUf, aUl, aVf, aVl);
-
- const gp_Pnt aPnts[aNbPoints] = { aSurf->Value(aUf, aVf),
- aSurf->Value(aUl, aVf),
- aSurf->Value(aUl, aVl),
- aSurf->Value(aUf, aVl)};
-
- for(Standard_Integer i = 0; i < aNbPoints; i++)
- {
- FS_Vertex aVert;
-
- NodeInspector anInspector(myVertexVec, aPnts[i], myTolerance);
- Bnd_Box aBox;
- aBox.Add(aPnts[i]);
- aBox.Enlarge(myTolerance);
-
- theCells.Inspect(aBox.CornerMin().XYZ(), aBox.CornerMax().XYZ(), anInspector);
- NodeInspector::Target aResID = anInspector.GetResult();
-
- if(aResID < 0)
- {//Add new Vertex
- aVert.myID = myVertexVec.Length(); //because start index is 0
- aVert.myPnt = aPnts[i];
- aVert.myFaces.Append(theSurfID);
- myVertexVec.Append(aVert);
- aFace.SetVertex(i, aVert.myID);
-
- theCells.Add(aVert.myID, aBox.CornerMin().XYZ(), aBox.CornerMax().XYZ());
- }
- else
- {//Change existing vertex
- aFace.SetVertex(i, aResID);
- myVertexVec.ChangeValue(aResID).myFaces.Append(theSurfID);
- }
- }
-}
-
-//=======================================================================
-//function : FindEdges
-//purpose :
-//=======================================================================
-void BRepBuilderAPI_FastSewing::FindEdges(const Standard_Integer theSurfID)
-{
- const Standard_Integer aNbPoints = 4;
- FS_Face& aFace = myFaceVec.ChangeValue(theSurfID);
-
- const Standard_Integer aFirstInd[aNbPoints] = {0, 1, 3, 0};
- const Standard_Integer aLastInd[aNbPoints] = {1, 2, 2, 3};
-
- for(Standard_Integer i = 0; i < aNbPoints; i++)
- {
- const Standard_Integer aFirstVertIndex = aFirstInd[i],
- aLastVertIndex = aLastInd[i];
- const Standard_Integer aFirstVertID = aFace.myVertices[aFirstVertIndex],
- aLastVertID = aFace.myVertices[aLastVertIndex];
-
- if(aFirstVertID == aLastVertID)
- {//Edge is degenerated.
- CreateNewEdge(aFirstVertID, aLastVertID, theSurfID, i);
- continue;
- }
-
- //Must be minimal element from list
- const Standard_Integer anIntRes =
- IntersectionOfSets(myVertexVec.Value(aFirstVertID).myFaces,
- myVertexVec.Value(aLastVertID).myFaces);
-
- if((anIntRes < 0) || (anIntRes >= theSurfID))
- {
- CreateNewEdge(aFirstVertID, aLastVertID, theSurfID, i);
- }
- else
- {//if(theSurfID > anIntRes) => The edge has been processed earlier
- UpdateEdgeInfo(aFirstVertID, aLastVertID, theSurfID, i);
- }
- }
-}
-
-//=======================================================================
-//function : GetStatuses
-//purpose :
-//=======================================================================
-BRepBuilderAPI_FastSewing::FS_VARStatuses
- BRepBuilderAPI_FastSewing::GetStatuses(Standard_OStream* const theOS)
-{
- if(!theOS)
- return myStatusList;
-
- if(!myStatusList)
- {
- *theOS << "Fast Sewing OK!\n";
- return myStatusList;
- }
-
- //Number of bits
- const Standard_Integer aNumMax = 8*sizeof(myStatusList);
- FS_Statuses anIDS = static_cast<FS_Statuses>(0x0001);
- for(Standard_Integer i = 1; i <= aNumMax; i++,
- anIDS = static_cast<FS_Statuses>(anIDS << 1))
- {
- if((anIDS & myStatusList) == 0)
- continue;
-
- switch(anIDS)
- {
- case FS_Degenerated:
- *theOS << "Degenerated case. Try to reduce tolerance.\n";
- break;
- case FS_FindVertexError:
- *theOS << "Error while creating list of vertices.\n";
- break;
- case FS_FindEdgeError:
- *theOS << "Error while creating list of edges.\n";
- break;
- case FS_Exception:
- *theOS << "Exception during the operation.\n";
- break;
- case FS_FaceWithNullSurface:
- *theOS << "Source face has null surface.\n";
- break;
- case FS_NotNaturalBoundsFace:
- *theOS << "Source face has trimmed surface.\n";
- break;
- case FS_InfiniteSurface:
- *theOS << "Source face has the surface with infinite boundaries.\n";
- break;
- case FS_EmptyInput:
- *theOS << "Empty source data.\n";
- break;
-
-
- default:
- return myStatusList;
- }
- }
-
- return myStatusList;
-}
-
-//=======================================================================
-//function : Compute3DRange
-//purpose :
-//=======================================================================
-Standard_Real BRepBuilderAPI_FastSewing::Compute3DRange()
-{
- Bnd_Box aBox;
-
- for(Standard_Integer i = myFaceVec.Lower(); i <= myFaceVec.Upper(); i++)
- {
- FS_Face& aFace = myFaceVec.ChangeValue(i);
- const Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace.mySrcFace);
- if(aSurf.IsNull())
- continue;
- Standard_Real aUf = 0.0, aUl = 0.0, aVf = 0.0, aVl = 0.0;
- aSurf->Bounds(aUf, aUl, aVf, aVl);
-
- aBox.Add(aSurf->Value(aUf, aVf));
- aBox.Add(aSurf->Value(aUl, aVf));
- aBox.Add(aSurf->Value(aUl, aVl));
- aBox.Add(aSurf->Value(aUf, aVl));
- }
-
- Standard_Real aXm = 0.0, aYm = 0.0, aZm = 0.0, aXM = 0.0, aYM = 0.0, aZM = 0.0;
- aBox.Get(aXm, aYm, aZm, aXM, aYM, aZM);
- Standard_Real aDelta = aXM - aXm;
- aDelta = Max(aDelta, aYM - aYm);
- aDelta = Max(aDelta, aZM - aZm);
-
- return aDelta;
-}
-
-//=======================================================================
-//function : NodeInspector constructor
-//purpose :
-//=======================================================================
-BRepBuilderAPI_FastSewing::NodeInspector::
- NodeInspector(const NCollection_Vector<FS_Vertex>& theVec,
- const gp_Pnt& thePnt,
- const Standard_Real theTol):
-myVecOfVertexes(theVec), myPoint(thePnt), myResID(-1)
-{
- mySQToler = theTol*theTol;
-}
-
-//=======================================================================
-//function : ::NodeInspector::Inspect
-//purpose :
-//=======================================================================
-NCollection_CellFilter_Action BRepBuilderAPI_FastSewing::
- NodeInspector::Inspect(const Target theID)
-{
- const gp_Pnt& aPt = myVecOfVertexes.Value(theID).myPnt;
- const Standard_Real aSQDist = aPt.SquareDistance(myPoint);
- if(aSQDist < mySQToler)
- {
- mySQToler = aSQDist;
- myResID = theID;
- }
-
- return CellFilter_Keep;
-}
-
-//=======================================================================
-//function : ::FS_Edge::CreateTopologicalEdge
-//purpose :
-//=======================================================================
-void BRepBuilderAPI_FastSewing::FS_Edge::
- CreateTopologicalEdge(const NCollection_Vector<FS_Vertex>& theVertexVec,
- const NCollection_Vector<FS_Face>& theFaceVec,
- const Standard_Real theTol)
-{
- BRep_Builder aBuilder;
-
- TopoDS_Vertex aV1 = theVertexVec(myVertices[0]).myTopoVert;
- TopoDS_Vertex aV2 = theVertexVec(myVertices[1]).myTopoVert;
-
- aV1.Orientation(TopAbs_FORWARD);
- aV2.Orientation(TopAbs_REVERSED);
-
- Handle(Geom_Curve) a3dCurv;
- TopLoc_Location aLocation;
-
- const FS_Face& aFace = theFaceVec.Value(myFaces.Value(myFaces.Lower()));
-
- //3D-curves in 1st and 2nd faces are considered to be in same-range
- const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(aFace.mySrcFace, aLocation);
-
- Standard_Real aUf = 0.0, aUl = 0.0, aVf = 0.0, aVl = 0.0;
- aSurf->Bounds(aUf, aUl, aVf, aVl);
-
- Standard_Integer anEdgeID = -1;
- for(Standard_Integer anInd = 0; anInd < 4; anInd++)
- {
- if(myID == aFace.myEdges[anInd])
- {
- anEdgeID = anInd;
- break;
- }
- }
-
- //For DEBUG mode only
- Standard_ProgramError_Raise_if(anEdgeID < 0,
- "BRepBuilderAPI_FastSewing::FS_Edge::CreateTopologicalEdge: Single edge.");
-
- if(IsDegenerated())
- {
- Handle(Geom2d_Curve) a2dCurv = Get2DCurve(anEdgeID, aUf, aUl, aVf, aVl);
- const Standard_Real aFPar = a2dCurv->FirstParameter(),
- aLPar = a2dCurv->LastParameter();
-
- aBuilder.MakeEdge(myTopoEdge);
- aBuilder.UpdateEdge(myTopoEdge, a2dCurv, aSurf, aLocation, theTol);
- aBuilder.Add(myTopoEdge, aV1);
- aBuilder.Add(myTopoEdge, aV2);
- aBuilder.Range(myTopoEdge, aFPar, aLPar);
- aBuilder.Degenerated(myTopoEdge, Standard_True);
- return;
- }
-
- switch(anEdgeID)
- {
- case 0:
- a3dCurv = aSurf->VIso(aVf);
- break;
- case 1:
- a3dCurv = aSurf->UIso(aUl);
- break;
- case 2:
- a3dCurv = aSurf->VIso(aVl);
- break;
- case 3:
- a3dCurv = aSurf->UIso(aUf);
- break;
- default:
- Standard_OutOfRange::Raise("FS_Edge::CreateTopologicalEdge()");
- break;
- }
-
- aBuilder.MakeEdge(myTopoEdge, a3dCurv, theTol);
- aBuilder.Add(myTopoEdge, aV1);
- aBuilder.Add(myTopoEdge, aV2);
- aBuilder.Range(myTopoEdge, a3dCurv->FirstParameter(), a3dCurv->LastParameter());
-}
-
-//=======================================================================
-//function : ::FS_Face::CreateTopologicalWire
-//purpose :
-//=======================================================================
-void BRepBuilderAPI_FastSewing::FS_Face::
- CreateTopologicalWire(const NCollection_Vector<FS_Edge>& theEdgeVec,
- const Standard_Real theToler)
-{
- TopLoc_Location aLocation;
- //3D-curves in 1st and 2nd faces are considered to be in same-range
- const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(mySrcFace, aLocation);
- Standard_Real aUf = 0.0, aUl = 0.0, aVf = 0.0, aVl = 0.0;
- aSurf->Bounds(aUf, aUl, aVf, aVl);
-
- BRep_Builder aB;
- aB.MakeWire(myWire);
- for(Standard_Integer anEdge = 0; anEdge < 4; anEdge++)
- {
- Standard_ProgramError_Raise_if(myEdges[anEdge] < 0,
- "BRepBuilderAPI_FastSewing::FS_Face::CreateTopologicalWire: Wire is not closed.");
-
- const BRepBuilderAPI_FastSewing::FS_Edge& aFSEdge = theEdgeVec.Value(myEdges[anEdge]);
- TopAbs_Orientation anOri = anEdge < 2 ? TopAbs_FORWARD : TopAbs_REVERSED;
- TopoDS_Edge anTopE = aFSEdge.myTopoEdge;
-
- if(aFSEdge.IsDegenerated())
- {
- anTopE.Orientation(anOri);
- aB.Add(myWire, anTopE);
- continue;
- }
-
- //Check if 3D and 2D-curve have same-orientation.
- //If it is not, 2d-curve will be reversed.
- {
- Standard_Real aFirstPar = 0.0, aLastPar = 0.0;
-
- const Handle(Geom_Curve) a3dCurv = BRep_Tool::Curve(anTopE, aFirstPar, aLastPar);
- Handle(Geom2d_Curve) a2dCurv = Get2DCurve(anEdge, aUf, aUl, aVf, aVl);
- const gp_Pnt aPref(a3dCurv->Value(aFirstPar));
- const gp_Pnt2d aP2df(a2dCurv->Value(aFirstPar)), aP2dl(a2dCurv->Value(aLastPar));
- gp_Pnt aP3df(aSurf->Value(aP2df.X(), aP2df.Y()));
- gp_Pnt aP3dl(aSurf->Value(aP2dl.X(), aP2dl.Y()));
- aP3df.Transform(aLocation);
- aP3dl.Transform(aLocation);
- const Standard_Real aSqD1 = aP3df.SquareDistance(aPref);
- const Standard_Real aSqD2 = aP3dl.SquareDistance(aPref);
-
- if(aSqD2 < aSqD1)
- {
- a2dCurv = Get2DCurve(anEdge, aUf, aUl, aVf, aVl, Standard_True);
- anOri = TopAbs::Reverse(anOri);
- }
-
- aB.UpdateEdge(anTopE, a2dCurv, aSurf, aLocation, theToler);
- }
-
- anTopE.Orientation(anOri);
-
- aB.Add(myWire, anTopE);
- }
-
- myWire.Closed(Standard_True);
-}
-
-//=======================================================================
-//function : ::FS_Face::CreateTopologicalFace
-//purpose :
-//=======================================================================
-void BRepBuilderAPI_FastSewing::FS_Face::CreateTopologicalFace()
-{
- Standard_ProgramError_Raise_if(myWire.IsNull(),
- "BRepBuilderAPI_FastSewing::FS_Face::CreateTopologicalFace: Cannot create wire.");
-
- BRep_Builder aBuilder;
- myRetFace = TopoDS::Face(mySrcFace.EmptyCopied());
- aBuilder.Add(myRetFace, myWire);
- aBuilder.NaturalRestriction(myRetFace, Standard_True);
-}
+++ /dev/null
-//! Created on: 2015-04-24
-//! Created by: NIKOLAI BUKHALOV
-//! Copyright (c) 2015 OPEN CASCADE SAS
-//!
-//! This file is part of Open CASCADE Technology software library.
-//!
-//! This library is free software; you can redistribute it and/or modify it under
-//! the terms of the GNU Lesser General Public License version 2.1 as published
-//! by the Free Software Foundation, with special exception defined in the file
-//! OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-//! distribution for complete text of the license and disclaimer of any warranty.
-//!
-//! Alternatively, this file may be used under the terms of Open CASCADE
-//! commercial license or contractual agreement.
-
-#ifndef _BRepBuilderAPI_FastSewing_HeaderFile
-#define _BRepBuilderAPI_FastSewing_HeaderFile
-
-#include <Standard_Transient.hxx>
-#include <BRep_Builder.hxx>
-
-#include <NCollection_List.hxx>
-#include <NCollection_Sequence.hxx>
-#include <NCollection_Vector.hxx>
-#include <NCollection_CellFilter.hxx>
-
-#include <TopoDS_Edge.hxx>
-#include <TopoDS_Face.hxx>
-#include <TopoDS_Vertex.hxx>
-#include <TopoDS_Wire.hxx>
-
-class Handle(NCollection_IncAllocator);
-class Handle(Geom_Surface);
-
-//! This class performs fast sewing of surfaces (faces). It supposes
-//! that all surfaces are finite and are naturally restricted by their bounds.
-//! Moreover, it supposes that stitched together surfaces have the same parameterization
-//! along common boundaries, therefore it does not perform time-consuming check for
-//! SameParameter property of edges.
-//!
-//! For sewing, use this function as following:
-//! - set tolerance value (default tolerance is 1.E-06)
-//! - add all necessary surfaces (faces)
-//! - check status if adding is correctly completed.
-//! - compute -> Perform
-//! - retrieve the error status if any
-//! - retrieve the resulted shape
-class BRepBuilderAPI_FastSewing : public Standard_Transient
-{
-public:
- typedef unsigned int FS_VARStatuses;
-
- //! Enumeration of result statuses
- //ATTENTION!!! If you add new status, please
- // describe it in GetStatuses() method
- enum FS_Statuses
- {
- FS_OK = 0x00000000,
- FS_Degenerated = 0x00000001,
- FS_FindVertexError = 0x00000002,
- FS_FindEdgeError = 0x00000004,
- FS_FaceWithNullSurface = 0x00000008,
- FS_NotNaturalBoundsFace = 0x00000010,
- FS_InfiniteSurface = 0x00000020,
- FS_EmptyInput = 0x00000040,
- FS_Exception = 0x00000080
- };
-
-
- //! Creates an object with tolerance of connexity
- Standard_EXPORT BRepBuilderAPI_FastSewing(const Standard_Real theTolerance = 1.0e-06);
-
- //! Adds faces of a shape
- Standard_EXPORT Standard_Boolean Add(const TopoDS_Shape& theShape);
-
- //! Adds a surface
- Standard_EXPORT Standard_Boolean Add(const Handle(Geom_Surface)& theSurface);
-
- //! Compute resulted shape
- Standard_EXPORT void Perform (void) ;
-
- //! Sets tolerance
- void SetTolerance (const Standard_Real theToler)
- {
- myTolerance = theToler;
- }
-
- //! Returns tolerance
- Standard_Real GetTolerance() const
- {
- return myTolerance;
- }
-
- //! Returns resulted shape
- const TopoDS_Shape& GetResult() const
- {
- return myResShape;
- }
-
- //! Returns list of statuses. Print message if theOS != 0
- Standard_EXPORT FS_VARStatuses GetStatuses(Standard_OStream* const theOS = 0);
-
- DEFINE_STANDARD_RTTI(BRepBuilderAPI_FastSewing)
-
-protected:
- class NodeInspector;
-
- Standard_EXPORT void FindVertexes(const Standard_Integer theSurfID,
- NCollection_CellFilter<NodeInspector>& theCells);
- Standard_EXPORT void FindEdges(const Standard_Integer theSurfID);
- Standard_EXPORT void UpdateEdgeInfo(const Standard_Integer theIDPrevVertex,
- const Standard_Integer theIDCurrVertex,
- const Standard_Integer theFaceID,
- const Standard_Integer theIDCurvOnFace);
- Standard_EXPORT void CreateNewEdge( const Standard_Integer theIDPrevVertex,
- const Standard_Integer theIDCurrVertex,
- const Standard_Integer theFaceID,
- const Standard_Integer theIDCurvOnFace);
-
- Standard_EXPORT Standard_Real Compute3DRange();
-
- //! Sets status. Returns numeric value of the status set
- FS_VARStatuses SetStatus(FS_Statuses theStatus)
- {
- const FS_VARStatuses aStatusID = (FS_VARStatuses)(theStatus);
- myStatusList |= aStatusID;
- return aStatusID;
- }
-
- class FS_Edge;
-
- // Classes FS_Vertex, FS_Face and FS_Edge keep information about
- // relations between resulted members (e.g. which faces share this vertex? etc.)
-
- //! The struct corresponding to a vertex
- struct FS_Vertex
- {
- public:
- FS_Vertex(): myID(-1){};
-
- //! Creates topological member (vertex)
- void CreateTopologicalVertex(const Standard_Real theToler)
- {
- BRep_Builder aBuilder;
- aBuilder.MakeVertex(myTopoVert, myPnt, theToler);
- }
-
- //! Geometry point of this Vertex
- gp_Pnt myPnt;
- TopoDS_Vertex myTopoVert;
-
- //! List of faces and edges which share this vertex
- NCollection_List<Standard_Integer> myFaces;
- NCollection_List<Standard_Integer> myEdges;
-
- //! Indentifies the place of this Vertex in
- //! BRepBuilderAPI_FastSewing::myVertexVec list
- Standard_Integer myID;
- };
-
- //! The struct corresponding to an face
- struct FS_Face
- {
- FS_Face(): myID(-1)
- {
- for (Standard_Integer i = 0; i < 4; i++)
- {
- myVertices[i] = -1;
- myEdges[i] = -1;
- }
- };
- //! Creates topological members (wire and face)
- void CreateTopologicalWire(const NCollection_Vector<FS_Edge>& theEdgeVec,
- const Standard_Real theToler);
- void CreateTopologicalFace();
-
- //! Sets vertex
- void SetVertex(const Standard_Integer thePlaceID, const Standard_Integer theVertID)
- {
- Standard_RangeError_Raise_if((thePlaceID < 0) || (thePlaceID > 3),
- "FS_Face::SetVertex(): OUT of Range");
-
- myVertices[thePlaceID] = theVertID;
- }
-
- //! Sets edge
- void SetEdge(const Standard_Integer thePlaceID, const Standard_Integer theEdgeID)
- {
- Standard_RangeError_Raise_if((thePlaceID < 0) || (thePlaceID > 3),
- "FS_Face::SetEdge(): OUT of Range");
-
- myEdges[thePlaceID] = theEdgeID;
- }
-
- TopoDS_Face mySrcFace;
- TopoDS_Wire myWire;
- TopoDS_Face myRetFace;
-
- //! myEdges[i] number of the edge in myEdgeVec
- //! (i==0) <-> (V=Vf); (i==1) <-> (U=Ul);
- //! (i==2) <-> (V=Vl); (i==3) <-> (U=Uf)
- Standard_Integer myEdges[4];
- //! myVertices[i] is Start point of myEdges[i]
- Standard_Integer myVertices[4];
-
- //! Indentifies the place of this Face in
- //! BRepBuilderAPI_FastSewing::myFaceVec list
- Standard_Integer myID;
- };
-
- //! The struct corresponding to a edge
- class FS_Edge
- {
- public:
- FS_Edge(): myID(-1)
- {
- myVertices[0] = -1;
- myVertices[1] = -1;
- }
-
- FS_Edge(const Standard_Integer theIDVert1, const Standard_Integer theIDVert2): myID(-1)
- {
- myVertices[0] = theIDVert1;
- myVertices[1] = theIDVert2;
- };
-
- //! Creates topological member (TopoDS_Edge)
- void CreateTopologicalEdge( const NCollection_Vector<FS_Vertex>& theVertexVec,
- const NCollection_Vector<FS_Face>& theFaceVec,
- const Standard_Real theTol);
-
- //! Sets vertex
- void SetVertex(const Standard_Integer thePlaceID, const Standard_Integer theVertID)
- {
- Standard_RangeError_Raise_if((thePlaceID < 0) || (thePlaceID > 1),
- "FS_Face::SetVertex(): OUT of Range");
-
- myVertices[thePlaceID] = theVertID;
- }
-
- Standard_Boolean IsDegenerated() const
- {
- return (myVertices[0] == myVertices[1]);
- }
-
- //! List of faces which are shared with this edge
- //! Value is the index of this shape in myFaceVec array
- NCollection_Sequence<Standard_Integer> myFaces;
-
- //! Indentifies the place of this Edge in
- //! BRepBuilderAPI_FastSewing::myEdgeVec list
- Standard_Integer myID;
-
- TopoDS_Edge myTopoEdge;
- private:
- //! Index of the vertex in myVertexVec array
- Standard_Integer myVertices[2];
- };
-
- //! This inspector will find a node nearest to the given point
- //! not far than on the given tolerance
- class NodeInspector: public NCollection_CellFilter_InspectorXYZ
- {
- public:
- typedef Standard_Integer Target;
-
- NodeInspector(const NCollection_Vector<FS_Vertex>& theVec,
- const gp_Pnt& thePnt, const Standard_Real theTol);
-
- Standard_EXPORT NCollection_CellFilter_Action Inspect (const Target theId);
-
- Target GetResult()
- {
- return myResID;
- }
-
- private:
- NodeInspector& operator = (const NodeInspector&);
- const NCollection_Vector<FS_Vertex>& myVecOfVertexes;
- gp_Pnt myPoint;
- Standard_Real mySQToler;
- Target myResID;
- Standard_Boolean myIsFindingEnable;
- };
-private:
- TopoDS_Shape myResShape;
-
- // myFaceVec, myVertexVec and myEdgeVec lists are filled only once!!!!!
-
- //! Vector of faces
- NCollection_Vector<FS_Face> myFaceVec;
- //! Vector of Vertices
- NCollection_Vector<FS_Vertex> myVertexVec;
- //! Vector of edges
- NCollection_Vector<FS_Edge> myEdgeVec;
-
- //! Tolerance
- Standard_Real myTolerance;
-
- //! Bits of computation status
- FS_VARStatuses myStatusList;
-};
-
-#endif // _BRepBuilderAPI_FastSewing_HeaderFile
-
-DEFINE_STANDARD_HANDLE(BRepBuilderAPI_FastSewing, Standard_Transient)