mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-04 13:13:25 +03:00
Integration of OCCT 6.5.0 from SVN
This commit is contained in:
1
src/ShapeFix/FILES
Executable file
1
src/ShapeFix/FILES
Executable file
@@ -0,0 +1 @@
|
||||
ShapeFix_Wire_1.cxx
|
145
src/ShapeFix/ShapeFix.cdl
Executable file
145
src/ShapeFix/ShapeFix.cdl
Executable file
@@ -0,0 +1,145 @@
|
||||
-- File: ShapeFix.cdl
|
||||
-- Created: Wed Jun 3 12:07:35 1998
|
||||
-- Author: data exchange team
|
||||
-- <det@nnov.matra-dtv.fr>
|
||||
---Copyright: Matra Datavision 1998
|
||||
|
||||
|
||||
package ShapeFix
|
||||
|
||||
---Purpose: This package provides algorithms for fixing
|
||||
-- problematic (violating Open CASCADE requirements) shapes.
|
||||
-- Tools from package ShapeAnalysis are used for detecting the problems. The
|
||||
-- detecting and fixing is done taking in account various
|
||||
-- criteria implemented in BRepCheck package.
|
||||
-- Each class of package ShapeFix deals with one
|
||||
-- certain type of shapes or with some family of problems.
|
||||
|
||||
uses
|
||||
|
||||
gp,
|
||||
Geom,
|
||||
Geom2d,
|
||||
Geom2dAPI,
|
||||
GeomAbs,
|
||||
Adaptor3d,
|
||||
TCollection,
|
||||
TColStd,
|
||||
TopAbs,
|
||||
TopLoc,
|
||||
TopoDS,
|
||||
TopTools,
|
||||
Message,
|
||||
ShapeExtend,
|
||||
ShapeAnalysis,
|
||||
ShapeConstruct,
|
||||
ShapeBuild,
|
||||
Bnd
|
||||
|
||||
is
|
||||
|
||||
-- classes
|
||||
class Root;
|
||||
|
||||
class EdgeProjAux;
|
||||
|
||||
class Edge;
|
||||
---Purpose: Fixing different problems on edge
|
||||
|
||||
class Wire;
|
||||
---Purpose: Fixing different problems with wires
|
||||
|
||||
class Face;
|
||||
---Purpose: Fixing problems with face (orientation of wires and wrong wires)
|
||||
|
||||
class FixSmallFace;
|
||||
---Purpose: Fixing face with small size
|
||||
|
||||
class WireVertex;
|
||||
---Purpose: Fixing disconnected edges in the wire
|
||||
|
||||
class Wireframe;
|
||||
---Purpose: Provides methods to fix wireframe of shape
|
||||
|
||||
class FreeBounds;
|
||||
---Purpose: Fixing free bounds of the shape (connecting open wires)
|
||||
|
||||
class FaceConnect;
|
||||
---Purpose: Rebuilds connectivity between faces in shell
|
||||
|
||||
class Shell;
|
||||
---Purpose: Fixing orientation of faces in shell
|
||||
|
||||
class Solid;
|
||||
---Purpose: Creating solid from shell and orienting it to have finite volume
|
||||
|
||||
class ShapeTolerance;
|
||||
---Purpose: Modifying shape tolerances
|
||||
|
||||
class Shape;
|
||||
---Purpose: Fixing problem of shape.
|
||||
|
||||
class EdgeConnect;
|
||||
---Purpose: Rebuilds edges to connect with new vertices, was moved from ShapeBuild
|
||||
|
||||
class ComposeShell;
|
||||
---Purpose: Splits a (pseudo)face onto grid of faces (shell)
|
||||
|
||||
class SplitCommonVertex;
|
||||
---Purpose: Splits vertex which is common for two wires
|
||||
-- (for writing into STEP)
|
||||
|
||||
class WireSegment;
|
||||
---Purpose: Auxiliary class (data storage) for ComposeShell
|
||||
|
||||
class IntersectionTool;
|
||||
---Purpose: Tool for fixing selfintersecting wire
|
||||
-- and intersecting wires
|
||||
|
||||
--class OverlappingTool; now it is in package OverlapShape of Products
|
||||
---Purpose: Tool for fixing overlapping
|
||||
|
||||
class SplitTool;
|
||||
---Purpose: Tool for splitting and cutting edges; incudes methods
|
||||
-- used in OverlappingTool and IntersectionTool
|
||||
|
||||
class SequenceOfWireSegment instantiates Sequence from TCollection
|
||||
(WireSegment from ShapeFix);
|
||||
|
||||
class DataMapOfShapeBox2d instantiates DataMap from TCollection
|
||||
(Shape from TopoDS, Box2d from Bnd, ShapeMapHasher from TopTools);
|
||||
|
||||
|
||||
SameParameter (shape : Shape from TopoDS;
|
||||
enforce: Boolean;
|
||||
preci : Real = 0.0)
|
||||
returns Boolean;
|
||||
---Purpose : Runs SameParameter from BRepLib with these adaptations :
|
||||
-- <enforce> forces computations, else they are made only on
|
||||
-- Edges with flag SameParameter false
|
||||
-- <preci>, if not precised, is taken for each EDge as its own
|
||||
-- Tolerance
|
||||
-- Returns True when done, False if an exception has been raised
|
||||
-- In case of exception anyway, as many edges as possible have
|
||||
-- been processed
|
||||
|
||||
EncodeRegularity (shape: Shape from TopoDS; tolang: Real = 1.0e-10);
|
||||
---Purpose : Runs EncodeRegularity from BRepLib taking into account
|
||||
-- shared components of assemblies, so that each component
|
||||
-- is processed only once
|
||||
|
||||
RemoveSmallEdges (shape: in out Shape from TopoDS; Tolerance: Real; context: in out ReShape from ShapeBuild)
|
||||
returns Shape from TopoDS;
|
||||
---Purpose: Removes edges which are less than given tolerance from shape
|
||||
-- with help of ShapeFix_Wire::FixSmall()
|
||||
|
||||
FixVertexPosition(theshape: in out Shape from TopoDS;
|
||||
theTolerance: Real;
|
||||
thecontext: ReShape from ShapeBuild) returns Boolean;
|
||||
---Purpose: Fix position of the vertices having tolerance more tnan specified one.;
|
||||
|
||||
LeastEdgeSize(theshape: in out Shape from TopoDS) returns Real;
|
||||
---Purpose: Calculate size of least edge;
|
||||
|
||||
|
||||
end ShapeFix;
|
664
src/ShapeFix/ShapeFix.cxx
Executable file
664
src/ShapeFix/ShapeFix.cxx
Executable file
@@ -0,0 +1,664 @@
|
||||
// File: ShapeFix.cxx
|
||||
// Created: Fri Jan 21 12:00:39 2000
|
||||
// Author: data exchange team
|
||||
// <det@nnov.matra-dtv.fr>
|
||||
|
||||
|
||||
#include <ShapeFix.hxx>
|
||||
//:k2 abv 16.12.98: eliminating code duplication
|
||||
//pdn 18.12.98: checking deviation for SP edges
|
||||
//: abv 22.02.99: method FillFace() removed since PRO13123 is fixed
|
||||
//szv#4 S4163
|
||||
//szv#9:S4244:19Aug99: Added method FixWireGaps
|
||||
//szv#10:S4244:23Aug99: Added method FixFaceGaps
|
||||
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
|
||||
#include <Geom2d_Curve.hxx>
|
||||
#include <Geom_Curve.hxx>
|
||||
|
||||
#include <Precision.hxx>
|
||||
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
#include <Standard_Failure.hxx>
|
||||
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopLoc_Location.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <Geom_Surface.hxx>
|
||||
|
||||
//:i2
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <Geom_Plane.hxx>
|
||||
#include <ShapeFix_Edge.hxx>
|
||||
#include <Geom2dAdaptor_HCurve.hxx>
|
||||
#include <Adaptor3d_CurveOnSurface.hxx>
|
||||
#include <Geom_RectangularTrimmedSurface.hxx>
|
||||
#include <ShapeAnalysis_Surface.hxx>
|
||||
|
||||
#include <ShapeFix_Edge.hxx>
|
||||
#include <ShapeFix_Shape.hxx>
|
||||
#include <ShapeFix_Wire.hxx>
|
||||
#include <ShapeFix_Face.hxx>
|
||||
#include <TopoDS_Iterator.hxx>
|
||||
#include <GeomAdaptor_HSurface.hxx>
|
||||
#include <TopTools_MapOfShape.hxx>
|
||||
#include <BRepLib.hxx>
|
||||
|
||||
#include <ShapeAnalysis_Edge.hxx>
|
||||
#include <ShapeBuild_Edge.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <ShapeBuild_ReShape.hxx>
|
||||
#include <TColgp_SequenceOfPnt.hxx>
|
||||
#include <TopTools_ListOfShape.hxx>
|
||||
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
||||
#include <TopTools_SequenceOfShape.hxx>
|
||||
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
#include <TopExp.hxx>
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : SameParameter
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix::SameParameter(const TopoDS_Shape& shape,
|
||||
const Standard_Boolean enforce,
|
||||
const Standard_Real preci)
|
||||
{
|
||||
BRep_Builder B;
|
||||
//Standard_Integer nbexcp = 0;
|
||||
Standard_Integer nbfail = 0, numedge = 0;
|
||||
Standard_Boolean status = Standard_True;
|
||||
Standard_Real tol = preci;
|
||||
Standard_Boolean iatol = (tol > 0);
|
||||
Handle(ShapeFix_Edge) sfe = new ShapeFix_Edge;
|
||||
TopExp_Explorer ex(shape,TopAbs_EDGE);
|
||||
|
||||
while (ex.More()) {
|
||||
TopoDS_Edge E;
|
||||
while (ex.More()) {
|
||||
numedge ++;
|
||||
int ierr = 0;
|
||||
TopLoc_Location loc; //Standard_Real u0,u1; //szv#4:S4163:12Mar99 moved down unused
|
||||
E = TopoDS::Edge (ex.Current());
|
||||
ex.Next();
|
||||
|
||||
//pdn degenerated edges shuld be samerange and sameparameter.
|
||||
//if (BRep_Tool::Degenerated(E)) continue; // ne vaut pas
|
||||
if (!iatol) tol = BRep_Tool::Tolerance (E);
|
||||
if (enforce) {
|
||||
B.SameRange (E,Standard_False);
|
||||
B.SameParameter (E,Standard_False);
|
||||
}
|
||||
//:pdn if (BRep_Tool::SameParameter(E)) continue;
|
||||
// Handle(Geom_Curve) crv = BRep_Tool::Curve (E,loc,u0,u1);
|
||||
// if (crv.IsNull()) BRepLib::BuildCurve3d (E,tol);
|
||||
sfe->FixSameParameter (E); // et non BRepLib:: jusqu a K2-SEP97
|
||||
if (!BRep_Tool::SameParameter (E)) { ierr = 1; nbfail ++; }
|
||||
|
||||
if (ierr) {
|
||||
status = Standard_False;
|
||||
B.SameRange (E,Standard_False);
|
||||
B.SameParameter (E,Standard_False);
|
||||
}
|
||||
|
||||
} // -- end while
|
||||
}
|
||||
|
||||
//:i2 abv 21 Aug 98: ProSTEP TR8 Motor.rle face 710:
|
||||
// Update tolerance of edges on planes (no pcurves are stored)
|
||||
for ( TopExp_Explorer exp ( shape, TopAbs_FACE ); exp.More(); exp.Next() ) {
|
||||
TopoDS_Face face = TopoDS::Face ( exp.Current() );
|
||||
Handle(Geom_Surface) Surf = BRep_Tool::Surface ( face );
|
||||
|
||||
Handle(Geom_Plane) plane = Handle(Geom_Plane)::DownCast ( Surf );
|
||||
if ( plane.IsNull() ) {
|
||||
Handle(Geom_RectangularTrimmedSurface) GRTS =
|
||||
Handle(Geom_RectangularTrimmedSurface)::DownCast ( Surf );
|
||||
if ( ! GRTS.IsNull() )
|
||||
plane = Handle(Geom_Plane)::DownCast ( GRTS->BasisSurface() );
|
||||
if ( plane.IsNull() ) continue;
|
||||
}
|
||||
|
||||
// Handle(ShapeConstruct_ProjectCurveOnSurface) Proj = new ShapeConstruct_ProjectCurveOnSurface; //:k2 abv 16 Dec 98: use existing tool //smh#14
|
||||
// Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface ( plane );
|
||||
// Proj->Init ( sas, Precision::Confusion() ); // projection will be analitic
|
||||
Handle(GeomAdaptor_HSurface) AS = new GeomAdaptor_HSurface ( plane );
|
||||
for ( TopExp_Explorer ed ( face, TopAbs_EDGE ); ed.More(); ed.Next() ) {
|
||||
TopoDS_Edge edge = TopoDS::Edge ( ed.Current() );
|
||||
Standard_Real f, l;
|
||||
Handle(Geom_Curve) crv = BRep_Tool::Curve ( edge, f, l );
|
||||
if ( crv.IsNull() ) continue;
|
||||
|
||||
// Handle(Geom2d_Curve) c2d;
|
||||
// Proj->Perform ( crv, f, l, c2d );
|
||||
Handle(Geom2d_Curve) c2d = BRep_Tool::CurveOnSurface ( edge, face, f, l );;
|
||||
if ( c2d.IsNull() ) continue;
|
||||
Handle(Geom2dAdaptor_HCurve) GHPC = new Geom2dAdaptor_HCurve ( c2d, f, l );
|
||||
Adaptor3d_CurveOnSurface ACS(GHPC,AS);//sas->Adaptor3d());
|
||||
|
||||
Standard_Real tol0 = BRep_Tool::Tolerance ( edge );
|
||||
tol = tol0;
|
||||
Standard_Real tol2 = tol*tol;
|
||||
const Standard_Integer NCONTROL = 23;
|
||||
for ( Standard_Integer i=0; i < NCONTROL; i++ ) {
|
||||
Standard_Real par = ( f * ( NCONTROL - 1 - i ) + l * i ) / ( NCONTROL - 1 );
|
||||
gp_Pnt pnt = crv->Value ( par );
|
||||
gp_Pnt prj = ACS.Value( par );
|
||||
Standard_Real dist = pnt.SquareDistance(prj);
|
||||
if ( tol2 < dist ) tol2 = dist;
|
||||
}
|
||||
tol = 1.00005 * sqrt(tol2); // coeff: see trj3_pm1-ct-203.stp #19681, edge 10
|
||||
if ( tol >= tol0 ) {
|
||||
B.UpdateEdge ( edge, tol );
|
||||
for ( TopoDS_Iterator itV(edge); itV.More(); itV.Next() ) {
|
||||
TopoDS_Shape S = itV.Value();
|
||||
B.UpdateVertex ( TopoDS::Vertex ( S ), tol );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!status) {
|
||||
#ifdef DEB
|
||||
cout<<"** SameParameter not complete. On "<<numedge<<" Edges:";
|
||||
if (nbfail > 0) cout<<" "<<nbfail<<" Failed";
|
||||
//if (nbexcp > 0) cout<<" "<<nbexcp<<" Raised"; //SK original
|
||||
cout<<endl;
|
||||
#endif
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : EncodeRegularity
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
static void EncodeRegularity (const TopoDS_Shape& shape,
|
||||
const Standard_Real tolang,
|
||||
TopTools_MapOfShape &aMap)
|
||||
{
|
||||
TopoDS_Shape S = shape;
|
||||
TopLoc_Location L;
|
||||
S.Location ( L );
|
||||
if ( ! aMap.Add ( S ) ) return;
|
||||
|
||||
if ( S.ShapeType() == TopAbs_COMPOUND ||
|
||||
S.ShapeType() == TopAbs_COMPSOLID ) {
|
||||
for ( TopoDS_Iterator it(S); it.More(); it.Next() ) {
|
||||
EncodeRegularity ( it.Value(), tolang, aMap );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
OCC_CATCH_SIGNALS
|
||||
BRepLib::EncodeRegularity ( S, tolang );
|
||||
}
|
||||
catch(Standard_Failure) {
|
||||
#ifdef DEB
|
||||
cout << "Warning: Exception in ShapeFix::EncodeRegularity(): ";
|
||||
Standard_Failure::Caught()->Print ( cout );
|
||||
cout << endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void ShapeFix::EncodeRegularity (const TopoDS_Shape& shape,
|
||||
const Standard_Real tolang)
|
||||
{
|
||||
TopTools_MapOfShape aMap;
|
||||
::EncodeRegularity ( shape, tolang, aMap );
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : RemoveSmallEdges
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
TopoDS_Shape ShapeFix::RemoveSmallEdges (TopoDS_Shape& Shape,
|
||||
const Standard_Real Tolerance,
|
||||
Handle(ShapeBuild_ReShape)& context)
|
||||
{
|
||||
Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
|
||||
sfs->Init(Shape);
|
||||
sfs->SetPrecision(Tolerance);
|
||||
Handle(ShapeFix_Face)::DownCast(sfs->FixFaceTool())->FixMissingSeamMode() = Standard_False;
|
||||
Handle(ShapeFix_Face)::DownCast(sfs->FixFaceTool())->FixOrientationMode() = Standard_False;
|
||||
Handle(ShapeFix_Face)::DownCast(sfs->FixFaceTool())->FixSmallAreaWireMode() = Standard_False;
|
||||
sfs->FixWireTool()->ModifyTopologyMode() = Standard_True;
|
||||
//sfs.FixWireTool().FixReorderMode() = Standard_False;
|
||||
sfs->FixWireTool()->FixConnectedMode() = Standard_False;
|
||||
sfs->FixWireTool()->FixEdgeCurvesMode() = Standard_False;
|
||||
sfs->FixWireTool()->FixDegeneratedMode() = Standard_False;
|
||||
Handle(ShapeFix_Wire)::DownCast(sfs->FixWireTool())->FixSelfIntersectionMode() = Standard_False;
|
||||
Handle(ShapeFix_Wire)::DownCast(sfs->FixWireTool())->FixLackingMode() = Standard_False;
|
||||
Handle(ShapeFix_Wire)::DownCast(sfs->FixWireTool())->FixSmallMode() = Standard_True;
|
||||
sfs->Perform();
|
||||
TopoDS_Shape result = sfs->Shape();
|
||||
context = sfs->Context();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : ReplaceVertex
|
||||
//purpose : auxilary for FixVertexPosition
|
||||
//=======================================================================
|
||||
static TopoDS_Edge ReplaceVertex(const TopoDS_Edge& theEdge,
|
||||
const gp_Pnt theP,
|
||||
const Standard_Boolean theFwd)
|
||||
{
|
||||
TopoDS_Vertex aNewVertex;
|
||||
BRep_Builder aB;
|
||||
aB.MakeVertex(aNewVertex,theP,Precision::Confusion());
|
||||
TopoDS_Vertex aV1,aV2;
|
||||
if(theFwd) {
|
||||
aV1 = aNewVertex;
|
||||
aV1.Orientation( TopAbs_FORWARD);
|
||||
}
|
||||
else {
|
||||
aV2 = aNewVertex;
|
||||
aV2.Orientation( TopAbs_REVERSED);
|
||||
}
|
||||
ShapeBuild_Edge aSbe;
|
||||
TopoDS_Edge e1 = theEdge;
|
||||
TopAbs_Orientation Ori = e1.Orientation();
|
||||
e1.Orientation(TopAbs_FORWARD);
|
||||
TopoDS_Edge aNewEdge = aSbe.CopyReplaceVertices(e1,aV1,aV2);
|
||||
aNewEdge.Orientation(Ori);
|
||||
return aNewEdge;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : getNearPoint
|
||||
//purpose : auxilary for FixVertexPosition
|
||||
//=======================================================================
|
||||
static Standard_Real getNearPoint(const TColgp_SequenceOfPnt& aSeq1,
|
||||
const TColgp_SequenceOfPnt& aSeq2,
|
||||
gp_XYZ& acent)
|
||||
{
|
||||
Standard_Integer i =1;
|
||||
Standard_Integer ind1 =0,ind2 =0;
|
||||
Standard_Real mindist =RealLast();
|
||||
for( ; i <= aSeq1.Length(); i++) {
|
||||
gp_Pnt p1 = aSeq1.Value(i);
|
||||
Standard_Integer j=1;
|
||||
for( ; j <= aSeq2.Length(); j++) {
|
||||
gp_Pnt p2 = aSeq2.Value(j);
|
||||
Standard_Real d = p1.Distance(p2);
|
||||
if(fabs(d -mindist ) <= Precision::Confusion())
|
||||
continue;
|
||||
if(d < mindist) {
|
||||
mindist = d;
|
||||
ind1 =i;
|
||||
ind2 = j;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if(ind1 && ind2)
|
||||
acent = (aSeq1.Value(ind1).XYZ() + aSeq2.Value(ind2).XYZ())/2.0;
|
||||
return mindist;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : getNearestEdges
|
||||
//purpose : auxilary for FixVertexPosition
|
||||
//=======================================================================
|
||||
static Standard_Boolean getNearestEdges(TopTools_ListOfShape& theLEdges,
|
||||
const TopoDS_Vertex theVert,
|
||||
TopTools_SequenceOfShape& theSuitEdges,
|
||||
TopTools_SequenceOfShape& theRejectEdges,
|
||||
const Standard_Real theTolerance,
|
||||
gp_XYZ& thecentersuit,
|
||||
gp_XYZ& thecenterreject)
|
||||
{
|
||||
if(theLEdges.IsEmpty())
|
||||
return Standard_False;
|
||||
TopTools_MapOfShape aMapEdges;
|
||||
|
||||
TopTools_ListOfShape atempList;
|
||||
atempList= theLEdges;
|
||||
TopTools_ListIteratorOfListOfShape alIter(atempList);
|
||||
|
||||
TopoDS_Edge aEdge1 = TopoDS::Edge(alIter.Value());
|
||||
TopoDS_Vertex aVert11,aVert12;
|
||||
TopExp::Vertices(aEdge1, aVert11,aVert12 );
|
||||
aMapEdges.Add(aEdge1);
|
||||
Standard_Real aFirst1,aLast1;
|
||||
Handle(Geom_Curve) aCurve1 = BRep_Tool::Curve(aEdge1,aFirst1,aLast1);
|
||||
gp_Pnt p11;
|
||||
gp_Pnt p12;
|
||||
Standard_Boolean isFirst1 = theVert.IsSame(aVert11);
|
||||
Standard_Boolean isSame1 = aVert11.IsSame(aVert12);
|
||||
if( !aCurve1.IsNull()) {
|
||||
if(isFirst1)
|
||||
p11 = aCurve1->Value(aFirst1);
|
||||
else if(!isSame1)
|
||||
p11 = aCurve1->Value(aLast1);
|
||||
if(isSame1)
|
||||
p12 = aCurve1->Value(aLast1);
|
||||
}
|
||||
else return Standard_False;
|
||||
alIter.Next();
|
||||
TopTools_SequenceOfShape aseqreject;
|
||||
TopTools_SequenceOfShape aseqsuit;
|
||||
|
||||
Standard_Integer anumLoop =0;
|
||||
for( ; alIter.More(); ) {
|
||||
TopoDS_Edge aEdge = TopoDS::Edge(alIter.Value());
|
||||
if( aMapEdges.Contains(aEdge)) {
|
||||
atempList.Remove(alIter);
|
||||
continue;
|
||||
}
|
||||
|
||||
TopoDS_Vertex aVert1,aVert2;
|
||||
TopExp::Vertices(aEdge, aVert1,aVert2 );
|
||||
Standard_Real isFirst = theVert.IsSame(aVert1);
|
||||
Standard_Boolean isSame = aVert1.IsSame(aVert2);
|
||||
|
||||
Standard_Boolean isLoop = ((aVert1.IsSame(aVert11) && aVert2.IsSame(aVert12)) ||
|
||||
(aVert1.IsSame(aVert12) && aVert2.IsSame(aVert11)));
|
||||
if(isLoop /*&& !aseqsuit.Length()*/ && (atempList.Extent() >anumLoop)) {
|
||||
atempList.Append(aEdge);
|
||||
atempList.Remove(alIter);
|
||||
anumLoop++;
|
||||
continue;
|
||||
}
|
||||
aMapEdges.Add(aEdge);
|
||||
Standard_Real aFirst,aLast;
|
||||
Handle(Geom_Curve) aCurve = BRep_Tool::Curve(aEdge,aFirst,aLast);
|
||||
if( !aCurve.IsNull()) {
|
||||
gp_Pnt p1;
|
||||
gp_Pnt p2;
|
||||
if(isFirst)
|
||||
p1 = aCurve->Value(aFirst);
|
||||
else
|
||||
p1 = aCurve->Value(aLast);
|
||||
if(isSame)
|
||||
p2 = aCurve->Value(aLast);
|
||||
Standard_Real aMinDist = RealLast();
|
||||
gp_XYZ acent;
|
||||
if(!isSame && ! isSame1) {
|
||||
aMinDist = p1.Distance(p11);
|
||||
acent = (p1.XYZ() + p11.XYZ())/2.0;
|
||||
}
|
||||
else {
|
||||
TColgp_SequenceOfPnt aSeq1;
|
||||
TColgp_SequenceOfPnt aSeq2;
|
||||
aSeq1.Append(p11);
|
||||
if(isSame1)
|
||||
aSeq1.Append(p12);
|
||||
aSeq2.Append(p1);
|
||||
if(isSame)
|
||||
aSeq2.Append(p2);
|
||||
aMinDist = getNearPoint(aSeq1,aSeq2,acent);
|
||||
}
|
||||
|
||||
if(aMinDist > theTolerance) {
|
||||
if(!aseqreject.Length())
|
||||
thecenterreject = acent;
|
||||
aseqreject.Append(aEdge);
|
||||
}
|
||||
else {
|
||||
if(!aseqsuit.Length()) {
|
||||
thecentersuit = acent;
|
||||
aseqsuit.Append(aEdge);
|
||||
}
|
||||
else if(!isSame1)
|
||||
aseqsuit.Append(aEdge);
|
||||
else if((thecentersuit - acent).Modulus() < theTolerance)
|
||||
aseqsuit.Append(aEdge);
|
||||
else
|
||||
aseqreject.Append(aEdge);
|
||||
}
|
||||
|
||||
}
|
||||
atempList.Remove(alIter);
|
||||
}
|
||||
|
||||
Standard_Boolean isDone = (!aseqsuit.IsEmpty() || !aseqreject.IsEmpty());
|
||||
if(isDone) {
|
||||
if(aseqsuit.IsEmpty()) {
|
||||
theRejectEdges.Append(aEdge1);
|
||||
theLEdges.RemoveFirst();
|
||||
|
||||
getNearestEdges(theLEdges,theVert,theSuitEdges,theRejectEdges,
|
||||
theTolerance,thecentersuit,thecenterreject);
|
||||
}
|
||||
else {
|
||||
theSuitEdges.Append(aEdge1);
|
||||
theSuitEdges.Append(aseqsuit);
|
||||
theRejectEdges.Append(aseqreject);
|
||||
}
|
||||
}
|
||||
else
|
||||
theRejectEdges.Append(aEdge1);
|
||||
|
||||
return isDone;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : FixVertexPosition
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix::FixVertexPosition(TopoDS_Shape& theshape,
|
||||
const Standard_Real theTolerance,
|
||||
const Handle(ShapeBuild_ReShape)& thecontext)
|
||||
{
|
||||
TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdges;
|
||||
TopExp_Explorer aExp1(theshape,TopAbs_EDGE);
|
||||
for( ; aExp1.More(); aExp1.Next()) {
|
||||
TopoDS_Shape aVert1;
|
||||
Standard_Integer nV =1;
|
||||
TopoDS_Iterator aExp3(aExp1.Current());
|
||||
for( ; aExp3.More(); aExp3.Next(),nV++) {
|
||||
TopoDS_Shape aVert = aExp3.Value();
|
||||
if(nV ==1)
|
||||
aVert1 = aVert;
|
||||
else if(aVert1.IsSame(aVert))
|
||||
continue;
|
||||
if(aMapVertEdges.Contains(aVert))
|
||||
aMapVertEdges.ChangeFromKey(aVert).Append(aExp1.Current());
|
||||
else {
|
||||
TopTools_ListOfShape alEdges;
|
||||
alEdges.Append(aExp1.Current());
|
||||
aMapVertEdges.Add(aVert,alEdges);
|
||||
}
|
||||
}
|
||||
}
|
||||
Standard_Boolean isDone = Standard_False;
|
||||
Standard_Integer i=1;
|
||||
for( ; i <= aMapVertEdges.Extent(); i++) {
|
||||
TopoDS_Vertex aVert = TopoDS::Vertex(aMapVertEdges.FindKey(i));
|
||||
Standard_Real aTolVert = BRep_Tool::Tolerance(aVert);
|
||||
if(aTolVert <= theTolerance)
|
||||
continue;
|
||||
|
||||
BRep_Builder aB1;
|
||||
aB1.UpdateVertex(aVert,theTolerance);
|
||||
gp_Pnt aPvert = BRep_Tool::Pnt(aVert);
|
||||
gp_XYZ acenter(aPvert.XYZ()), acenterreject(aPvert.XYZ());
|
||||
|
||||
TopTools_SequenceOfShape aSuitEdges;
|
||||
TopTools_SequenceOfShape aRejectEdges;
|
||||
TopTools_ListOfShape aledges;
|
||||
aledges= aMapVertEdges.FindFromIndex(i);
|
||||
if(aledges.Extent() ==1)
|
||||
continue;
|
||||
//if tolerance of vertex is more than specified tolerance
|
||||
// check distance between curves and vertex
|
||||
|
||||
if(!getNearestEdges(aledges,aVert,aSuitEdges,aRejectEdges,theTolerance,acenter,acenterreject))
|
||||
continue;
|
||||
|
||||
//update vertex by nearest point
|
||||
Standard_Boolean isAdd = Standard_False;
|
||||
Standard_Integer k =1;
|
||||
for( ; k <= aSuitEdges.Length(); k++) {
|
||||
|
||||
TopoDS_Edge aEdgeOld = TopoDS::Edge(aSuitEdges.Value(k));
|
||||
TopoDS_Vertex aVert1,aVert2;
|
||||
TopExp::Vertices(aEdgeOld, aVert1,aVert2 );
|
||||
|
||||
Standard_Boolean isFirst = (aVert1.IsSame(aVert));
|
||||
Standard_Boolean isLast = (aVert2.IsSame(aVert));
|
||||
if(!isFirst && !isLast)
|
||||
continue;
|
||||
Standard_Real aFirst,aLast;
|
||||
Handle(Geom_Curve) aCurve;
|
||||
TopoDS_Edge aEdge = TopoDS::Edge(thecontext->Apply(aEdgeOld));
|
||||
|
||||
TopoDS_Vertex aVert1n,aVert2n;
|
||||
TopExp::Vertices(aEdge, aVert1n,aVert2n );
|
||||
aCurve = BRep_Tool::Curve(aEdge,aFirst,aLast);
|
||||
if( !aCurve.IsNull()) {
|
||||
gp_Pnt p1 = aCurve->Value(aFirst);
|
||||
gp_Pnt p2 = aCurve->Value(aLast);
|
||||
|
||||
//if distance between ends of curve more than specified tolerance
|
||||
//but vertices are the same that one of the vertex will be replaced.
|
||||
|
||||
Standard_Boolean isReplace = (aVert1n.IsSame(aVert2n) && p1.Distance(p2) >theTolerance);
|
||||
|
||||
//Standard_Real dd1 = (acenter - p1.XYZ()).Modulus();
|
||||
//Standard_Real dd2 = (acenter - p2.XYZ()).Modulus();
|
||||
if(isFirst) {
|
||||
if( k>2) {
|
||||
acenter += p1.XYZ();
|
||||
acenter /= 2.0;
|
||||
}
|
||||
if(isReplace) {
|
||||
TopoDS_Edge enew;
|
||||
if(p1.Distance(acenter) < p2.Distance(acenter))
|
||||
enew = ReplaceVertex(aEdge,p2,Standard_False);
|
||||
else
|
||||
enew = ReplaceVertex(aEdge,p1,Standard_True);
|
||||
thecontext->Replace(aEdge,enew);
|
||||
isDone = Standard_True;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if( k>2) {
|
||||
acenter += p2.XYZ();
|
||||
acenter /= 2.0;
|
||||
}
|
||||
if(isReplace) {
|
||||
TopoDS_Edge enew;
|
||||
if(p1.Distance(acenter) < p2.Distance(acenter))
|
||||
enew = ReplaceVertex(aEdge,p2,Standard_False);
|
||||
else
|
||||
enew = ReplaceVertex(aEdge,p1,Standard_True);
|
||||
thecontext->Replace(aEdge,enew);
|
||||
isDone = Standard_True;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
isAdd = Standard_True;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(isAdd && aPvert.Distance(acenter) > theTolerance)
|
||||
{
|
||||
|
||||
BRep_Builder aB;
|
||||
|
||||
// aB.UpdateVertex(aVert,Precision::Confusion());
|
||||
//else {
|
||||
isDone = Standard_True;
|
||||
TopoDS_Vertex aNewVertex;
|
||||
aB.MakeVertex(aNewVertex,acenter,Precision::Confusion());
|
||||
aNewVertex.Orientation(aVert.Orientation());
|
||||
thecontext->Replace(aVert,aNewVertex);
|
||||
|
||||
}
|
||||
|
||||
for( k =1; k <= aRejectEdges.Length(); k++) {
|
||||
TopoDS_Edge aEdgeOld = TopoDS::Edge( aRejectEdges.Value(k));
|
||||
TopoDS_Vertex aVert1,aVert2;
|
||||
TopExp::Vertices(aEdgeOld, aVert1,aVert2 );
|
||||
|
||||
Standard_Boolean isFirst = (aVert1.IsSame(aVert));
|
||||
Standard_Boolean isLast = (aVert2.IsSame(aVert));
|
||||
if(!isFirst && !isLast)
|
||||
continue;
|
||||
Standard_Boolean isSame = aVert1.IsSame(aVert2);
|
||||
Handle(Geom_Curve) aCurve;
|
||||
TopoDS_Edge aEdge = TopoDS::Edge(thecontext->Apply(aEdgeOld));
|
||||
|
||||
TopoDS_Vertex aVert1n,aVert2n;
|
||||
TopExp::Vertices(aEdge, aVert1n,aVert2n );
|
||||
|
||||
Standard_Real aFirst,aLast;
|
||||
aCurve = BRep_Tool::Curve(aEdge,aFirst,aLast);
|
||||
if( !aCurve.IsNull()) {
|
||||
gp_Pnt p1 = aCurve->Value(aFirst);
|
||||
gp_Pnt p2 = aCurve->Value(aLast);
|
||||
TopoDS_Edge enew;
|
||||
if(isFirst) {
|
||||
enew = ReplaceVertex(aEdge,p1,Standard_True);
|
||||
if(isSame)
|
||||
enew = ReplaceVertex(enew,p2,Standard_False);
|
||||
}
|
||||
else {
|
||||
enew = ReplaceVertex(aEdge,p2,Standard_False);
|
||||
if(isSame)
|
||||
enew = ReplaceVertex(enew ,p1,Standard_True);
|
||||
}
|
||||
|
||||
thecontext->Replace(aEdge,enew);
|
||||
isDone = Standard_True;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if(isDone)
|
||||
theshape = thecontext->Apply(theshape);
|
||||
return isDone;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : LeastEdgeSize
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Real ShapeFix::LeastEdgeSize(TopoDS_Shape& theShape)
|
||||
{
|
||||
Standard_Real aRes = RealLast();
|
||||
for(TopExp_Explorer exp(theShape,TopAbs_EDGE); exp.More(); exp.Next()) {
|
||||
TopoDS_Edge edge = TopoDS::Edge ( exp.Current() );
|
||||
Standard_Real first,last;
|
||||
Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge, first, last);
|
||||
if(!c3d.IsNull()) {
|
||||
Bnd_Box bb;
|
||||
bb.Add(c3d->Value(first));
|
||||
bb.Add(c3d->Value(last));
|
||||
bb.Add(c3d->Value((last+first)/2.));
|
||||
Standard_Real x1,x2,y1,y2,z1,z2,size;
|
||||
bb.Get(x1,y1,z1,x2,y2,z2);
|
||||
size = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) + (z2-z1)*(z2-z1);
|
||||
if(size<aRes) aRes = size;
|
||||
}
|
||||
}
|
||||
aRes = sqrt(aRes);
|
||||
return aRes;
|
||||
}
|
266
src/ShapeFix/ShapeFix_ComposeShell.cdl
Executable file
266
src/ShapeFix/ShapeFix_ComposeShell.cdl
Executable file
@@ -0,0 +1,266 @@
|
||||
-- File: ShapeFix_ComposeShell.cdl
|
||||
-- Created: Mon Apr 26 19:04:10 1999
|
||||
-- Author: Andrey BETENEV
|
||||
-- <abv@doomox.nnov.matra-dtv.fr>
|
||||
---Copyright: Matra Datavision 1999
|
||||
|
||||
|
||||
class ComposeShell from ShapeFix inherits Root from ShapeFix
|
||||
|
||||
---Purpose: This class is intended to create a shell from the composite
|
||||
-- surface (grid of surfaces) and set of wires.
|
||||
-- It may be either division of the supporting surface of the
|
||||
-- face, or creating a shape corresponding to face on composite
|
||||
-- surface which is missing in CAS.CADE but exists in some other
|
||||
-- systems.
|
||||
--
|
||||
-- It splits (if necessary) original face to several ones by
|
||||
-- splitting lines which are joint lines on a supplied grid of
|
||||
-- surfaces (U- and V- isolines of the composite surface).
|
||||
-- There are two modes of work, which differ in the way of
|
||||
-- handling faces on periodic surfaces:
|
||||
--
|
||||
-- - if ClosedMode is False (default), when splitting itself is
|
||||
-- done as if surface were not periodic. The periodicity of the
|
||||
-- underlying surface is taken into account by duplicating splitting
|
||||
-- lines in the periodic direction, as necessary to split all
|
||||
-- the wires (whole parametrical range of a face)
|
||||
-- In this mode, some regularization procedures are performed
|
||||
-- (indexation of splitted segments by patch numbers), and it is
|
||||
-- expected to be more reliable and robust in case of bad shapes
|
||||
--
|
||||
-- - if ClosedMode is True, when everything on a periodic surfaces
|
||||
-- is considered as modulo period. This allows to deal with wires
|
||||
-- which are closed in 3d but not in 2d, with wires which may be
|
||||
-- shifted on several periods in 2d etc. However, this mode is
|
||||
-- less reliable since some regularizations do not work for it.
|
||||
--
|
||||
-- The work is made basing on pcurves of the edges. These pcurves
|
||||
-- should already exist (for example, in the case of division of
|
||||
-- existing face), then they are taken as is. The existing pcurves
|
||||
-- should be assigned to one surface (face) for all edges,
|
||||
-- this surface (face) will be used only for accessing pcurves,
|
||||
-- and it may have any geometry.
|
||||
--
|
||||
-- All the modifications are recorded in the context tool
|
||||
-- (ShapeBuild_ReShape).
|
||||
|
||||
uses
|
||||
Lin2d from gp,
|
||||
Curve from Geom2d,
|
||||
Surface from Geom,
|
||||
Location from TopLoc,
|
||||
Edge from TopoDS,
|
||||
Face from TopoDS,
|
||||
Shape from TopoDS,
|
||||
Status from ShapeExtend,
|
||||
WireData from ShapeExtend,
|
||||
CompositeSurface from ShapeExtend,
|
||||
WireSegment from ShapeFix,
|
||||
Orientation from TopAbs,
|
||||
SequenceOfReal from TColStd,
|
||||
SequenceOfInteger from TColStd,
|
||||
SequenceOfShape from TopTools,
|
||||
SequenceOfWireSegment from ShapeFix,
|
||||
TransferParameters from ShapeAnalysis
|
||||
is
|
||||
Create returns ComposeShell from ShapeFix;
|
||||
---Purpose: Creates empty tool.
|
||||
|
||||
Init (me: mutable; Grid: CompositeSurface from ShapeExtend;
|
||||
L : Location from TopLoc;
|
||||
Face: Face from TopoDS;
|
||||
Prec: Real);
|
||||
---Purpose: Initializes with composite surface, face and precision.
|
||||
-- Here face defines both set of wires and way of getting
|
||||
-- pcurves. Precision is used (together with tolerance of edges)
|
||||
-- for handling subtle cases, such as tangential intersections.
|
||||
|
||||
ClosedMode (me: mutable) returns Boolean;
|
||||
---Purpose: Returns (modifiable) flag for special 'closed'
|
||||
-- mode which forces ComposeShell to consider
|
||||
-- all pcurves on closed surface as modulo period.
|
||||
-- This can reduce reliability, but allows to deal
|
||||
-- with wires closed in 3d but open in 2d (missing seam)
|
||||
-- Default is False
|
||||
---C++: return &
|
||||
|
||||
Perform (me: mutable)
|
||||
returns Boolean is virtual;
|
||||
---Purpose: Performs the work on already loaded data.
|
||||
|
||||
SplitEdges (me: mutable);
|
||||
---Purpose: Splits edges in the original shape by grid.
|
||||
-- This is a part of Perform() which does not produce any
|
||||
-- resulting shape; the only result is filled context
|
||||
-- where splittings are recorded.
|
||||
--
|
||||
-- NOTE: If edge is splitted, it is replaced by wire, and
|
||||
-- order of edges in the wire corresponds to FORWARD orientation
|
||||
-- of the edge.
|
||||
|
||||
Result (me) returns Shape from TopoDS;
|
||||
---Purpose: Returns resulting shell or face (or Null shape if not done)
|
||||
---C++: return const &
|
||||
|
||||
Status (me; status: Status from ShapeExtend) returns Boolean;
|
||||
---Purpose: Queries status of last call to Perform()
|
||||
-- OK : nothing done (some kind of error)
|
||||
-- DONE1: splitting is done, at least one new face created
|
||||
-- DONE2: splitting is done, several new faces obtained
|
||||
-- FAIL1: misoriented wire encountered (handled)
|
||||
-- FAIL2: recoverable parity error
|
||||
-- FAIL3: edge with no pcurve on supporting face
|
||||
-- FAIL4: unrecoverable algorithm error (parity check)
|
||||
|
||||
---Protected methods:
|
||||
|
||||
LoadWires (me; seqw: out SequenceOfWireSegment from ShapeFix)
|
||||
is protected;
|
||||
---Purpose: Fill sequence of wire segments by wires from myFace
|
||||
-- (pre-loaded). It performs reorder so that edges in segments
|
||||
-- are well-ordered. The context is applied to all wires
|
||||
-- before using them.
|
||||
|
||||
ComputeCode (me: mutable; wire : WireData from ShapeExtend;
|
||||
line : Lin2d from gp;
|
||||
begInd: Integer;
|
||||
endInd: Integer;
|
||||
begPar: Real;
|
||||
endPar: Real;
|
||||
IsInternal : Boolean = Standard_False)
|
||||
returns Integer is protected;
|
||||
---Purpose: Analyze tangencies and compute orientation code for wire segment
|
||||
-- between two intersections: tells if segment is on left or right side
|
||||
-- of cutting line, or tangent to it (by several points recomputed to 3d,
|
||||
-- distance is compared with tolerance of corresponding edge).
|
||||
|
||||
SplitWire (me: mutable; wire : in out WireSegment from ShapeFix;
|
||||
indexes : in out SequenceOfInteger from TColStd;
|
||||
values : SequenceOfReal from TColStd;
|
||||
vertices: out SequenceOfShape from TopTools;
|
||||
segcodes: SequenceOfInteger from TColStd;
|
||||
cutbyu : Boolean;
|
||||
cutindex: Integer)
|
||||
returns WireSegment from ShapeFix is protected;
|
||||
---Purpose: Splits edges in the wire by given indices of edges and
|
||||
-- parameters on them. Returns resulting wire and vertices
|
||||
-- corresponding to splitting parameters. If two consequtive
|
||||
-- splitting points are too near one to another (with tolerance
|
||||
-- of edge), edge is divided in single point. In the same way,
|
||||
-- splitting which is too near to end of edge, is not applied
|
||||
-- (end vertex is returned instead).
|
||||
--
|
||||
-- NOTE: If edge is splitted, it is replaced by wire, and
|
||||
-- order of edges in the wire corresponds to FORWARD orientation
|
||||
-- of the edge.
|
||||
|
||||
SplitByLine (me: mutable; wire : in out WireSegment from ShapeFix;
|
||||
line : Lin2d from gp;
|
||||
cutbyu : Boolean;
|
||||
cutindex: Integer;
|
||||
SplitLinePar : out SequenceOfReal from TColStd;
|
||||
SplitLineCode : out SequenceOfInteger from TColStd;
|
||||
SplitLineVertex: out SequenceOfShape from TopTools)
|
||||
returns Boolean is protected;
|
||||
---Purpose: Split edges in the wire by cutting line.
|
||||
-- Wires with FORWARD or REVERSED orientation are considered
|
||||
-- as closed.
|
||||
--
|
||||
-- All modifications (splitting) are recorded in context,
|
||||
-- except splitting of wires marked as EXTERNAL
|
||||
-- (they are supposed to be former cutting lines).
|
||||
--
|
||||
-- Method fills sequences of parameters of intersection points
|
||||
-- of cutting line with all edges, their types, and corresponding
|
||||
-- vertices (including ones created during splitting edges).
|
||||
|
||||
SplitByLine (me: mutable; seqw: in out SequenceOfWireSegment from ShapeFix;
|
||||
line: Lin2d from gp;
|
||||
cutbyu : Boolean;
|
||||
cutindex: Integer)
|
||||
is protected;
|
||||
---Purpose: Split edges in the sequence of wires by cutting line.
|
||||
-- Wires with FORWARD or REVERSED orientation are considered
|
||||
-- as closed.
|
||||
--
|
||||
-- Parts of cutting line which get inside the face (defined by
|
||||
-- parity check of intersections with all wires) are added
|
||||
-- into that sequence (with orientation EXTERNAL). Each part
|
||||
-- is represented by one-edge wire segment with no 3d curve.
|
||||
-- They share common vertices with all wires they intersect.
|
||||
--
|
||||
-- All modifications (splitting) are recorded in context,
|
||||
-- except splitting of wires marked as EXTERNAL
|
||||
-- (they are supposed to be former cutting lines).
|
||||
|
||||
SplitByGrid (me: mutable; seqw: in out SequenceOfWireSegment from ShapeFix)
|
||||
is protected;
|
||||
---Purpose: Split initial set of (closed) wires by grid of lines corresponding
|
||||
-- to joints between patches on the composite surface.
|
||||
-- Parts of joint lines which get inside the face are also added
|
||||
-- into the sequence as wires with orientation EXTERNAL.
|
||||
-- They share common vertices with all wires they intersect.
|
||||
-- All modifications (splitting) are recorded in context,
|
||||
-- except splitting of joint edge itself and wires marked as
|
||||
-- EXTERNAL (they supposed to be another joint edges).
|
||||
|
||||
BreakWires (me: mutable; seqw: in out SequenceOfWireSegment from ShapeFix)
|
||||
is protected;
|
||||
---Purpose: Break wires into open wire segments by common vertices
|
||||
-- (splitting points), so that each segment is either closed and
|
||||
-- not touching others, or touches others at ends (have common
|
||||
-- vertices).
|
||||
-- After that, each wire segment lies on its own patch of grid.
|
||||
|
||||
CollectWires (me: mutable; wires: out SequenceOfWireSegment from ShapeFix;
|
||||
seqw : in out SequenceOfWireSegment from ShapeFix )
|
||||
is protected;
|
||||
---Purpose: Collect set of wire segments (already splitted) into closed
|
||||
-- wires. This is done by traversing all the segments in allowed
|
||||
-- directions, starting only from the REVERSED and FORWARD and
|
||||
-- taking EXTERNAL as necessary in fork points. Forks are detected
|
||||
-- by common vertices. In fork point, most left way is seleccted
|
||||
-- among all possible ways.
|
||||
|
||||
MakeFacesOnPatch (me; faces: out SequenceOfShape from TopTools;
|
||||
surf : Surface from Geom;
|
||||
loops: in out SequenceOfShape from TopTools)
|
||||
is protected;
|
||||
---Purpose: Creates new faces on one path of grid. It dispatches given loops
|
||||
-- (wires) into one or several faces depending on their mutual
|
||||
-- position.
|
||||
|
||||
DispatchWires (me; faces : out SequenceOfShape from TopTools;
|
||||
wires : in out SequenceOfWireSegment from ShapeFix);
|
||||
---Purpose: Creates new faces from the set of (closed) wires. Each wire
|
||||
-- is put on corresponding patch in the composite surface,
|
||||
-- and all pcurves on the initial (pseudo)face are reassigned to
|
||||
-- that surface. If several wires are one inside another, single
|
||||
-- face is created.
|
||||
|
||||
SetTransferParamTool(me: mutable; TransferParam : TransferParameters from ShapeAnalysis);
|
||||
---Purpose: Sets tool for transfer parameters from 3d to 2d and vice versa.
|
||||
|
||||
GetTransferParamTool(me) returns TransferParameters from ShapeAnalysis;
|
||||
---Purpose: Gets tool for transfer parameters from 3d to 2d and vice versa.
|
||||
|
||||
fields
|
||||
|
||||
myGrid : CompositeSurface from ShapeExtend;
|
||||
myLoc : Location from TopLoc;
|
||||
myFace : Face from TopoDS; -- underlying face for pcurves (real or pseudo)
|
||||
myOrient : Orientation from TopAbs is protected; -- orientation of face
|
||||
myResult : Shape from TopoDS is protected;
|
||||
myStatus : Integer is protected;
|
||||
myUResolution: Real; -- summary resolution on grid (minimum on patches)
|
||||
myVResolution: Real;
|
||||
myTransferParamTool: TransferParameters from ShapeAnalysis;
|
||||
myInvertEdgeStatus : Boolean;
|
||||
myClosedMode : Boolean;
|
||||
myUClosed : Boolean;
|
||||
myVClosed : Boolean;
|
||||
myUPeriod : Real;
|
||||
myVPeriod : Real;
|
||||
|
||||
end ComposeShell;
|
2765
src/ShapeFix/ShapeFix_ComposeShell.cxx
Executable file
2765
src/ShapeFix/ShapeFix_ComposeShell.cxx
Executable file
File diff suppressed because it is too large
Load Diff
193
src/ShapeFix/ShapeFix_Edge.cdl
Executable file
193
src/ShapeFix/ShapeFix_Edge.cdl
Executable file
@@ -0,0 +1,193 @@
|
||||
-- File: ShapeFix_Edge.cdl
|
||||
-- Created: Wed Jun 17 13:31:39 1998
|
||||
-- Author: data exchange team
|
||||
-- <det@nnov.matra-dtv.fr>
|
||||
---Copyright: Matra Datavision 1998
|
||||
|
||||
|
||||
class Edge from ShapeFix inherits TShared from MMgt
|
||||
|
||||
---Purpose: Fixing invalid edge.
|
||||
-- Geometrical and/or topological inconsistency:
|
||||
-- - no 3d curve or pcurve,
|
||||
-- - mismatching orientation of 3d curve and pcurve,
|
||||
-- - incorrect SameParameter flag (curve deviation is greater than
|
||||
-- edge tolerance),
|
||||
-- - not adjacent curves (3d or pcurve) to the vertices.
|
||||
|
||||
uses
|
||||
Surface from Geom,
|
||||
Surface from ShapeAnalysis,
|
||||
Edge from TopoDS,
|
||||
Face from TopoDS,
|
||||
Location from TopLoc,
|
||||
Status from ShapeExtend,
|
||||
ProjectCurveOnSurface from ShapeConstruct
|
||||
|
||||
is
|
||||
Create returns Edge from ShapeFix;
|
||||
---Purpose: Empty constructor
|
||||
|
||||
Projector (me: mutable) returns ProjectCurveOnSurface from ShapeConstruct;
|
||||
---Purpose: Returns the projector used for recomputing missing pcurves
|
||||
-- Can be used for adjusting parameters of projector
|
||||
|
||||
FixRemovePCurve (me: mutable; edge: Edge from TopoDS;
|
||||
face: Face from TopoDS)
|
||||
returns Boolean;
|
||||
|
||||
FixRemovePCurve (me: mutable; edge : Edge from TopoDS;
|
||||
surface : Surface from Geom;
|
||||
location: Location from TopLoc)
|
||||
returns Boolean;
|
||||
---Purpose: Removes the pcurve(s) of the edge if it does not match the
|
||||
-- vertices
|
||||
-- Check is done
|
||||
-- Use : It is to be called when pcurve of an edge can be wrong
|
||||
-- (e.g., after import from IGES)
|
||||
-- Returns: True, if does not match, removed (status DONE)
|
||||
-- False, (status OK) if matches or (status FAIL) if no pcurve,
|
||||
-- nothing done
|
||||
|
||||
FixRemoveCurve3d (me: mutable; edge: Edge from TopoDS) returns Boolean;
|
||||
---Purpose: Removes 3d curve of the edge if it does not match the vertices
|
||||
-- Returns: True, if does not match, removed (status DONE)
|
||||
-- False, (status OK) if matches or (status FAIL) if no 3d curve,
|
||||
-- nothing done
|
||||
|
||||
FixAddPCurve (me: mutable; edge : Edge from TopoDS;
|
||||
face : Face from TopoDS;
|
||||
isSeam: Boolean;
|
||||
prec : Real = 0.0)
|
||||
returns Boolean;
|
||||
---Purpose: See method below for information
|
||||
|
||||
FixAddPCurve (me: mutable; edge : Edge from TopoDS;
|
||||
surface : Surface from Geom;
|
||||
location: Location from TopLoc;
|
||||
isSeam : Boolean;
|
||||
prec : Real = 0.0)
|
||||
returns Boolean;
|
||||
---Purpose: See method below for information
|
||||
|
||||
FixAddPCurve (me: mutable; edge : Edge from TopoDS;
|
||||
face : Face from TopoDS;
|
||||
isSeam : Boolean;
|
||||
surfana : Surface from ShapeAnalysis;
|
||||
prec : Real = 0.0)
|
||||
returns Boolean;
|
||||
---Purpose: See method below for information
|
||||
|
||||
FixAddPCurve (me: mutable; edge : Edge from TopoDS;
|
||||
surface : Surface from Geom;
|
||||
location: Location from TopLoc;
|
||||
isSeam : Boolean;
|
||||
surfana : Surface from ShapeAnalysis;
|
||||
prec : Real = 0.0)
|
||||
returns Boolean;
|
||||
---Purpose: Adds pcurve(s) of the edge if missing (by projecting 3d curve)
|
||||
-- Parameter isSeam indicates if the edge is a seam.
|
||||
-- The parameter <prec> defines the precision for calculations.
|
||||
-- If it is 0 (default), the tolerance of the edge is taken.
|
||||
-- Remark : This method is rather for internal use since it accepts parameter
|
||||
-- <surfana> for optimization of computations
|
||||
-- Use : It is to be called after FixRemovePCurve (if removed) or in any
|
||||
-- case when edge can have no pcurve
|
||||
-- Returns: True if pcurve was added, else False
|
||||
-- Status :
|
||||
-- OK : Pcurve exists
|
||||
-- FAIL1: No 3d curve
|
||||
-- FAIL2: fail during projecting
|
||||
-- DONE1: Pcurve was added
|
||||
-- DONE2: specific case of pcurve going through degenerated point on
|
||||
-- sphere encountered during projection (see class
|
||||
-- ShapeConstruct_ProjectCurveOnSurface for more info)
|
||||
|
||||
FixAddCurve3d (me: mutable; edge: Edge from TopoDS) returns Boolean;
|
||||
---Purpose: Tries to build 3d curve of the edge if missing
|
||||
-- Use : It is to be called after FixRemoveCurve3d (if removed) or in any
|
||||
-- case when edge can have no 3d curve
|
||||
-- Returns: True if 3d curve was added, else False
|
||||
-- Status :
|
||||
-- OK : 3d curve exists
|
||||
-- FAIL1: BRepLib::BuildCurve3d() has failed
|
||||
-- DONE1: 3d curve was added
|
||||
|
||||
FixVertexTolerance (me: mutable; edge: Edge from TopoDS;
|
||||
face: Face from TopoDS) returns Boolean;
|
||||
FixVertexTolerance (me: mutable; edge: Edge from TopoDS) returns Boolean;
|
||||
---Purpose: Increases the tolerances of the edge vertices to comprise
|
||||
-- the ends of 3d curve and pcurve on the given face
|
||||
-- (first method) or all pcurves stored in an edge (second one)
|
||||
-- Returns: True, if tolerances have been increased, otherwise False
|
||||
-- Status:
|
||||
-- OK : the original tolerances have not been changed
|
||||
-- DONE1: the tolerance of first vertex has been increased
|
||||
-- DONE2: the tolerance of last vertex has been increased
|
||||
|
||||
FixReversed2d (me: mutable; edge: Edge from TopoDS;
|
||||
face: Face from TopoDS)
|
||||
returns Boolean;
|
||||
|
||||
FixReversed2d (me: mutable; edge : Edge from TopoDS;
|
||||
surface : Surface from Geom;
|
||||
location: Location from TopLoc)
|
||||
returns Boolean;
|
||||
---Purpose: Fixes edge if pcurve is directed opposite to 3d curve
|
||||
-- Check is done by call to the function
|
||||
-- ShapeAnalysis_Edge::CheckCurve3dWithPCurve()
|
||||
-- Warning: For seam edge this method will check and fix the pcurve in only
|
||||
-- one direction. Hence, it should be called twice for seam edge:
|
||||
-- once with edge orientation FORWARD and once with REVERSED.
|
||||
-- Returns: False if nothing done, True if reversed (status DONE)
|
||||
-- Status: OK - pcurve OK, nothing done
|
||||
-- FAIL1 - no pcurve
|
||||
-- FAIL2 - no 3d curve
|
||||
-- DONE1 - pcurve was reversed
|
||||
|
||||
FixSameParameter (me: mutable; edge : Edge from TopoDS;
|
||||
tolerance: Real = 0.0)
|
||||
returns Boolean;
|
||||
---Purpose: Tries to make edge SameParameter and sets corresponding
|
||||
-- tolerance and SameParameter flag.
|
||||
-- First, it makes edge same range if SameRange flag is not set.
|
||||
--
|
||||
-- If flag SameParameter is set, this method calls the
|
||||
-- function ShapeAnalysis_Edge::CheckSameParameter() that
|
||||
-- calculates the maximal deviation of pcurves of the edge from
|
||||
-- its 3d curve. If deviation > tolerance, the tolerance of edge
|
||||
-- is increased to a value of deviation. If deviation < tolerance
|
||||
-- nothing happens.
|
||||
--
|
||||
-- If flag SameParameter is not set, this method chooses the best
|
||||
-- variant (one that has minimal tolerance), either
|
||||
-- a. only after computing deviation (as above) or
|
||||
-- b. after calling standard procedure BRepLib::SameParameter
|
||||
-- and computing deviation (as above). If <tolerance> > 0, it is
|
||||
-- used as parameter for BRepLib::SameParameter, otherwise,
|
||||
-- tolerance of the edge is used.
|
||||
--
|
||||
-- Use : Is to be called after all pcurves and 3d curve of the edge are
|
||||
-- correctly computed
|
||||
-- Remark : SameParameter flag is always set to True after this method
|
||||
-- Returns: True, if something done, else False
|
||||
-- Status : OK - edge was initially SameParameter, nothing is done
|
||||
-- FAIL1 - computation of deviation of pcurves from 3d curve has failed
|
||||
-- FAIL2 - BRepLib::SameParameter() has failed
|
||||
-- DONE1 - tolerance of the edge was increased
|
||||
-- DONE2 - flag SameParameter was set to True (only if
|
||||
-- BRepLib::SameParameter() did not set it)
|
||||
-- DONE3 - edge was modified by BRepLib::SameParameter() to SameParameter
|
||||
-- DONE4 - not used anymore
|
||||
-- DONE5 - if the edge resulting from BRepLib has been chosen, i.e. variant b. above
|
||||
-- (only for edges with not set SameParameter)
|
||||
|
||||
Status (me; status: Status from ShapeExtend) returns Boolean;
|
||||
---Purpose: Returns the status (in the form of True/False) of last Fix
|
||||
|
||||
fields
|
||||
|
||||
myStatus: Integer is protected;
|
||||
myProjector: ProjectCurveOnSurface from ShapeConstruct is protected;
|
||||
|
||||
end Edge;
|
816
src/ShapeFix/ShapeFix_Edge.cxx
Executable file
816
src/ShapeFix/ShapeFix_Edge.cxx
Executable file
@@ -0,0 +1,816 @@
|
||||
// abv 30 Dec 98: code optimizations
|
||||
//:o1 abv 16.02.99: updating vertices tolerance when edge is updated
|
||||
// rln 03.03.99 S4135: removed unnecessary check for Geom_SphericalSurface (as not V-closed)
|
||||
//:q8 abv 23.03.99: bm4_al_eye.stp #53710: avoid shifting pcurves for pseudo-seam
|
||||
//#78 rln 12.03.99 S4135: checking spatial closure with prec
|
||||
//#81 rln 15.03.99 S4135: for not SP edge chose the best result (either BRepLib or deviation only)
|
||||
//#82 rln 16.03.99 S4135: avoiding setting input precision into the edge in FixAddPCurve
|
||||
//:r4 abv 02.04.99 improving method FixSameParameter()
|
||||
//:s5 abv 22.04.99 Adding debug printouts in catch {} blocks
|
||||
// abv 05.05.99 S4137: method CopyPCurves moved to ShapeBuild_Edge
|
||||
#include <ShapeFix_Edge.ixx>
|
||||
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
#include <Standard_Failure.hxx>
|
||||
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRep_GCurve.hxx>
|
||||
#include <BRep_TEdge.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
|
||||
#include <BRep_ListOfCurveRepresentation.hxx>
|
||||
#include <BRepLib.hxx>
|
||||
|
||||
#include <Geom2d_Curve.hxx>
|
||||
#include <Geom2d_Line.hxx>
|
||||
#include <Geom2d_BSplineCurve.hxx>
|
||||
#include <Geom2d_TrimmedCurve.hxx>
|
||||
#include <Geom2d_BezierCurve.hxx>
|
||||
|
||||
#include <Geom_Curve.hxx>
|
||||
#include <GeomLib.hxx>
|
||||
|
||||
#include <Precision.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
|
||||
#include <ShapeAnalysis_Edge.hxx>
|
||||
#include <ShapeExtend.hxx>
|
||||
#include <ShapeBuild_Edge.hxx>
|
||||
#include <ShapeFix_ShapeTolerance.hxx>
|
||||
#include <Geom2d_OffsetCurve.hxx>
|
||||
#include <ShapeAnalysis_Curve.hxx>
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeFix_Edge
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
ShapeFix_Edge::ShapeFix_Edge()
|
||||
{
|
||||
myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
|
||||
myProjector = new ShapeConstruct_ProjectCurveOnSurface;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Projector
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Handle(ShapeConstruct_ProjectCurveOnSurface) ShapeFix_Edge::Projector()
|
||||
{
|
||||
return myProjector;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : FixRemovePCurve
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_Edge::FixRemovePCurve (const TopoDS_Edge& edge,
|
||||
const TopoDS_Face& face)
|
||||
{
|
||||
TopLoc_Location L;
|
||||
const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
|
||||
return FixRemovePCurve (edge, S, L);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixRemovePCurve
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_Edge::FixRemovePCurve (const TopoDS_Edge& edge,
|
||||
const Handle(Geom_Surface)& surface,
|
||||
const TopLoc_Location& location)
|
||||
{
|
||||
myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
|
||||
ShapeAnalysis_Edge EA;
|
||||
Standard_Boolean result = EA.CheckVerticesWithPCurve (edge, surface, location);
|
||||
if (result) ShapeBuild_Edge().RemovePCurve (edge, surface, location);
|
||||
return result;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixRemoveCurve3d
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_Edge::FixRemoveCurve3d (const TopoDS_Edge& edge)
|
||||
{
|
||||
myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
|
||||
ShapeAnalysis_Edge EA;
|
||||
Standard_Boolean result = EA.CheckVerticesWithCurve3d (edge);
|
||||
if (result) ShapeBuild_Edge().RemoveCurve3d (edge);
|
||||
return result;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixAddPCurve
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_Edge::FixAddPCurve (const TopoDS_Edge& edge,
|
||||
const TopoDS_Face& face,
|
||||
const Standard_Boolean isSeam,
|
||||
const Standard_Real prec)
|
||||
{
|
||||
TopLoc_Location L;
|
||||
const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
|
||||
return FixAddPCurve (edge, S, L, isSeam, prec);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixAddPCurve
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_Edge::FixAddPCurve (const TopoDS_Edge& edge,
|
||||
const Handle(Geom_Surface)& surface,
|
||||
const TopLoc_Location& location,
|
||||
const Standard_Boolean isSeam,
|
||||
const Standard_Real prec)
|
||||
{
|
||||
Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface (surface);
|
||||
return FixAddPCurve (edge, surface, location, isSeam, sas, prec);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixAddPCurve
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_Edge::FixAddPCurve (const TopoDS_Edge& edge,
|
||||
const TopoDS_Face& face,
|
||||
const Standard_Boolean isSeam,
|
||||
const Handle(ShapeAnalysis_Surface)& surfana,
|
||||
const Standard_Real prec)
|
||||
{
|
||||
TopLoc_Location L;
|
||||
const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
|
||||
return FixAddPCurve (edge, S, L, isSeam, surfana, prec);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixAddPCurve
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
//#12 rln 17/03/98 making this method to be more general : if a curve is
|
||||
//parallel to one iso let us translate it parallely in the direction to another
|
||||
//iso (which is located farther from aC2d). Thus, the requirement for closeness
|
||||
//to the surface bounds may be avoid.
|
||||
//For example, instead of Abs(theLoc.X()-uf) <= Tol) ... elseif (...-ul..)...
|
||||
//the comparison if (Abs(theLoc.X()-uf) <= Abs(theLoc.X()-ul)) .... can be used.
|
||||
|
||||
//The reason of this fix #12 is that seam is not sure to lie on the bound :
|
||||
//if a surface is periodic the whole contour may be shifted (e.g. ProSTEP,
|
||||
//file ug_exhaust-A.stp entity #284920)
|
||||
|
||||
static Handle(Geom2d_Curve) TranslatePCurve (const Handle(Geom_Surface)& aSurf,
|
||||
Handle(Geom2d_Curve)& aC2d,
|
||||
const Standard_Real& aTol)
|
||||
{
|
||||
Standard_Real uf,ul,vf,vl;
|
||||
aSurf->Bounds(uf,ul,vf,vl);
|
||||
|
||||
// cas d une ligne
|
||||
Handle(Geom2d_Line) theL2d = Handle(Geom2d_Line)::DownCast(aC2d);
|
||||
if (!theL2d.IsNull()) {
|
||||
gp_Pnt2d theLoc = theL2d->Location();
|
||||
gp_Dir2d theDir = theL2d->Direction();
|
||||
|
||||
gp_Pnt2d newLoc;
|
||||
Handle(Geom2d_Line) theNewL2d = theL2d;
|
||||
|
||||
//case UClosed
|
||||
if (Abs(theDir.X()) <= aTol && Abs(theDir.Y()) >= aTol) {
|
||||
if (Abs(theLoc.X() - uf) < Abs(theLoc.X() - ul))
|
||||
newLoc.SetCoord (theLoc.X() + (ul - uf), theLoc.Y());
|
||||
else
|
||||
newLoc.SetCoord (theLoc.X() - (ul - uf), theLoc.Y());
|
||||
theNewL2d = new Geom2d_Line(newLoc, theDir);
|
||||
}
|
||||
/* // case UClosed and line in U = UFirst
|
||||
if ((Abs(theLoc.X() - uf) <= aTol) &&
|
||||
(Abs(theDir.X()) <= aTol) &&
|
||||
(Abs(theDir.Y()) >= aTol)) {
|
||||
// on translate en ul
|
||||
gp_Pnt2d newLoc(ul, theLoc.Y());
|
||||
Handle(Geom2d_Line) theNewL2d = new Geom2d_Line(newLoc, theDir);
|
||||
return theNewL2d;
|
||||
}
|
||||
// cas UClosed and line in U = ULast
|
||||
if ((Abs(theLoc.X() - ul) <= aTol) &&
|
||||
(Abs(theDir.X()) <= aTol) &&
|
||||
(Abs(theDir.Y()) >= aTol)) {
|
||||
// on translate en uf
|
||||
gp_Pnt2d newLoc(uf, theLoc.Y());
|
||||
Handle(Geom2d_Line) theNewL2d = new Geom2d_Line(newLoc, theDir);
|
||||
return theNewL2d;
|
||||
}
|
||||
*/
|
||||
//case VClosed
|
||||
if (Abs(theDir.X()) >= aTol && Abs(theDir.Y()) <= aTol) {
|
||||
if (Abs(theLoc.Y() - vf) < Abs(theLoc.Y() - vl))
|
||||
newLoc.SetCoord (theLoc.X(), theLoc.Y() + (vl - vf));
|
||||
else
|
||||
newLoc.SetCoord (theLoc.X(), theLoc.Y() - (vl - vf));
|
||||
theNewL2d = new Geom2d_Line(newLoc, theDir);
|
||||
}
|
||||
/* // case VClosed and line in V = VFirst
|
||||
if ((Abs(theLoc.Y() - vf) <= aTol) &&
|
||||
(Abs(theDir.X()) >= aTol) &&
|
||||
(Abs(theDir.Y()) <= aTol)) {
|
||||
// on translate en vl
|
||||
gp_Pnt2d newLoc(theLoc.X(), vl);
|
||||
Handle(Geom2d_Line) theNewL2d = new Geom2d_Line(newLoc, theDir);
|
||||
return theNewL2d;
|
||||
}
|
||||
// cas VClosed and line in V = VLast
|
||||
if ((Abs(theLoc.Y() - vl) <= aTol) &&
|
||||
(Abs(theDir.X()) >= aTol) &&
|
||||
(Abs(theDir.Y()) <= aTol)) {
|
||||
// on translate en vf
|
||||
gp_Pnt2d newLoc(theLoc.X(), vf);
|
||||
Handle(Geom2d_Line) theNewL2d = new Geom2d_Line(newLoc, theDir);
|
||||
return theNewL2d;
|
||||
}
|
||||
*/
|
||||
// Other case not yet implemented
|
||||
#ifdef DEBUG
|
||||
cout << "TranslatePCurve not performed" << endl;
|
||||
#endif
|
||||
return theNewL2d;//*theL2d;
|
||||
}
|
||||
else {
|
||||
// cas bspline curve
|
||||
Handle(Geom2d_BSplineCurve)
|
||||
aBC = Handle(Geom2d_BSplineCurve)::DownCast(aC2d);
|
||||
if (aBC.IsNull()) {
|
||||
#ifdef DEBUG
|
||||
cout << "Untreated curve type in TranslatePCurve" << endl;
|
||||
#endif
|
||||
return aC2d;
|
||||
}
|
||||
Handle(Geom2d_BSplineCurve) newC =
|
||||
Handle(Geom2d_BSplineCurve)::DownCast(aBC->Copy());
|
||||
gp_Pnt2d FirstPoint = aBC->StartPoint();
|
||||
gp_Pnt2d LastPoint = aBC->EndPoint();
|
||||
gp_Vec2d theVector (FirstPoint, LastPoint);
|
||||
gp_Pnt2d p00(uf, vf), p01(uf,vl), p10(ul,vf);
|
||||
gp_Vec2d VectIsoUF(p00, p01);
|
||||
gp_Vec2d VectIsoVF(p00, p10);
|
||||
|
||||
gp_Trsf2d T;
|
||||
if (theVector.IsParallel(VectIsoUF, aTol)) {
|
||||
if (Abs(FirstPoint.X() - uf) < Abs(FirstPoint.X() - ul)) T.SetTranslation(p00, p10);
|
||||
else T.SetTranslation(p10, p00);
|
||||
newC->Transform(T);
|
||||
return newC;
|
||||
}
|
||||
/* // case UClosed and line in U = UFirst
|
||||
if (Abs(FirstPoint.X() - uf) <= aTol) {
|
||||
gp_Trsf2d T;
|
||||
T.SetTranslation(p00, p10);
|
||||
newC->Transform(T);
|
||||
return newC;
|
||||
}
|
||||
// case UClosed and line in U = ULast
|
||||
else if (Abs(FirstPoint.X() - ul) <= aTol) {
|
||||
gp_Trsf2d T;
|
||||
T.SetTranslation(p10, p00);
|
||||
newC->Transform(T);
|
||||
return newC;
|
||||
}
|
||||
else { // les courbes ne sont pas sur la couture
|
||||
return aC2d;
|
||||
}
|
||||
*/
|
||||
else if (theVector.IsParallel(VectIsoVF, aTol)) {
|
||||
//#ifdef DEBUG
|
||||
// cout << "other curve-VClosed Surface. TranslatePC not impl." << endl;
|
||||
//#endif
|
||||
if (Abs(FirstPoint.Y() - vf) < Abs(FirstPoint.Y() - vl)) T.SetTranslation(p00, p01);
|
||||
else T.SetTranslation(p01, p00);
|
||||
newC->Transform(T);
|
||||
return newC;
|
||||
}
|
||||
}
|
||||
// les courbes ne sont pas sur la couture
|
||||
return aC2d;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//static : Range3d
|
||||
//purpose : contournement du Range de BRep_Builder pour ne pas affecter
|
||||
// les ranges des pcurves.
|
||||
//=======================================================================
|
||||
|
||||
static void Range3d (const TopoDS_Edge& E,
|
||||
const Standard_Real First, const Standard_Real Last,
|
||||
const Standard_Real myPrecision)
|
||||
{
|
||||
// set the range to all the representations
|
||||
const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
|
||||
|
||||
BRep_ListOfCurveRepresentation& lcr = TE->ChangeCurves();
|
||||
BRep_ListIteratorOfListOfCurveRepresentation itcr(lcr);
|
||||
Handle(BRep_GCurve) GC;
|
||||
|
||||
while (itcr.More()) {
|
||||
GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
|
||||
if (!GC.IsNull()) {
|
||||
if (GC->IsCurve3D()) {
|
||||
GC->SetRange(First,Last);
|
||||
// Set the closedness flag to the correct value.
|
||||
Handle(Geom_Curve) C = GC->Curve3D();
|
||||
if ( !C.IsNull() ) {
|
||||
Standard_Boolean closed = C->Value(First).IsEqual(C->Value(Last),myPrecision);
|
||||
TE->Closed(closed);
|
||||
}
|
||||
}
|
||||
}
|
||||
itcr.Next();
|
||||
}
|
||||
|
||||
TE->Modified(Standard_True);
|
||||
}
|
||||
//=======================================================================
|
||||
//function : SameRange (Temp)
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
//:b0 abv 16 Feb 98: This is a copy of BRepLib::SameRange()
|
||||
// modified in order to be able to fix seam edges
|
||||
// NOTE: It is to be removed when is fixed either BRepLib::SameRange()
|
||||
// (concerning seam edges) or BRepLib::SameParameter() (concerning call
|
||||
// to GeomLib::SameRange() with 3d tolerance)
|
||||
|
||||
static void TempSameRange(const TopoDS_Edge& AnEdge,
|
||||
const Standard_Real Tolerance)
|
||||
{
|
||||
BRep_ListIteratorOfListOfCurveRepresentation an_Iterator
|
||||
((*((Handle(BRep_TEdge)*)&AnEdge.TShape()))->ChangeCurves());
|
||||
|
||||
Handle(Geom2d_Curve) Curve2dPtr, NewCurve2dPtr;
|
||||
Handle(Geom2d_Curve) Curve2dPtr2, NewCurve2dPtr2;
|
||||
TopLoc_Location LocalLoc ;
|
||||
|
||||
//Standard_Boolean IsSameRange = Standard_True //skl
|
||||
Standard_Boolean first_time_in = Standard_True, has_curve, has_closed_curve;
|
||||
Handle(BRep_GCurve) geometric_representation_ptr;
|
||||
Standard_Real first, current_first, last, current_last;
|
||||
|
||||
const Handle(Geom_Curve) C = BRep_Tool::Curve(AnEdge, LocalLoc,
|
||||
current_first, current_last);
|
||||
if (!C.IsNull()) first_time_in = Standard_False;
|
||||
|
||||
while (an_Iterator.More()) {
|
||||
geometric_representation_ptr =
|
||||
Handle(BRep_GCurve)::DownCast(an_Iterator.Value());
|
||||
if (! geometric_representation_ptr.IsNull()) {
|
||||
has_closed_curve = has_curve = Standard_False;
|
||||
first = geometric_representation_ptr->First();
|
||||
last = geometric_representation_ptr->Last();
|
||||
if (geometric_representation_ptr->IsCurveOnSurface()) {
|
||||
Curve2dPtr = geometric_representation_ptr->PCurve() ;
|
||||
has_curve = Standard_True ;
|
||||
}
|
||||
if (geometric_representation_ptr->IsCurveOnClosedSurface()) {
|
||||
Curve2dPtr2 = geometric_representation_ptr->PCurve2() ;
|
||||
has_closed_curve = Standard_True ;
|
||||
}
|
||||
if (has_curve || has_closed_curve) {
|
||||
if (first_time_in) {
|
||||
current_first = first;
|
||||
current_last = last;
|
||||
first_time_in = Standard_False;
|
||||
}
|
||||
|
||||
if (Abs(first - current_first) > Precision::PConfusion() || //:b8 abv 20 Feb 98: Confusion -> PConfusion
|
||||
Abs(last - current_last) > Precision::PConfusion() ) { //:b8
|
||||
Standard_Real oldFirst=0., oldLast=0.; //skl
|
||||
if (has_curve) {
|
||||
//pdn 20.05.99 Work around
|
||||
oldFirst = geometric_representation_ptr->First();
|
||||
oldLast = geometric_representation_ptr->Last();
|
||||
// 15.11.2002 PTV OCC966
|
||||
if(ShapeAnalysis_Curve::IsPeriodic(Curve2dPtr)) {
|
||||
Handle(Geom2d_TrimmedCurve) tc = new Geom2d_TrimmedCurve(Curve2dPtr,oldFirst,oldLast);
|
||||
Standard_Real shift = tc->FirstParameter()-oldFirst;
|
||||
oldFirst += shift;
|
||||
oldLast += shift;
|
||||
}
|
||||
//pdn 30.06.2000 work arounf on beziers
|
||||
Standard_Real oldFirstCurve1 = oldFirst, oldLastCurve1 = oldLast;
|
||||
if(Curve2dPtr->IsKind(STANDARD_TYPE(Geom2d_BezierCurve))) {
|
||||
|
||||
Standard_Real preci = Precision::PConfusion();
|
||||
if ( Abs(oldFirst) > preci || Abs(oldLast-1) > preci ) {
|
||||
Handle(Geom2d_BezierCurve) bezier = Handle(Geom2d_BezierCurve)::DownCast(Curve2dPtr->Copy());
|
||||
bezier->Segment(oldFirst,oldLast);
|
||||
Curve2dPtr = bezier;
|
||||
}
|
||||
oldFirstCurve1 = 0;
|
||||
oldLastCurve1 = 1;
|
||||
}
|
||||
|
||||
GeomLib::SameRange(Tolerance, Curve2dPtr,
|
||||
oldFirstCurve1,
|
||||
oldLastCurve1,
|
||||
current_first, current_last, NewCurve2dPtr);
|
||||
geometric_representation_ptr->PCurve(NewCurve2dPtr) ;
|
||||
}
|
||||
if (has_closed_curve) {
|
||||
|
||||
Standard_Real oldFirstCurve2 = oldFirst, oldLastCurve2 = oldLast;
|
||||
|
||||
if(Curve2dPtr2->IsKind(STANDARD_TYPE(Geom2d_BezierCurve))) {
|
||||
|
||||
Standard_Real preci = Precision::PConfusion();
|
||||
if ( Abs(oldFirst) > preci || Abs(oldLast-1) > preci ) {
|
||||
Handle(Geom2d_BezierCurve) bezier = Handle(Geom2d_BezierCurve)::DownCast(Curve2dPtr2->Copy());
|
||||
bezier->Segment(oldFirst,oldLast);
|
||||
Curve2dPtr2 = bezier;
|
||||
}
|
||||
oldFirstCurve2 = 0;
|
||||
oldLastCurve2 = 1;
|
||||
}
|
||||
|
||||
GeomLib::SameRange(Tolerance, Curve2dPtr2,
|
||||
oldFirstCurve2,
|
||||
oldLastCurve2,
|
||||
current_first, current_last, NewCurve2dPtr2);
|
||||
geometric_representation_ptr->PCurve2(NewCurve2dPtr2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
an_Iterator.Next();
|
||||
}
|
||||
BRep_Builder B;
|
||||
B.Range(TopoDS::Edge(AnEdge), current_first, current_last);
|
||||
B.SameRange(AnEdge, Standard_True);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixAddPCurve
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_Edge::FixAddPCurve (const TopoDS_Edge& edge,
|
||||
const Handle(Geom_Surface)& surf,
|
||||
const TopLoc_Location& location,
|
||||
const Standard_Boolean isSeam,
|
||||
const Handle(ShapeAnalysis_Surface)& sas,
|
||||
const Standard_Real prec)
|
||||
{
|
||||
ShapeAnalysis_Edge sae;
|
||||
myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
|
||||
if ( (!isSeam && sae.HasPCurve (edge, surf, location))||
|
||||
( isSeam && sae.IsSeam(edge, surf, location))) return Standard_False;
|
||||
|
||||
// PCurve on Plane not computed
|
||||
if (surf->IsKind(STANDARD_TYPE(Geom_Plane))) return Standard_False;
|
||||
|
||||
// Standard_Real step = 0;
|
||||
try {
|
||||
OCC_CATCH_SIGNALS
|
||||
Standard_Real First, Last;
|
||||
|
||||
BRep_Builder B;
|
||||
|
||||
Standard_Real preci = ( prec >0. ? prec : BRep_Tool::Tolerance(edge) );
|
||||
Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge, /*Loc,*/ First, Last);
|
||||
// Handle(Geom_Curve) c3d = BRep_Tool::Curve(E, First, Last);
|
||||
if (c3d.IsNull() || (Abs(Last-First) <Precision::PConfusion())) {
|
||||
myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1);
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
// Trim the curve to avoid problem ??
|
||||
// c3d = Handle(Geom_Curve)::DownCast(c3d->Transformed(Loc.Transformation()));
|
||||
// Handle(Geom_TrimmedCurve) theTrimmed = new Geom_TrimmedCurve(c3d, First, Last);
|
||||
// c3d = theTrimmed;
|
||||
|
||||
// step = 1;
|
||||
|
||||
// A present, on projette
|
||||
// stat : 0 pas pu faire, 1 analytique, 2 approx
|
||||
Handle(Geom2d_Curve) c2d;
|
||||
Standard_Real a1, b1;
|
||||
if ( ! sae.HasPCurve (edge, surf, location)) {
|
||||
myProjector->Init ( sas, preci );
|
||||
myProjector->Perform (c3d,First,Last,c2d);
|
||||
// stat = 2 : reinterpoler la c3d ?
|
||||
if ( myProjector->Status ( ShapeExtend_DONE4 ) )
|
||||
myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_DONE2);
|
||||
a1 = First;
|
||||
b1 = Last;
|
||||
}
|
||||
else {
|
||||
sae.PCurve ( edge, surf, location, c2d, a1, b1, Standard_False );
|
||||
}
|
||||
|
||||
// step = 2;
|
||||
|
||||
// adding by skl 28.03.2003 for usung Line instead of BSpline
|
||||
Standard_Real fp=0.,lp=0.;
|
||||
Standard_Boolean isLine=Standard_False;
|
||||
if(c2d->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) {
|
||||
Handle(Geom2d_TrimmedCurve) tc = Handle(Geom2d_TrimmedCurve)::DownCast(c2d);
|
||||
if(tc->BasisCurve()->IsKind(STANDARD_TYPE(Geom2d_Line))) {
|
||||
fp = tc->FirstParameter();
|
||||
lp = tc->LastParameter();
|
||||
isLine = Standard_True;
|
||||
}
|
||||
}
|
||||
|
||||
if (isSeam) {
|
||||
// On ne sait pas laquelle est Forward. Au PIF. La geometrie Forward
|
||||
// sera mise a jour dans ComputeWire
|
||||
Handle(Geom2d_Curve) c2d2 = Handle(Geom2d_Curve)::DownCast(c2d->Copy());
|
||||
// ATTENTION : TranslatePCurve reconstruit une Line // bords, en
|
||||
// intuitant U ou V ...
|
||||
// Ici, on exploite les infos deja connues
|
||||
Standard_Real uf,ul,vf,vl;
|
||||
surf->Bounds (uf,ul,vf,vl);
|
||||
//#4 rln 19/02/98 ProSTEP ug_exhaust-A.stp entity #284920 (thoroidal surface)
|
||||
//#13 rln 17/03/98 (updating fix #4) call to TranslatePCurve in the case
|
||||
//when a surface is either u- and vclosed or neither u- nor vclosed
|
||||
//#78 rln 12.03.99 S4135: checking spatial closure with prec
|
||||
if (sas->IsUClosed(prec) && ! sas->IsVClosed(prec) //rln S4135 sphere is not considered as V-closed anymore ||
|
||||
/* rln S4135 sas->Surface()->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) */ ) {//:d9 abv 17 Mar 98: any sphere
|
||||
gp_Vec2d tranvec (ul-uf,0);
|
||||
c2d2->Translate (tranvec);
|
||||
}
|
||||
else if (sas->IsVClosed(prec) && ! sas->IsUClosed(prec) ) {
|
||||
gp_Vec2d tranvec (0,vl-vf);
|
||||
c2d2->Translate (tranvec);
|
||||
}
|
||||
else if ( sas->IsUClosed() && sas->IsVClosed() ) { //:q8 abv 23 Mar 99: bm4_al_eye.stp #53710: avoid shifting pcurves for pseudo-seam
|
||||
// Doublement fermee (ex tore) : on lance la charge
|
||||
c2d2 = TranslatePCurve(sas->Surface(), c2d2, prec);
|
||||
}
|
||||
B.UpdateEdge (edge,c2d,c2d2,surf,location, 0.); //#82 rln 16.03.99: preci
|
||||
// if ( c2d->IsKind (STANDARD_TYPE(Geom2d_BoundedCurve)) )
|
||||
// B.Range (edge,surf,location,c2d->FirstParameter(),c2d->LastParameter());
|
||||
B.Range (edge,surf,location,a1,b1);
|
||||
}
|
||||
else {
|
||||
B.UpdateEdge (edge,c2d,surf,location, 0.); //#82 rln 16.03.99: preci
|
||||
}
|
||||
|
||||
if ( isLine ) {
|
||||
B.Range(edge,surf,location,fp,lp);
|
||||
B.SameParameter(edge,Standard_False);
|
||||
B.SameRange(edge,Standard_False);
|
||||
}
|
||||
|
||||
// Conclusion
|
||||
// step = 3;
|
||||
if ( myProjector->Status ( ShapeExtend_DONE3 ) ) {
|
||||
Standard_Real G3dCFirst = c3d->FirstParameter();
|
||||
Standard_Real G3dCLast = c3d->LastParameter();
|
||||
B.UpdateEdge(edge, c3d, 0.);
|
||||
Range3d(edge, G3dCFirst, G3dCLast, 0.);
|
||||
}
|
||||
} // end try
|
||||
catch(Standard_Failure) {
|
||||
myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL2);
|
||||
#ifdef DEB //:s5
|
||||
cout << "Warning: ShapeFix_Edge::FixAddPCurve(): Exception: ";
|
||||
Standard_Failure::Caught()->Print(cout); cout << endl;
|
||||
#endif
|
||||
}
|
||||
myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixAddCurve3d
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_Edge::FixAddCurve3d(const TopoDS_Edge& edge)
|
||||
{
|
||||
myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
|
||||
ShapeAnalysis_Edge EA;
|
||||
if ( BRep_Tool::Degenerated ( edge ) || EA.HasCurve3d (edge) ) return Standard_False;
|
||||
if(!BRep_Tool::SameRange(edge))
|
||||
TempSameRange(edge,Precision::PConfusion());
|
||||
|
||||
if (!ShapeBuild_Edge().BuildCurve3d(edge)) {
|
||||
myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1);
|
||||
return Standard_False;
|
||||
}
|
||||
myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixVertexTolerance
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_Edge::FixVertexTolerance(const TopoDS_Edge& edge,
|
||||
const TopoDS_Face& face)
|
||||
{
|
||||
myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
|
||||
ShapeAnalysis_Edge sae;
|
||||
Standard_Real toler1, toler2;
|
||||
if (!sae.CheckVertexTolerance (edge, face, toler1, toler2)) return Standard_False;
|
||||
if (sae.Status (ShapeExtend_DONE1))
|
||||
myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
|
||||
if (sae.Status (ShapeExtend_DONE2))
|
||||
myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE2);
|
||||
BRep_Builder B;
|
||||
TopoDS_Vertex V1 = sae.FirstVertex(edge);
|
||||
TopoDS_Vertex V2 = sae.LastVertex(edge);
|
||||
B.UpdateVertex (V1, toler1);
|
||||
B.UpdateVertex (V2, toler2);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixVertexTolerance
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_Edge::FixVertexTolerance(const TopoDS_Edge& edge)
|
||||
{
|
||||
myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
|
||||
ShapeAnalysis_Edge sae;
|
||||
Standard_Real toler1, toler2;
|
||||
if (!sae.CheckVertexTolerance (edge, toler1, toler2)) return Standard_False;
|
||||
if (sae.Status (ShapeExtend_DONE1))
|
||||
myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
|
||||
if (sae.Status (ShapeExtend_DONE2))
|
||||
myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE2);
|
||||
BRep_Builder B;
|
||||
TopoDS_Vertex V1 = sae.FirstVertex(edge);
|
||||
TopoDS_Vertex V2 = sae.LastVertex(edge);
|
||||
B.UpdateVertex (V1, toler1);
|
||||
B.UpdateVertex (V2, toler2);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixReversed2d
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_Edge::FixReversed2d (const TopoDS_Edge& edge,
|
||||
const TopoDS_Face& face)
|
||||
{
|
||||
TopLoc_Location L;
|
||||
const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
|
||||
return FixReversed2d (edge, S, L);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixReversed2d
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_Edge::FixReversed2d (const TopoDS_Edge& edge,
|
||||
const Handle(Geom_Surface)& surface,
|
||||
const TopLoc_Location& location)
|
||||
{
|
||||
myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
|
||||
|
||||
ShapeAnalysis_Edge EA;
|
||||
EA.CheckCurve3dWithPCurve (edge, surface, location);
|
||||
if (EA.Status (ShapeExtend_FAIL1))
|
||||
myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1);
|
||||
if (EA.Status (ShapeExtend_FAIL2))
|
||||
myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL2);
|
||||
if ( ! EA.Status (ShapeExtend_DONE) ) return Standard_False;
|
||||
|
||||
Handle(Geom2d_Curve) c2d;
|
||||
Standard_Real f,l;
|
||||
EA.PCurve (edge, surface, location, c2d, f, l, Standard_False);
|
||||
//#46 rln 01.12.98 buc40130, entity 272 (4-th curve)
|
||||
Standard_Real newf = c2d->ReversedParameter (l), newl = c2d->ReversedParameter (f);
|
||||
c2d->Reverse();
|
||||
BRep_Builder B;
|
||||
//will break seams! B.UpdateEdge (edge, c2d, surface, location, Precision::Confusion());
|
||||
B.Range (edge, surface, location, newf, newl);
|
||||
//#51 rln 15.12.98 pro6562 entity 2788
|
||||
//Because of numerical accuracy the range on B-Splines (moreover, on any curve!)
|
||||
//the range is changed
|
||||
Standard_Real first, last;
|
||||
BRep_Tool::Range (edge, first, last);
|
||||
if (first != newf || last != newl) {
|
||||
B.SameRange (edge, Standard_False);
|
||||
B.SameParameter (edge, Standard_False);
|
||||
}
|
||||
myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : FixSameParameter
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_Edge::FixSameParameter(const TopoDS_Edge& edge,
|
||||
const Standard_Real tolerance)
|
||||
{
|
||||
myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
|
||||
|
||||
if ( BRep_Tool::Degenerated ( edge ) ) {
|
||||
BRep_Builder B;
|
||||
if ( ! BRep_Tool::SameRange (edge) )
|
||||
TempSameRange ( edge, Precision::PConfusion() );
|
||||
B.SameParameter ( edge, Standard_True );
|
||||
return Standard_False;
|
||||
}
|
||||
ShapeFix_ShapeTolerance SFST;
|
||||
ShapeAnalysis_Edge sae;
|
||||
BRep_Builder B;
|
||||
|
||||
TopoDS_Edge copyedge;
|
||||
TopoDS_Vertex V1 = sae.FirstVertex (edge);
|
||||
TopoDS_Vertex V2 = sae.LastVertex (edge);
|
||||
Standard_Real TolFV = ( V1.IsNull() ? 0. : BRep_Tool::Tolerance ( V1 ) );
|
||||
Standard_Real TolLV = ( V2.IsNull() ? 0. : BRep_Tool::Tolerance ( V2 ) );
|
||||
Standard_Real tol = BRep_Tool::Tolerance (edge);
|
||||
|
||||
Standard_Boolean wasSP = BRep_Tool::SameParameter ( edge ), SP = Standard_False;
|
||||
{
|
||||
try {
|
||||
OCC_CATCH_SIGNALS
|
||||
if ( ! BRep_Tool::SameRange (edge) )
|
||||
TempSameRange ( edge, Precision::PConfusion() );
|
||||
//#81 rln 15.03.99 S4135: for not SP edge choose the best result (either BRepLib or deviation only)
|
||||
if ( ! wasSP ) {
|
||||
//create copyedge as copy of edge with the same vertices and copy of pcurves on the same surface(s)
|
||||
copyedge = ShapeBuild_Edge().Copy ( edge, Standard_False );
|
||||
B.SameParameter ( copyedge, Standard_False );
|
||||
BRepLib::SameParameter ( copyedge, ( tolerance >= Precision::Confusion() ?
|
||||
tolerance : tol ) );
|
||||
SP = BRep_Tool::SameParameter ( copyedge );
|
||||
if ( ! SP ) myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
|
||||
}
|
||||
}
|
||||
catch(Standard_Failure) {
|
||||
#ifdef DEB
|
||||
cout << "\nWarning: ShapeFix_Edge: Exception in SameParameter: ";
|
||||
Standard_Failure::Caught()->Print(cout); cout << endl;
|
||||
#endif
|
||||
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
|
||||
}
|
||||
}
|
||||
|
||||
// compute deviation on the original pcurves
|
||||
Standard_Real maxdev;
|
||||
B.SameParameter ( edge, Standard_True );
|
||||
sae.CheckSameParameter ( edge, maxdev );
|
||||
if ( sae.Status ( ShapeExtend_FAIL2 ) )
|
||||
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
|
||||
|
||||
// if BRepLib was OK, compare and select the best variant
|
||||
if ( SP ) {
|
||||
Standard_Real BRLTol = BRep_Tool::Tolerance ( copyedge ), BRLDev;
|
||||
sae.CheckSameParameter ( copyedge, BRLDev );
|
||||
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
|
||||
if ( BRLTol < BRLDev ) BRLTol = BRLDev;
|
||||
|
||||
//chose the best result
|
||||
if ( BRLTol < maxdev ) {
|
||||
if ( sae.Status ( ShapeExtend_FAIL2 ) )
|
||||
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
|
||||
//copy pcurves and tolerances from copyedge
|
||||
ShapeBuild_Edge().CopyPCurves ( edge, copyedge );
|
||||
maxdev = BRLTol;
|
||||
SFST.SetTolerance (edge, BRLTol, TopAbs_EDGE);
|
||||
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE5 );
|
||||
}
|
||||
}
|
||||
//restore tolerances because they could be modified by BRepLib
|
||||
if ( ! V1.IsNull() ) SFST.SetTolerance ( V1, Max (maxdev, TolFV), TopAbs_VERTEX);
|
||||
if ( ! V2.IsNull() ) SFST.SetTolerance ( V2, Max (maxdev, TolLV), TopAbs_VERTEX);
|
||||
|
||||
if ( maxdev > tol ) {
|
||||
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
|
||||
B.UpdateEdge ( edge, maxdev );
|
||||
FixVertexTolerance(edge);
|
||||
}
|
||||
|
||||
if ( ! wasSP && ! SP ) myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
|
||||
return Status ( ShapeExtend_DONE );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Status
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_Edge::Status(const ShapeExtend_Status status) const
|
||||
{
|
||||
return ShapeExtend::DecodeStatus (myStatus, status);
|
||||
}
|
44
src/ShapeFix/ShapeFix_EdgeConnect.cdl
Executable file
44
src/ShapeFix/ShapeFix_EdgeConnect.cdl
Executable file
@@ -0,0 +1,44 @@
|
||||
-- File: ShapeFix_EdgeConnect.cdl
|
||||
-- Created: Tue May 11 11:27:03 1999
|
||||
-- Author: Sergei ZERTCHANINOV
|
||||
-- <szv@nnov>
|
||||
---Copyright: Matra Datavision 1999
|
||||
|
||||
|
||||
class EdgeConnect from ShapeFix
|
||||
|
||||
---Purpose : Makes vertices to be shared to connect edges,
|
||||
-- updates positions and tolerances for shared vertices.
|
||||
-- Accepts edges bounded by two vertices each.
|
||||
|
||||
uses
|
||||
DataMapOfShapeShape from TopTools,
|
||||
DataMapOfShapeListOfShape from TopTools,
|
||||
Edge from TopoDS, Shape from TopoDS
|
||||
|
||||
is
|
||||
|
||||
Create returns EdgeConnect from ShapeFix;
|
||||
|
||||
Add (me : in out; aFirst : Edge from TopoDS; aSecond : Edge from TopoDS);
|
||||
---Purpose : Adds information on connectivity between start vertex
|
||||
-- of second edge and end vertex of first edge,
|
||||
-- taking edges orientation into account
|
||||
|
||||
Add (me : in out; aShape : Shape from TopoDS);
|
||||
---Purpose : Adds connectivity information for the whole shape.
|
||||
-- Note: edges in wires must be well ordered
|
||||
-- Note: flag Closed should be set for closed wires
|
||||
|
||||
Build (me : in out);
|
||||
---Purpose : Builds shared vertices, updates their positions and tolerances
|
||||
|
||||
Clear (me : in out);
|
||||
---Purpose : Clears internal data structure
|
||||
|
||||
fields
|
||||
|
||||
myVertices : DataMapOfShapeShape from TopTools; -- Map of pairs (vertex, shared)
|
||||
myLists : DataMapOfShapeListOfShape from TopTools; -- Map of pairs (shared, list of vertices/edges)
|
||||
|
||||
end EdgeConnect;
|
291
src/ShapeFix/ShapeFix_EdgeConnect.cxx
Executable file
291
src/ShapeFix/ShapeFix_EdgeConnect.cxx
Executable file
@@ -0,0 +1,291 @@
|
||||
// File: ShapeFix_EdgeConnect.cxx
|
||||
// Created: Tue May 11 11:27:03 1999
|
||||
// Author: Sergei ZERTCHANINOV
|
||||
// <szv@nnov>
|
||||
// Copyright: Matra Datavision 1999
|
||||
|
||||
#include <ShapeFix_EdgeConnect.ixx>
|
||||
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopoDS_Wire.hxx>
|
||||
#include <TopTools_ListOfShape.hxx>
|
||||
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
||||
#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
|
||||
#include <BRep_TEdge.hxx>
|
||||
#include <BRep_GCurve.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <gp_XYZ.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <TColgp_SequenceOfXYZ.hxx>
|
||||
|
||||
//#define POSITION_USES_MEAN_POINT
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeFix_EdgeConnect
|
||||
//=======================================================================
|
||||
|
||||
ShapeFix_EdgeConnect::ShapeFix_EdgeConnect () {}
|
||||
|
||||
//=======================================================================
|
||||
//function : Add
|
||||
//purpose : Adds connectivity information for two edges
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_EdgeConnect::Add (const TopoDS_Edge& aFirst, const TopoDS_Edge& aSecond)
|
||||
{
|
||||
// Select vertices to connect
|
||||
TopoDS_Vertex theFirstVertex = TopExp::LastVertex( aFirst, Standard_True );
|
||||
TopoDS_Vertex theSecondVertex = TopExp::FirstVertex( aSecond, Standard_True );
|
||||
|
||||
// Make necessary bindings
|
||||
if ( myVertices.IsBound( theFirstVertex ) ) {
|
||||
// First vertex is bound - find shared vertex
|
||||
TopoDS_Vertex theFirstShared = TopoDS::Vertex( myVertices( theFirstVertex ) );
|
||||
if ( myVertices.IsBound( theSecondVertex ) ) {
|
||||
// Second vertex is bound - find shared vertex
|
||||
TopoDS_Vertex theSecondShared = TopoDS::Vertex( myVertices( theSecondVertex ) );
|
||||
if ( !theFirstShared.IsSame(theSecondShared) ) {
|
||||
// Concatenate lists
|
||||
TopTools_ListOfShape& theFirstList = myLists( theFirstShared );
|
||||
TopTools_ListOfShape& theSecondList = myLists( theSecondShared );
|
||||
for ( TopTools_ListIteratorOfListOfShape theIterator( theSecondList );
|
||||
theIterator.More();
|
||||
theIterator.Next() ) {
|
||||
// Rebind shared vertex for current one
|
||||
myVertices( theIterator.Value() ) = theFirstShared;
|
||||
// Skip the following edge
|
||||
theIterator.Next();
|
||||
}
|
||||
// Append second list to the first one
|
||||
theFirstList.Append( theSecondList );
|
||||
// Unbind the second shared vertex
|
||||
myLists.UnBind( theSecondShared );
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Bind second vertex with shared vertex of the first one
|
||||
myVertices.Bind( theSecondVertex, theFirstShared );
|
||||
// Add second vertex and second edge to the list
|
||||
TopTools_ListOfShape& theFirstList = myLists( theFirstShared );
|
||||
theFirstList.Append( theSecondVertex );
|
||||
theFirstList.Append( aSecond );
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( myVertices.IsBound( theSecondVertex ) ) {
|
||||
// Second vertex is bound - find shared vertex
|
||||
TopoDS_Vertex& theSecondShared = TopoDS::Vertex( myVertices( theSecondVertex ) );
|
||||
// Bind first vertex with shared vertex of the second one
|
||||
myVertices.Bind( theFirstVertex, theSecondShared );
|
||||
// Add first vertex and first edge to the list
|
||||
TopTools_ListOfShape& theSecondList = myLists( theSecondShared );
|
||||
theSecondList.Append( theFirstVertex );
|
||||
theSecondList.Append( aFirst );
|
||||
}
|
||||
else {
|
||||
// None is bound - create new bindings
|
||||
myVertices.Bind( theFirstVertex, theFirstVertex );
|
||||
myVertices.Bind( theSecondVertex, theFirstVertex );
|
||||
TopTools_ListOfShape theNewList;
|
||||
theNewList.Append( theFirstVertex );
|
||||
theNewList.Append( aFirst );
|
||||
theNewList.Append( theSecondVertex );
|
||||
theNewList.Append( aSecond );
|
||||
myLists.Bind( theFirstVertex, theNewList );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Add
|
||||
//purpose : Adds connectivity information for the whole shape
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_EdgeConnect::Add (const TopoDS_Shape& aShape)
|
||||
{
|
||||
for ( TopExp_Explorer expw( aShape, TopAbs_WIRE ); expw.More(); expw.Next() ) {
|
||||
TopoDS_Wire theWire = TopoDS::Wire(expw.Current());
|
||||
TopExp_Explorer expe( theWire, TopAbs_EDGE );
|
||||
if (expe.More()) {
|
||||
// Obtain the first edge and remember it
|
||||
TopoDS_Edge theEdge = TopoDS::Edge(expe.Current());
|
||||
TopoDS_Edge theFirst = theEdge;
|
||||
expe.Next();
|
||||
for (; expe.More(); expe.Next()) {
|
||||
// Obtain second edge and connect it
|
||||
TopoDS_Edge theNext = TopoDS::Edge(expe.Current());
|
||||
Add( theEdge, theNext );
|
||||
theEdge = theNext;
|
||||
}
|
||||
// Connect first and last edges if wire is closed
|
||||
if (theWire.Closed()) Add( theEdge, theFirst );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Build
|
||||
//purpose : Builds shared vertices
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_EdgeConnect::Build ()
|
||||
{
|
||||
TopTools_ListIteratorOfListOfShape theLIterator;
|
||||
BRep_ListIteratorOfListOfCurveRepresentation theCIterator;
|
||||
|
||||
TColgp_SequenceOfXYZ thePositions;
|
||||
gp_XYZ thePosition;
|
||||
Standard_Real theMaxDev;
|
||||
BRep_Builder theBuilder;
|
||||
|
||||
// Iterate on shared vertices
|
||||
for ( TopTools_DataMapIteratorOfDataMapOfShapeListOfShape theSIterator( myLists );
|
||||
theSIterator.More();
|
||||
theSIterator.Next() ) {
|
||||
TopoDS_Vertex theSharedVertex = TopoDS::Vertex( theSIterator.Key() );
|
||||
const TopTools_ListOfShape& theList = theSIterator.Value();
|
||||
|
||||
thePositions.Clear();
|
||||
|
||||
// Iterate on edges, accumulating positions
|
||||
for ( theLIterator.Initialize( theList );
|
||||
theLIterator.More();
|
||||
theLIterator.Next() ) {
|
||||
TopoDS_Vertex& theVertex = TopoDS::Vertex( theLIterator.Value() );
|
||||
theLIterator.Next();
|
||||
TopoDS_Edge& theEdge = TopoDS::Edge( theLIterator.Value() );
|
||||
|
||||
// Determine usage of curve bound points
|
||||
TopoDS_Vertex theStart, theEnd;
|
||||
theEdge.Orientation(TopAbs_FORWARD);
|
||||
TopExp::Vertices( theEdge, theStart, theEnd );
|
||||
Standard_Boolean use_start = ( theVertex.IsSame( theStart ) );
|
||||
Standard_Boolean use_end = ( theVertex.IsSame( theEnd ) );
|
||||
|
||||
// Iterate on edge curves, accumulating positions
|
||||
for (theCIterator.Initialize((*((Handle(BRep_TEdge)*)&theEdge.TShape()))->ChangeCurves());
|
||||
theCIterator.More(); theCIterator.Next()) {
|
||||
Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(theCIterator.Value());
|
||||
if ( GC.IsNull() ) continue;
|
||||
// Calculate vertex position for this curve
|
||||
Standard_Real theFParam, theLParam;
|
||||
GC->Range( theFParam, theLParam );
|
||||
gp_Pnt thePoint;
|
||||
if (use_start) {
|
||||
GC->D0( theFParam, thePoint );
|
||||
thePositions.Append( thePoint.XYZ() );
|
||||
}
|
||||
if (use_end) {
|
||||
GC->D0( theLParam, thePoint );
|
||||
thePositions.Append( thePoint.XYZ() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Integer i, theNbPos = thePositions.Length();
|
||||
|
||||
// Calculate vertex position
|
||||
thePosition = gp_XYZ(0.,0.,0.);
|
||||
|
||||
#ifdef POSITION_USES_MEAN_POINT
|
||||
#undef POSITION_USES_MEAN_POINT
|
||||
for ( i = 1; i <= theNbPos; i++ ) thePosition += thePositions.Value(i);
|
||||
if ( theNbPos > 1 ) thePosition /= theNbPos;
|
||||
#else
|
||||
gp_XYZ theLBound(0.,0.,0.), theRBound(0.,0.,0.);
|
||||
for ( i = 1; i <= theNbPos; i++ ) {
|
||||
thePosition = thePositions.Value(i);
|
||||
if ( i == 1 ) theLBound = theRBound = thePosition;
|
||||
Standard_Real val = thePosition.X();
|
||||
if ( val < theLBound.X() ) theLBound.SetX( val );
|
||||
else if ( val > theRBound.X() ) theRBound.SetX( val );
|
||||
val = thePosition.Y();
|
||||
if ( val < theLBound.Y() ) theLBound.SetY( val );
|
||||
else if ( val > theRBound.Y() ) theRBound.SetY( val );
|
||||
val = thePosition.Z();
|
||||
if ( val < theLBound.Z() ) theLBound.SetZ( val );
|
||||
else if ( val > theRBound.Z() ) theRBound.SetZ( val );
|
||||
}
|
||||
if ( theNbPos > 1 ) thePosition = (theLBound + theRBound)/2.;
|
||||
#endif
|
||||
|
||||
// Calculate maximal deviation
|
||||
theMaxDev = 0.;
|
||||
|
||||
for ( i = 1; i <= theNbPos; i++ ) {
|
||||
Standard_Real theDeviation = (thePosition-thePositions.Value(i)).Modulus();
|
||||
if ( theDeviation > theMaxDev ) theMaxDev = theDeviation;
|
||||
}
|
||||
theMaxDev *= 1.0001; // To avoid numerical roundings
|
||||
if ( theMaxDev < Precision::Confusion() ) theMaxDev = Precision::Confusion();
|
||||
|
||||
// Update shared vertex
|
||||
theBuilder.UpdateVertex( theSharedVertex, gp_Pnt(thePosition), theMaxDev );
|
||||
|
||||
// Iterate on edges, adding shared vertex
|
||||
for ( theLIterator.Initialize( theList );
|
||||
theLIterator.More();
|
||||
theLIterator.Next() ) {
|
||||
TopoDS_Vertex& theVertex = TopoDS::Vertex( theLIterator.Value() );
|
||||
theLIterator.Next();
|
||||
TopoDS_Edge& theEdge = TopoDS::Edge( theLIterator.Value() );
|
||||
|
||||
// Determine usage of old vertices
|
||||
TopoDS_Vertex theStart, theEnd;
|
||||
theEdge.Orientation(TopAbs_FORWARD);
|
||||
TopExp::Vertices( theEdge, theStart, theEnd );
|
||||
Standard_Boolean use_start = ( theVertex.IsSame( theStart ) );
|
||||
Standard_Boolean use_end = ( theVertex.IsSame( theEnd ) );
|
||||
|
||||
// Prepare vertex to remove
|
||||
TopoDS_Vertex theOldVertex;
|
||||
if (use_start) theOldVertex = theStart; // start is preferred for closed edges
|
||||
else theOldVertex = theEnd;
|
||||
|
||||
// Prepare vertex to add
|
||||
TopoDS_Vertex theNewVertex;
|
||||
//smh#8 Porting AIX
|
||||
if (use_start) {
|
||||
TopoDS_Shape tmpshapeFwd = theSharedVertex.Oriented(TopAbs_FORWARD);
|
||||
theNewVertex = TopoDS::Vertex(tmpshapeFwd);
|
||||
}
|
||||
else {
|
||||
TopoDS_Shape tmpshapeRev = theSharedVertex.Oriented(TopAbs_REVERSED);
|
||||
theNewVertex = TopoDS::Vertex(tmpshapeRev);
|
||||
}
|
||||
if ( !theOldVertex.IsSame(theNewVertex) ) {
|
||||
// Replace vertices
|
||||
Standard_Boolean freeflag = theEdge.Free();
|
||||
theEdge.Free(Standard_True); //smh
|
||||
theBuilder.Remove( theEdge, theOldVertex );
|
||||
theBuilder.Add( theEdge, theNewVertex );
|
||||
if (use_start && use_end) {
|
||||
// process special case for closed edge
|
||||
theBuilder.Remove( theEdge, theOldVertex.Oriented(TopAbs_REVERSED) ); // remove reversed from closed edge
|
||||
theBuilder.Add( theEdge, theNewVertex.Oriented(TopAbs_REVERSED) ); // add reversed to closed edge
|
||||
}
|
||||
theEdge.Free(freeflag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clear maps after build
|
||||
Clear();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Clear
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_EdgeConnect::Clear ()
|
||||
{
|
||||
myVertices.Clear();
|
||||
myLists.Clear();
|
||||
}
|
56
src/ShapeFix/ShapeFix_EdgeProjAux.cdl
Executable file
56
src/ShapeFix/ShapeFix_EdgeProjAux.cdl
Executable file
@@ -0,0 +1,56 @@
|
||||
-- File: ShapeFix_EdgeProjAux.cdl
|
||||
-- Created: Wed Jun 3 12:32:09 1998
|
||||
-- Author: data exchange team
|
||||
-- <det@nnov.matra-dtv.fr>
|
||||
---Copyright: Matra Datavision 1998
|
||||
|
||||
|
||||
class EdgeProjAux from ShapeFix inherits TShared from MMgt
|
||||
|
||||
---Purpose: Project 3D point (vertex) on pcurves to find Vertex Parameter
|
||||
-- on parametric representation of an edge
|
||||
|
||||
uses
|
||||
|
||||
Curve from Geom2d,
|
||||
Face from TopoDS,
|
||||
Edge from TopoDS,
|
||||
Surface from Geom
|
||||
|
||||
is
|
||||
|
||||
Create returns mutable EdgeProjAux from ShapeFix;
|
||||
|
||||
Create (F: Face from TopoDS; E: Edge from TopoDS)
|
||||
returns mutable EdgeProjAux from ShapeFix;
|
||||
|
||||
Init (me: mutable; F: Face from TopoDS; E: Edge from TopoDS);
|
||||
|
||||
Compute (me: mutable; preci: Real);
|
||||
|
||||
IsFirstDone (me) returns Boolean from Standard;
|
||||
|
||||
IsLastDone (me) returns Boolean from Standard;
|
||||
|
||||
FirstParam (me) returns Real from Standard;
|
||||
|
||||
LastParam (me) returns Real from Standard;
|
||||
|
||||
IsIso (me: mutable; C: Curve from Geom2d) returns Boolean;
|
||||
|
||||
Init2d (me: mutable; preci: Real) is protected;
|
||||
|
||||
Init3d (me: mutable; preci: Real) is protected;
|
||||
|
||||
UpdateParam2d (me: mutable; C: Curve from Geom2d) is protected;
|
||||
|
||||
fields
|
||||
|
||||
myFace: Face from TopoDS is protected;
|
||||
myEdge: Edge from TopoDS is protected;
|
||||
myFirstParam: Real is protected;
|
||||
myLastParam: Real is protected;
|
||||
myFirstDone: Boolean is protected;
|
||||
myLastDone: Boolean is protected;
|
||||
|
||||
end EdgeProjAux;
|
556
src/ShapeFix/ShapeFix_EdgeProjAux.cxx
Executable file
556
src/ShapeFix/ShapeFix_EdgeProjAux.cxx
Executable file
@@ -0,0 +1,556 @@
|
||||
//:r5 abv 06.04.99: ec_turbine-A.stp, #4313: protect against null curve
|
||||
// abv 09.04.99 S4136: add parameter preci (to eliminate BRepAPI::Precision)
|
||||
#include <ShapeFix_EdgeProjAux.ixx>
|
||||
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
#include <Standard_Failure.hxx>
|
||||
|
||||
#include <ElCLib.hxx>
|
||||
|
||||
#include <Adaptor3d_CurveOnSurface.hxx>
|
||||
#include <Geom2dAdaptor_Curve.hxx>
|
||||
#include <Geom2dAdaptor_HCurve.hxx>
|
||||
#include <GeomAdaptor_Surface.hxx>
|
||||
#include <GeomAdaptor_HSurface.hxx>
|
||||
|
||||
#include <Geom2d_Curve.hxx>
|
||||
#include <Geom2d_BSplineCurve.hxx>
|
||||
#include <Geom2d_Line.hxx>
|
||||
#include <Geom_Curve.hxx>
|
||||
#include <Geom_Surface.hxx>
|
||||
#include <Geom_SphericalSurface.hxx>
|
||||
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopExp.hxx>
|
||||
|
||||
#include <ShapeAnalysis.hxx>
|
||||
#include <ShapeAnalysis_Curve.hxx>
|
||||
#include <ShapeAnalysis_Edge.hxx>
|
||||
#include <ShapeAnalysis_Surface.hxx>
|
||||
|
||||
#include <Extrema_ExtPC.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeFix_EdgeProjAux
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
ShapeFix_EdgeProjAux::ShapeFix_EdgeProjAux ()
|
||||
{
|
||||
myFirstDone = myLastDone = Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeFix_EdgeProjAux
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
ShapeFix_EdgeProjAux::ShapeFix_EdgeProjAux (const TopoDS_Face& F,
|
||||
const TopoDS_Edge& E)
|
||||
{
|
||||
Init (F, E);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Init
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_EdgeProjAux::Init (const TopoDS_Face& F,
|
||||
const TopoDS_Edge& E)
|
||||
{
|
||||
myFace = F;
|
||||
myEdge = E;
|
||||
myFirstDone = myLastDone = Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Compute
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_EdgeProjAux::Compute (const Standard_Real preci)
|
||||
{
|
||||
myFirstDone = myLastDone = Standard_False;
|
||||
|
||||
// Project Point3d on Surface
|
||||
// TEMPORARY Call ShapeFix_EdgeProjAux
|
||||
|
||||
Init2d(preci);
|
||||
if (IsFirstDone() && IsLastDone()) {
|
||||
Standard_Real U1 = FirstParam();
|
||||
Standard_Real U2 = LastParam();
|
||||
if (U1>=U2) {
|
||||
#ifdef DEBUG
|
||||
cout << "Parametres inverses ... " << endl;
|
||||
#endif
|
||||
Standard_Real tmp = U1;
|
||||
U1 = U2; U2 = tmp;
|
||||
}
|
||||
myFirstParam = U1;
|
||||
myFirstDone = Standard_True;
|
||||
myLastParam = U2;
|
||||
myLastDone = Standard_True;
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsFirstDone
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_EdgeProjAux::IsFirstDone() const
|
||||
{
|
||||
return myFirstDone;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsLastDone
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_EdgeProjAux::IsLastDone() const
|
||||
{
|
||||
return myLastDone;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FirstParam
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Real ShapeFix_EdgeProjAux::FirstParam() const
|
||||
{
|
||||
return myFirstParam;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : LastParam
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Real ShapeFix_EdgeProjAux::LastParam() const
|
||||
{
|
||||
return myLastParam;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsIso
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_EdgeProjAux::IsIso (const Handle(Geom2d_Curve)& /*theCurve2d*/)
|
||||
{
|
||||
// Until an ISO is recognized by Adaptor3d_Curve
|
||||
/*
|
||||
if (theCurve2d->IsKind(STANDARD_TYPE(Geom2d_Line))) {
|
||||
Handle(Geom2d_Line) theLine2d = Handle(Geom2d_Line)::DownCast(theCurve2d);
|
||||
gp_Dir2d theDir2d = theLine2d->Direction();
|
||||
|
||||
gp_Dir2d dir1(0.,1.);
|
||||
gp_Dir2d dir2(0.,-1.);
|
||||
|
||||
return (theDir2d.IsEqual(dir1,Precision::Angular()) ||
|
||||
theDir2d.IsEqual(dir2,Precision::Angular()) ||
|
||||
theDir2d.IsNormal(dir1,Precision::Angular()) ||
|
||||
theDir2d.IsNormal(dir2,Precision::Angular()) );
|
||||
}
|
||||
*/
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// static : FindParameterWithExt
|
||||
// Purpose : Computes the trimming parameter of Pt1 on COnS
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static Standard_Boolean FindParameterWithExt (const gp_Pnt& Pt1,
|
||||
const Adaptor3d_CurveOnSurface& COnS,
|
||||
const Standard_Real Uinf,
|
||||
const Standard_Real Usup,
|
||||
const Standard_Real preci,
|
||||
Standard_Real& w1)
|
||||
{
|
||||
try { // et allez donc !
|
||||
OCC_CATCH_SIGNALS
|
||||
Extrema_ExtPC myExtPC (Pt1, COnS, Uinf, Usup, preci);
|
||||
|
||||
//ShapeFix_ExtPCOnS myExtPCOnS1 =
|
||||
//ShapeFix_ExtPCOnS(Pt1, COnS, Uinf, Usup, preci);
|
||||
|
||||
if (myExtPC.IsDone()) {
|
||||
Standard_Integer NbExt1 = myExtPC.NbExt();
|
||||
for (Standard_Integer i=1; i<=NbExt1; i++) {
|
||||
if (myExtPC.IsMin(i)) {
|
||||
//Standard_Real dist = myExtPC.Value(i); //szv#4:S4163:12Mar99 debug mode only
|
||||
w1 = myExtPC.Point(i).Parameter();
|
||||
}
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
else return Standard_False;
|
||||
} // end try
|
||||
catch(Standard_Failure) {
|
||||
#ifdef DEB //:s5
|
||||
cout << "Warning: ShapeFix_EdgeProjAux, FindParameterWithExt(): Exception: ";
|
||||
Standard_Failure::Caught()->Print(cout); cout << endl;
|
||||
#endif
|
||||
return Standard_False;
|
||||
}
|
||||
return Standard_False; // normalement, on n y passe jamais
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Init2d
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_EdgeProjAux::Init2d (const Standard_Real preci)
|
||||
{
|
||||
Standard_Real cl, cf;
|
||||
|
||||
// Extract Geometries
|
||||
Handle(Geom_Surface) theSurface = BRep_Tool::Surface(myFace);
|
||||
Handle(Geom2d_Curve) theCurve2d = BRep_Tool::CurveOnSurface(myEdge, myFace, cf, cl);
|
||||
if ( theCurve2d.IsNull() ) return; //:r5 abv 6 Apr 99: ec_turbine-A.stp, #4313
|
||||
|
||||
TopoDS_Vertex V1,V2;
|
||||
TopExp::Vertices(myEdge, V1, V2);
|
||||
gp_Pnt Pt1,Pt2;
|
||||
// pdn 28.12.98: r_39-db.stp #605: use ends of 3d curve instead of vertices
|
||||
ShapeAnalysis_Edge sae;
|
||||
Standard_Real a,b;
|
||||
Handle(Geom_Curve) C3d;
|
||||
if(sae.Curve3d(myEdge,C3d,a,b,Standard_False)) {
|
||||
Pt1 = C3d->Value(a);
|
||||
Pt2 = C3d->Value(b);
|
||||
}
|
||||
else {
|
||||
Pt1 = BRep_Tool::Pnt(V1);
|
||||
Pt2 = BRep_Tool::Pnt(V2);
|
||||
}
|
||||
//:S4136 Standard_Real preci = BRepAPI::Precision();
|
||||
//pdn to manage degenerated case
|
||||
if (V1.IsSame(V2)) {
|
||||
Handle(ShapeAnalysis_Surface) stsu = new ShapeAnalysis_Surface (theSurface);
|
||||
gp_Pnt2d aPt1,aPt2;
|
||||
Standard_Real firstpar,lastpar;
|
||||
if (stsu->DegeneratedValues(Pt1,preci,aPt1,aPt2,firstpar,lastpar)){
|
||||
|
||||
if(theCurve2d->IsKind(STANDARD_TYPE(Geom2d_Line))) {
|
||||
if (aPt1.IsEqual(theCurve2d->Value(firstpar),preci) &&
|
||||
aPt2.IsEqual(theCurve2d->Value(lastpar),preci)){
|
||||
myFirstParam = firstpar;
|
||||
myLastParam = lastpar;
|
||||
myFirstDone = myLastDone = Standard_True;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else cout <<"Other type of deg curve"<<endl;
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Boolean parU = Standard_False, parV = Standard_False;
|
||||
GeomAdaptor_Surface SA = GeomAdaptor_Surface(theSurface);
|
||||
Handle(GeomAdaptor_HSurface) myHSur = new GeomAdaptor_HSurface(SA);
|
||||
|
||||
cf = theCurve2d->FirstParameter();
|
||||
cl = theCurve2d->LastParameter();
|
||||
//pdn cutting pcurve by suface bounds
|
||||
if (Precision::IsInfinite(cf)||Precision::IsInfinite(cf)) {
|
||||
if(theCurve2d->IsKind(STANDARD_TYPE(Geom2d_Line))) {
|
||||
Standard_Real uf,ul,vf,vl;
|
||||
theSurface->Bounds(uf,ul,vf,vl);
|
||||
if(!Precision::IsInfinite(uf)&&!Precision::IsInfinite(ul)&&
|
||||
!Precision::IsInfinite(vf)&&!Precision::IsInfinite(vl)) {
|
||||
Standard_Real cfi,cli;
|
||||
Handle(Geom2d_Line) lin = Handle(Geom2d_Line)::DownCast(theCurve2d);
|
||||
gp_Pnt2d pnt = lin->Location();
|
||||
gp_Dir2d dir = lin->Direction();
|
||||
if (dir.Y()==0) {
|
||||
parU = Standard_True;
|
||||
cfi = (uf-pnt.X())/dir.X();
|
||||
cli = (ul-pnt.X())/dir.X();
|
||||
}
|
||||
else if (dir.X()==0) {
|
||||
parV = Standard_True;
|
||||
cfi = (vf-pnt.Y())/dir.Y();
|
||||
cli = (vl-pnt.Y())/dir.Y();
|
||||
}
|
||||
else {//common case
|
||||
Standard_Real xfi, xli, yfi, yli;
|
||||
xfi = (uf-pnt.X())/dir.X();
|
||||
xli = (ul-pnt.X())/dir.X();
|
||||
yfi = (vf-pnt.Y())/dir.Y();
|
||||
yli = (vl-pnt.Y())/dir.Y();
|
||||
if (dir.X()*dir.Y() > 0) {
|
||||
cfi = (Abs(xli-xfi) < Abs(xli-yfi)? xfi : yfi);
|
||||
cli = (Abs(xfi-xli) < Abs(xfi-yli)? xli : yli);
|
||||
} else {
|
||||
cfi = (Abs(xli-xfi) < Abs(xli-yli)? xfi : yli);
|
||||
cli = (Abs(yli-xli) < Abs(yli-yfi)? xli : yfi);
|
||||
}
|
||||
}
|
||||
if (cfi < cli) { cf = cfi; cl = cli; }
|
||||
else { cf = cli; cl = cfi; }
|
||||
}
|
||||
else if(!Precision::IsInfinite(uf)&&!Precision::IsInfinite(ul)){
|
||||
Handle(Geom2d_Line) lin = Handle(Geom2d_Line)::DownCast(theCurve2d);
|
||||
gp_Dir2d dir = lin->Direction();
|
||||
if (dir.X()!=0) {
|
||||
if (dir.Y()==0) parU = Standard_True;
|
||||
gp_Pnt2d pnt = lin->Location(); //szv#4:S4163:12Mar99 moved
|
||||
Standard_Real cfi = (uf-pnt.X())/dir.X();
|
||||
Standard_Real cli = (ul-pnt.X())/dir.X();
|
||||
if (cfi < cli) { cf = cfi; cl = cli; }
|
||||
else { cf = cli; cl = cfi; }
|
||||
}
|
||||
else {
|
||||
cf=-10000;
|
||||
cl= 10000;
|
||||
}
|
||||
}
|
||||
else {
|
||||
cf=-10000;
|
||||
cl= 10000;
|
||||
//pdn not cutted by bounds
|
||||
#ifdef DEBUG
|
||||
cout<<"Infinite Surface"<<endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else {
|
||||
//pdn not linear case not managed
|
||||
cf=-10000;
|
||||
cl= 10000;
|
||||
#ifdef DEBUG
|
||||
cout<<"Some infinite curve"<<endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
Geom2dAdaptor_Curve CA = Geom2dAdaptor_Curve(theCurve2d,cf,cl);
|
||||
Handle(Geom2dAdaptor_HCurve) myHCur = new Geom2dAdaptor_HCurve(CA);
|
||||
|
||||
Adaptor3d_CurveOnSurface COnS = Adaptor3d_CurveOnSurface(myHCur, myHSur);
|
||||
|
||||
// ----------------------------------------------
|
||||
// --- topological limit == geometric limit ? ---
|
||||
// ----------------------------------------------
|
||||
Standard_Real Uinf = COnS.FirstParameter();
|
||||
Standard_Real Usup = COnS.LastParameter();
|
||||
|
||||
Standard_Real w1,w2;
|
||||
ShapeAnalysis_Curve sac;
|
||||
gp_Pnt pnt;
|
||||
Standard_Real dist = sac.Project(COnS,Pt1,preci,pnt,w1,Standard_False);
|
||||
if (dist > preci) return;
|
||||
dist = sac.Project(COnS,Pt2,preci,pnt,w2,Standard_False);
|
||||
if (dist > preci) return;
|
||||
|
||||
myFirstParam = w1;
|
||||
myLastParam = w2;
|
||||
myFirstDone = myLastDone = Standard_True;
|
||||
if ( myFirstParam == Uinf && myLastParam == Usup ) return;
|
||||
if ( myFirstParam == Usup && myLastParam == Uinf ) {
|
||||
myFirstParam = theCurve2d->ReversedParameter(Usup);
|
||||
myLastParam = theCurve2d->ReversedParameter(Uinf);
|
||||
theCurve2d->Reverse();
|
||||
#ifdef DEB
|
||||
cout << "Warning: ShapeFix_EdgeProjAux: pcurve reversed" << endl;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
//:abv 29.08.01: SAT: fix for closed case
|
||||
if ( COnS.Value(Uinf).Distance ( COnS.Value(Usup) ) < Precision::Confusion() ) {
|
||||
// 18.11.2002 SKL OCC630 compare values with tolerance Precision::PConfusion() instead of "=="
|
||||
if ( Abs(myFirstParam-Uinf) < ::Precision::PConfusion() &&
|
||||
Abs(myLastParam-Uinf) < ::Precision::PConfusion() )
|
||||
myLastParam = w2 = Usup;
|
||||
// 18.11.2002 SKL OCC630 compare values with tolerance Precision::PConfusion() instead of "=="
|
||||
else if ( Abs(myFirstParam-Usup) < ::Precision::PConfusion() &&
|
||||
Abs(myLastParam-Usup) < ::Precision::PConfusion() )
|
||||
myFirstParam = w1 = Uinf;
|
||||
}
|
||||
|
||||
//pdn adjust parameters in periodic case
|
||||
if(parU || parV) {
|
||||
Standard_Real uf,ul,vf,vl;
|
||||
theSurface->Bounds(uf,ul,vf,vl);
|
||||
Standard_Real period = (parU ? ul-uf : vl-vf);
|
||||
w1+=ShapeAnalysis::AdjustToPeriod(w1,0,period);
|
||||
myFirstParam = w1;
|
||||
w2+=ShapeAnalysis::AdjustToPeriod(w2,0,period);
|
||||
myLastParam = w2;
|
||||
Handle(Geom_Curve) C3d1;
|
||||
if(!sae.Curve3d (myEdge, C3d1, cf, cl, Standard_False )) {
|
||||
UpdateParam2d(theCurve2d);
|
||||
return;
|
||||
}
|
||||
gp_Pnt mid = C3d1->Value((cf+cl)/2);
|
||||
Standard_Real wmid;
|
||||
sac.Project(COnS,mid,preci,pnt,wmid,Standard_False);
|
||||
wmid+=ShapeAnalysis::AdjustToPeriod(wmid,0,period);
|
||||
if(w1>w2) {
|
||||
if(w2 > wmid) myFirstParam -= period;
|
||||
else if (w1 > wmid)
|
||||
UpdateParam2d(theCurve2d);
|
||||
else {
|
||||
myLastParam+=period;
|
||||
#ifdef DEBUG
|
||||
cout <<" Added"<<endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(w1 > wmid) {
|
||||
myLastParam -=period;
|
||||
UpdateParam2d(theCurve2d);
|
||||
#ifdef DEBUG
|
||||
cout <<" Added & Inverted"<<endl;
|
||||
#endif
|
||||
} else if (w2 < wmid) {
|
||||
myFirstParam += period;
|
||||
UpdateParam2d(theCurve2d);
|
||||
}
|
||||
}
|
||||
}
|
||||
UpdateParam2d(theCurve2d);
|
||||
return;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Init3d
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_EdgeProjAux::Init3d (const Standard_Real preci)
|
||||
{
|
||||
Standard_Real cl, cf;
|
||||
|
||||
// Extract Geometries
|
||||
Handle(Geom_Surface) theSurface = BRep_Tool::Surface(myFace);
|
||||
Handle(Geom2d_Curve) theCurve2d = BRep_Tool::CurveOnSurface(myEdge, myFace, cf, cl);
|
||||
if ( theCurve2d.IsNull() ) return; //:r5 abv 6 Apr 99: ec_turbine-A.stp, #4313
|
||||
TopoDS_Vertex V1,V2;
|
||||
|
||||
V1 = TopExp::FirstVertex(myEdge);
|
||||
V2 = TopExp::LastVertex(myEdge);
|
||||
gp_Pnt Pt1 = BRep_Tool::Pnt(V1);
|
||||
gp_Pnt Pt2 = BRep_Tool::Pnt(V2);
|
||||
|
||||
|
||||
GeomAdaptor_Surface SA = GeomAdaptor_Surface(theSurface);
|
||||
Handle(GeomAdaptor_HSurface) myHSur = new GeomAdaptor_HSurface(SA);
|
||||
|
||||
Geom2dAdaptor_Curve CA = Geom2dAdaptor_Curve(theCurve2d);
|
||||
Handle(Geom2dAdaptor_HCurve) myHCur = new Geom2dAdaptor_HCurve(CA);
|
||||
|
||||
Adaptor3d_CurveOnSurface COnS = Adaptor3d_CurveOnSurface(myHCur, myHSur);
|
||||
|
||||
//:S4136 Standard_Real preci = BRepAPI::Precision();
|
||||
Standard_Real Uinf = theCurve2d->FirstParameter();
|
||||
Standard_Real Usup = theCurve2d->LastParameter();
|
||||
|
||||
// ----------------------------------------------
|
||||
// --- topological limit == geometric limit ? ---
|
||||
// ----------------------------------------------
|
||||
|
||||
if (theCurve2d->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve))) {
|
||||
|
||||
gp_Pnt Pdeb = COnS.Value(Uinf);
|
||||
gp_Pnt Pfin = COnS.Value(Usup);
|
||||
|
||||
//szv#4:S4163:12Mar99 optimized
|
||||
if ( Pdeb.IsEqual(Pt1, preci) && Pfin.IsEqual(Pt2, preci) ) {
|
||||
myFirstParam = Uinf;
|
||||
myLastParam = Usup;
|
||||
myFirstDone = myLastDone = Standard_True;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------
|
||||
// --- The CurveOnSurface is not infinite ---
|
||||
// --- Try with Extrema ---
|
||||
// ------------------------------------------
|
||||
|
||||
Standard_Real w1 = COnS.FirstParameter();
|
||||
Standard_Real w2 = COnS.LastParameter();
|
||||
|
||||
if ((!Precision::IsInfinite(w1) &&
|
||||
!Precision::IsInfinite(w2) &&
|
||||
theCurve2d->Continuity() != GeomAbs_C0) ||
|
||||
IsIso(theCurve2d)) {
|
||||
|
||||
//szv#4:S4163:12Mar99 optimized
|
||||
if ( FindParameterWithExt(Pt1, COnS, Uinf, Usup, preci, w1) &&
|
||||
FindParameterWithExt(Pt2, COnS, Uinf, Usup, preci, w2) ) {
|
||||
myFirstParam = w1;
|
||||
myLastParam = w2;
|
||||
UpdateParam2d(theCurve2d);
|
||||
myFirstDone = myLastDone = Standard_True;
|
||||
return;
|
||||
}
|
||||
}
|
||||
myFirstDone = myLastDone = Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : UpdateParam2d
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_EdgeProjAux::UpdateParam2d (const Handle(Geom2d_Curve)& theCurve2d)
|
||||
{
|
||||
if (myFirstParam < myLastParam) return;
|
||||
|
||||
Standard_Real cf = theCurve2d->FirstParameter();
|
||||
Standard_Real cl = theCurve2d->LastParameter();
|
||||
//:S4136 Standard_Real preci = BRepAPI::Precision();
|
||||
Standard_Real preci2d = Precision::PConfusion(); //:S4136: Parametric(preci, 0.01);
|
||||
|
||||
// 15.11.2002 PTV OCC966
|
||||
if (ShapeAnalysis_Curve::IsPeriodic(theCurve2d)) {
|
||||
ElCLib::AdjustPeriodic(cf,cl,preci2d,myFirstParam,myLastParam);
|
||||
}
|
||||
else if (theCurve2d->IsClosed()) {
|
||||
//szv#4:S4163:12Mar99 optimized
|
||||
if ( Abs ( myFirstParam - cl ) <= preci2d ) myFirstParam = cf;
|
||||
else if ( Abs ( myLastParam - cf ) <= preci2d ) myLastParam = cl;
|
||||
else {
|
||||
#ifdef DEBUG
|
||||
cout << "Error : curve 2d range crossing non periodic curve origin";
|
||||
cout << endl;
|
||||
#endif
|
||||
// add fail result;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// the curve is closed within the 'file' 2D tolerance
|
||||
else if (theCurve2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) {
|
||||
Handle(Geom2d_BSplineCurve) aBSpline2d =
|
||||
Handle(Geom2d_BSplineCurve)::DownCast(theCurve2d);
|
||||
if (aBSpline2d->StartPoint().Distance(aBSpline2d->EndPoint()) <= preci2d) {
|
||||
if ( Abs ( myFirstParam - cl ) <= preci2d ) myFirstParam = cf;
|
||||
else if ( Abs ( myLastParam - cf ) <= preci2d ) myLastParam = cl;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef DEBUG
|
||||
cout << "Warning : non increasing parameters for 2d curve." << endl;
|
||||
cout << " update parameter 2d uncertain." << endl;
|
||||
#endif
|
||||
Standard_Real tmp1 = myFirstParam, tmp2 = myLastParam;
|
||||
myFirstParam = theCurve2d->ReversedParameter(tmp1);
|
||||
myLastParam = theCurve2d->ReversedParameter(tmp2);
|
||||
theCurve2d->Reverse();
|
||||
//cout<<"Reversed case 2"<<endl;
|
||||
}
|
||||
}
|
261
src/ShapeFix/ShapeFix_Face.cdl
Executable file
261
src/ShapeFix/ShapeFix_Face.cdl
Executable file
@@ -0,0 +1,261 @@
|
||||
-- File: ShapeFix_Face.cdl
|
||||
-- Created: Wed Jun 3 12:33:25 1998
|
||||
-- Author: data exchange team
|
||||
-- <det@nnov.matra-dtv.fr>
|
||||
---Copyright: Matra Datavision 1998
|
||||
|
||||
|
||||
class Face from ShapeFix inherits Root from ShapeFix
|
||||
|
||||
---Purpose: This operator allows to perform various fixes on face
|
||||
-- and its wires: fixes provided by ShapeFix_Wire,
|
||||
-- fixing orientation of wires, addition of natural bounds,
|
||||
-- fixing of missing seam edge,
|
||||
-- and detection and removal of null-area wires
|
||||
|
||||
uses
|
||||
|
||||
Surface from Geom,
|
||||
Shape from TopoDS,
|
||||
Face from TopoDS,
|
||||
Wire from TopoDS,
|
||||
BasicMsgRegistrator from ShapeExtend,
|
||||
Status from ShapeExtend,
|
||||
Surface from ShapeAnalysis,
|
||||
Wire from ShapeFix,
|
||||
SequenceOfShape from TopTools,
|
||||
WireData from ShapeExtend,
|
||||
Vertex from TopoDS,
|
||||
DataMapOfShapeBox2d from ShapeFix,
|
||||
DataMapOfShapeListOfShape from TopTools
|
||||
is
|
||||
|
||||
Create returns Face from ShapeFix;
|
||||
---Purpose: Creates an empty tool
|
||||
|
||||
Create (face: Face from TopoDS) returns Face from ShapeFix;
|
||||
---Purpose: Creates a tool and loads a face
|
||||
|
||||
ClearModes (me: mutable) is virtual;
|
||||
---Purpose: Sets all modes to default
|
||||
|
||||
Init (me: mutable; face: Face from TopoDS);
|
||||
---Purpose: Loads a whole face already created, with its wires, sense and
|
||||
-- location
|
||||
|
||||
Init (me: mutable; surf: Surface from Geom; preci: Real;
|
||||
fwd: Boolean = Standard_True);
|
||||
---Purpose: Starts the creation of the face
|
||||
-- By default it will be FORWARD, or REVERSED if <fwd> is False
|
||||
|
||||
Init (me: mutable; surf: Surface from ShapeAnalysis; preci: Real;
|
||||
fwd: Boolean = Standard_True);
|
||||
---Purpose: Starts the creation of the face
|
||||
-- By default it will be FORWARD, or REVERSED if <fwd> is False
|
||||
|
||||
SetMsgRegistrator (me: mutable; msgreg: BasicMsgRegistrator from ShapeExtend) is redefined;
|
||||
---Purpose: Sets message registrator
|
||||
|
||||
SetPrecision (me: mutable; preci: Real) is redefined;
|
||||
---Purpose: Sets basic precision value (also to FixWireTool)
|
||||
|
||||
SetMinTolerance (me: mutable; mintol: Real) is redefined;
|
||||
---Purpose: Sets minimal allowed tolerance (also to FixWireTool)
|
||||
|
||||
SetMaxTolerance (me: mutable; maxtol: Real) is redefined;
|
||||
---Purpose: Sets maximal allowed tolerance (also to FixWireTool)
|
||||
|
||||
FixWireMode (me: mutable) returns Integer;
|
||||
---C++: return &
|
||||
---C++: inline
|
||||
---Purpose: Returns (modifiable) the mode for applying fixes of
|
||||
-- ShapeFix_Wire, by default True.
|
||||
|
||||
FixOrientationMode (me: mutable) returns Integer;
|
||||
---C++: return &
|
||||
---C++: inline
|
||||
---Purpose: Returns (modifiable) the fix orientation mode, by default
|
||||
-- True. If True, wires oriented to border limited square.
|
||||
|
||||
FixAddNaturalBoundMode (me: mutable) returns Integer;
|
||||
---C++: return &
|
||||
---C++: inline
|
||||
---Purpose: Returns (modifiable) the add natural bound mode.
|
||||
-- If true, natural boundary is added on faces that miss them.
|
||||
-- Default is False for faces with single wire (they are
|
||||
-- handled by FixOrientation in that case) and True for others.
|
||||
|
||||
FixMissingSeamMode (me: mutable) returns Integer;
|
||||
---C++: return &
|
||||
---C++: inline
|
||||
---Purpose: Returns (modifiable) the fix missing seam mode, by default
|
||||
-- True. If True, tries to insert seam is missed.
|
||||
|
||||
FixSmallAreaWireMode (me: mutable) returns Integer;
|
||||
---C++: return &
|
||||
---C++: inline
|
||||
---Purpose: Returns (modifiable) the fix small area wire mode, by default
|
||||
-- False. If True, drops small wires.
|
||||
FixIntersectingWiresMode (me: mutable) returns Integer;
|
||||
---C++: return &
|
||||
---C++: inline
|
||||
---Purpose: Returns (modifiable) the fix intersecting wires mode
|
||||
-- by default True.
|
||||
|
||||
FixLoopWiresMode (me: mutable) returns Integer;
|
||||
---C++: return &
|
||||
---C++: inline
|
||||
---Purpose: Returns (modifiable) the fix loop wires mode
|
||||
-- by default True.
|
||||
|
||||
FixSplitFaceMode (me: mutable) returns Integer;
|
||||
---C++: return &
|
||||
---C++: inline
|
||||
---Purpose: Returns (modifiable) the fix split face mode
|
||||
-- by default True.
|
||||
|
||||
AutoCorrectPrecisionMode (me: mutable) returns Integer;
|
||||
---C++: return &
|
||||
---C++: inline
|
||||
---Purpose: Returns (modifiable) the auto-correct precision mode
|
||||
-- by default False.
|
||||
|
||||
Face (me) returns Face from TopoDS;
|
||||
---C++: inline
|
||||
---Purpose: Returns a face which corresponds to the current state
|
||||
-- Warning: The finally produced face may be another one ... but with the
|
||||
-- same support
|
||||
|
||||
Result (me) returns Shape from TopoDS;
|
||||
---C++: inline
|
||||
---Purpose: Returns resulting shape (Face or Shell if splitted)
|
||||
-- To be used instead of Face() if FixMissingSeam involved
|
||||
|
||||
Add (me: mutable; wire: Wire from TopoDS);
|
||||
---Purpose: Add a wire to current face using BRep_Builder.
|
||||
-- Wire is added without taking into account orientation of face
|
||||
-- (as if face were FORWARD).
|
||||
---Warning: Method is retained for compatibility with previous versions.
|
||||
|
||||
Perform (me: mutable) returns Boolean;
|
||||
---Purpose: Performs all the fixes, depending on modes
|
||||
-- Function Status returns the status of last call to Perform()
|
||||
-- ShapeExtend_OK : face was OK, nothing done
|
||||
-- ShapeExtend_DONE1: some wires are fixed
|
||||
-- ShapeExtend_DONE2: orientation of wires fixed
|
||||
-- ShapeExtend_DONE3: missing seam added
|
||||
-- ShapeExtend_DONE4: small area wire removed
|
||||
-- ShapeExtend_DONE5: natural bounds added
|
||||
-- ShapeExtend_FAIL1: some fails during fixing wires
|
||||
-- ShapeExtend_FAIL2: cannot fix orientation of wires
|
||||
-- ShapeExtend_FAIL3: cannot add missing seam
|
||||
-- ShapeExtend_FAIL4: cannot remove small area wire
|
||||
|
||||
FixOrientation (me: mutable) returns Boolean;
|
||||
---Purpose: Fixes orientation of wires on the face
|
||||
-- It tries to make all wires lie outside all others (according
|
||||
-- to orientation) by reversing orientation of some of them.
|
||||
-- If face lying on sphere or torus has single wire and
|
||||
-- AddNaturalBoundMode is True, that wire is not reversed in
|
||||
-- any case (supposing that natural bound will be added).
|
||||
-- Returns True if wires were reversed
|
||||
|
||||
FixOrientation (me: mutable; MapWires : in out DataMapOfShapeListOfShape from TopTools)
|
||||
returns Boolean;
|
||||
---Purpose: Fixes orientation of wires on the face
|
||||
-- It tries to make all wires lie outside all others (according
|
||||
-- to orientation) by reversing orientation of some of them.
|
||||
-- If face lying on sphere or torus has single wire and
|
||||
-- AddNaturalBoundMode is True, that wire is not reversed in
|
||||
-- any case (supposing that natural bound will be added).
|
||||
-- Returns True if wires were reversed
|
||||
-- OutWires return information about out wires + list of
|
||||
-- internal wires for each (for performing split face).
|
||||
|
||||
FixAddNaturalBound(me: mutable) returns Boolean;
|
||||
---Purpose: Adds natural boundary on face if it is missing.
|
||||
-- Two cases are supported:
|
||||
-- - face has no wires
|
||||
-- - face lies on geometrically double-closed surface
|
||||
-- (sphere or torus) and none of wires is left-oriented
|
||||
-- Returns True if natural boundary was added
|
||||
|
||||
FixMissingSeam (me: mutable) returns Boolean;
|
||||
---Purpose: Detects and fixes the special case when face on a closed
|
||||
-- surface is given by two wires closed in 3d but with gap in 2d.
|
||||
-- In that case it creates a new wire from the two, and adds a
|
||||
-- missing seam edge
|
||||
-- Returns True if missing seam was added
|
||||
|
||||
FixSmallAreaWire (me: mutable) returns Boolean;
|
||||
---Purpose: Detects wires with small area (that is less than
|
||||
-- 100*Precision::PConfusion(). Removes these wires if they are internal.
|
||||
-- Returns : True if at least one small wire removed,
|
||||
-- False if does nothing.
|
||||
FixLoopWire(me: mutable; aResWires : out SequenceOfShape from TopTools) returns Boolean;
|
||||
---Purpose: Detects if wire has a loop and fixes this situation by splitting on the few parts.
|
||||
-- if wire has a loops and it was splitted Status was set to value ShapeExtend_DONE6.
|
||||
|
||||
SplitEdge (me: mutable; sewd: WireData from ShapeExtend; num: Integer from Standard;
|
||||
param: Real from Standard; vert: Vertex from TopoDS;
|
||||
preci: Real from Standard; boxes: in out DataMapOfShapeBox2d from ShapeFix)
|
||||
returns Boolean from Standard is private;
|
||||
|
||||
SplitEdge (me: mutable; sewd: WireData from ShapeExtend; num: Integer from Standard;
|
||||
param1: Real from Standard; param2: Real from Standard;
|
||||
vert: Vertex from TopoDS; preci: Real from Standard;
|
||||
boxes: in out DataMapOfShapeBox2d from ShapeFix)
|
||||
returns Boolean from Standard is private;
|
||||
|
||||
FixIntersectingWires (me: mutable) returns Boolean;
|
||||
---Purpose: Detects and fixes the special case when face has more than one wire
|
||||
-- and this wires have intersection point
|
||||
|
||||
FixWiresTwoCoincEdges (me: mutable) returns Boolean;
|
||||
---Purpose: If wire contains two coincidence edges it must be removed
|
||||
-- Queries on status after Perform()
|
||||
|
||||
FixSplitFace (me: mutable; MapWires : DataMapOfShapeListOfShape from TopTools)
|
||||
returns Boolean;
|
||||
---Purpose: Split face if there are more than one out wire
|
||||
-- using inrormation after FixOrientation()
|
||||
|
||||
Status (me; status: Status from ShapeExtend) returns Boolean;
|
||||
---Purpose: Returns the status of last call to Perform()
|
||||
-- ShapeExtend_OK : face was OK, nothing done
|
||||
-- ShapeExtend_DONE1: some wires are fixed
|
||||
-- ShapeExtend_DONE2: orientation of wires fixed
|
||||
-- ShapeExtend_DONE3: missing seam added
|
||||
-- ShapeExtend_DONE4: small area wire removed
|
||||
-- ShapeExtend_DONE5: natural bounds added
|
||||
-- ShapeExtend_DONE8: face may be splited
|
||||
-- ShapeExtend_FAIL1: some fails during fixing wires
|
||||
-- ShapeExtend_FAIL2: cannot fix orientation of wires
|
||||
-- ShapeExtend_FAIL3: cannot add missing seam
|
||||
-- ShapeExtend_FAIL4: cannot remove small area wire
|
||||
---C++: inline
|
||||
|
||||
FixWireTool (me: mutable) returns Wire from ShapeFix;
|
||||
---Purpose: Returns tool for fixing wires.
|
||||
---C++: inline
|
||||
|
||||
fields
|
||||
|
||||
mySurf : Surface from ShapeAnalysis is protected;
|
||||
myFace : Face from TopoDS is protected;
|
||||
myResult : Shape from TopoDS is protected; -- result (shell or face)
|
||||
myFixWire: Wire from ShapeFix is protected;
|
||||
myFwd : Boolean is protected;
|
||||
|
||||
myFixWireMode : Integer;
|
||||
myFixOrientationMode : Integer;
|
||||
myFixAddNaturalBoundMode: Integer;
|
||||
myFixMissingSeamMode : Integer;
|
||||
myFixSmallAreaWireMode : Integer;
|
||||
myFixLoopWiresMode : Integer; --gka 08.01.2004
|
||||
myFixIntersectingWiresMode : Integer; -- skl 23.12.2003
|
||||
myFixSplitFaceMode : Integer; -- skl 03.02.2004
|
||||
myAutoCorrectPrecisionMode: Integer; --skl 26.03.2010
|
||||
myStatus : Integer is protected;
|
||||
|
||||
end Face;
|
2243
src/ShapeFix/ShapeFix_Face.cxx
Executable file
2243
src/ShapeFix/ShapeFix_Face.cxx
Executable file
File diff suppressed because it is too large
Load Diff
131
src/ShapeFix/ShapeFix_Face.lxx
Executable file
131
src/ShapeFix/ShapeFix_Face.lxx
Executable file
@@ -0,0 +1,131 @@
|
||||
#include <ShapeExtend.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : FixWireMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Face::FixWireMode()
|
||||
{
|
||||
return myFixWireMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixOrientationMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Face::FixOrientationMode()
|
||||
{
|
||||
return myFixOrientationMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixAddNaturalBoundMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Face::FixAddNaturalBoundMode()
|
||||
{
|
||||
return myFixAddNaturalBoundMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixMissingSeamMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Face::FixMissingSeamMode()
|
||||
{
|
||||
return myFixMissingSeamMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixSmallAreaWireMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Face::FixSmallAreaWireMode()
|
||||
{
|
||||
return myFixSmallAreaWireMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixIntersectingWiresMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Face::FixIntersectingWiresMode()
|
||||
{
|
||||
return myFixIntersectingWiresMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixLoopWiresMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Face::FixLoopWiresMode()
|
||||
{
|
||||
return myFixLoopWiresMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixSplitFaceMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Face::FixSplitFaceMode()
|
||||
{
|
||||
return myFixSplitFaceMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : AutoCorrectPrecisionMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Face::AutoCorrectPrecisionMode()
|
||||
{
|
||||
return myAutoCorrectPrecisionMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Face
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline TopoDS_Face ShapeFix_Face::Face() const
|
||||
{
|
||||
return myFace;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Result
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline TopoDS_Shape ShapeFix_Face::Result() const
|
||||
{
|
||||
return myResult;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Status
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean ShapeFix_Face::Status (const ShapeExtend_Status status) const
|
||||
{
|
||||
return ShapeExtend::DecodeStatus ( myStatus, status );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixWireTool
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Handle(ShapeFix_Wire) ShapeFix_Face::FixWireTool()
|
||||
{
|
||||
return myFixWire;
|
||||
}
|
43
src/ShapeFix/ShapeFix_FaceConnect.cdl
Executable file
43
src/ShapeFix/ShapeFix_FaceConnect.cdl
Executable file
@@ -0,0 +1,43 @@
|
||||
-- File: ShapeFix_FaceConnect.cdl
|
||||
-- Created: Fri Jun 18 11:27:03 1999
|
||||
-- Author: Sergei ZERTCHANINOV
|
||||
-- <szv@nnov>
|
||||
---Copyright: Matra Datavision 1999
|
||||
|
||||
|
||||
class FaceConnect from ShapeFix
|
||||
|
||||
---Purpose :
|
||||
|
||||
uses
|
||||
DataMapOfShapeListOfShape from TopTools,
|
||||
Face from TopoDS, Shell from TopoDS
|
||||
|
||||
is
|
||||
|
||||
Create returns FaceConnect from ShapeFix;
|
||||
|
||||
Add (me : in out; aFirst : Face from TopoDS; aSecond : Face from TopoDS)
|
||||
returns Boolean from Standard;
|
||||
---Purpose :
|
||||
|
||||
Build (me : in out; shell : Shell from TopoDS;
|
||||
sewtoler : Real from Standard; fixtoler : Real from Standard)
|
||||
returns Shell from TopoDS;
|
||||
---Purpose :
|
||||
|
||||
Clear (me : in out);
|
||||
---Purpose : Clears internal data structure
|
||||
|
||||
fields
|
||||
|
||||
myConnected : DataMapOfShapeListOfShape from TopTools;
|
||||
-- Map of pairs (face, list of connected faces) - to store connectivity info
|
||||
myOriFreeEdges : DataMapOfShapeListOfShape from TopTools;
|
||||
-- Map of pairs (face, list of original free edges)
|
||||
myResFreeEdges : DataMapOfShapeListOfShape from TopTools;
|
||||
-- Map of pairs (free edge, list of result free edges)
|
||||
myResSharEdges : DataMapOfShapeListOfShape from TopTools;
|
||||
-- Map of pairs (free edge, list of result shared edges)
|
||||
|
||||
end FaceConnect;
|
678
src/ShapeFix/ShapeFix_FaceConnect.cxx
Executable file
678
src/ShapeFix/ShapeFix_FaceConnect.cxx
Executable file
@@ -0,0 +1,678 @@
|
||||
// File: ShapeFix_FaceConnect.cxx
|
||||
// Created: Fri Jun 18 11:27:03 1999
|
||||
// Author: Sergei ZERTCHANINOV
|
||||
// <szv@nnov>
|
||||
// Copyright: Matra Datavision 1999
|
||||
|
||||
#include <ShapeFix_FaceConnect.ixx>
|
||||
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
#include <Standard_Failure.hxx>
|
||||
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Wire.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopoDS_Iterator.hxx>
|
||||
#include <TopTools_ListOfShape.hxx>
|
||||
#include <TopTools_Array1OfShape.hxx>
|
||||
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
||||
#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
|
||||
#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
|
||||
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRepBuilderAPI_Sewing.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
|
||||
#include <ShapeBuild_ReShape.hxx>
|
||||
|
||||
#include <ShapeFix_Face.hxx>
|
||||
#include <ShapeFix_Wire.hxx>
|
||||
#include <ShapeAnalysis_Edge.hxx>
|
||||
#include <ShapeAnalysis_WireOrder.hxx>
|
||||
#include <Geom2d_Curve.hxx>
|
||||
#ifdef DEB
|
||||
#include <TopTools_MapOfShape.hxx>
|
||||
#endif
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeFix_FaceConnect
|
||||
//=======================================================================
|
||||
|
||||
ShapeFix_FaceConnect::ShapeFix_FaceConnect() {}
|
||||
|
||||
//=======================================================================
|
||||
//function : Connect
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_FaceConnect::Add(const TopoDS_Face& aFirst,
|
||||
const TopoDS_Face& aSecond)
|
||||
{
|
||||
if (!aFirst.IsNull() && !aSecond.IsNull()) {
|
||||
// Process first face
|
||||
if (myConnected.IsBound(aFirst)) {
|
||||
// Find list for the first face
|
||||
TopTools_ListOfShape& theFirstList = myConnected(aFirst);
|
||||
// Append second face to the first list
|
||||
TopTools_ListIteratorOfListOfShape theIter;
|
||||
for ( theIter.Initialize(theFirstList); theIter.More(); theIter.Next() )
|
||||
if (theIter.Value().IsSame(aSecond)) return Standard_True;
|
||||
theFirstList.Append(aSecond);
|
||||
}
|
||||
else {
|
||||
// Append second face to the first list
|
||||
TopTools_ListOfShape theNewFirstList;
|
||||
theNewFirstList.Append(aSecond);
|
||||
myConnected.Bind(aFirst,theNewFirstList);
|
||||
}
|
||||
|
||||
// Process second face if not same
|
||||
if (!aFirst.IsSame(aSecond)) {
|
||||
if (myConnected.IsBound(aSecond)) {
|
||||
// No need to iterate on faces - append first
|
||||
myConnected(aSecond).Append(aFirst);
|
||||
}
|
||||
else {
|
||||
// Append first face to the second list
|
||||
TopTools_ListOfShape theNewSecondList;
|
||||
theNewSecondList.Append(aFirst);
|
||||
myConnected.Bind(aSecond,theNewSecondList);
|
||||
}
|
||||
}
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Build
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
TopoDS_Shell ShapeFix_FaceConnect::Build (const TopoDS_Shell& shell,
|
||||
const Standard_Real sewtoler,
|
||||
const Standard_Real fixtoler)
|
||||
{
|
||||
TopoDS_Shell result = shell;
|
||||
|
||||
/***************************************************************
|
||||
/ INITIAL PREPARATIONS
|
||||
/ Fill map of original free edges,
|
||||
/ fill maps of resulting free and shared edges
|
||||
***************************************************************/
|
||||
|
||||
// Clear maps of free and shared edges
|
||||
myOriFreeEdges.Clear();
|
||||
myResFreeEdges.Clear();
|
||||
myResSharEdges.Clear();
|
||||
|
||||
TopTools_DataMapOfShapeShape theFreeEdges;
|
||||
TopoDS_Shape theEdge, theFace;
|
||||
|
||||
// Fill map of free edges / faces
|
||||
for ( TopoDS_Iterator itf(result); itf.More(); itf.Next() ) {
|
||||
theFace = itf.Value();
|
||||
for ( TopExp_Explorer expe(theFace,TopAbs_EDGE); expe.More(); expe.Next() ) {
|
||||
theEdge = expe.Current();
|
||||
if (theFreeEdges.IsBound(theEdge)) theFreeEdges.UnBind(theEdge);
|
||||
else theFreeEdges.Bind(theEdge,theFace);
|
||||
}
|
||||
}
|
||||
|
||||
// Fill maps of original and resulting edges
|
||||
for ( TopTools_DataMapIteratorOfDataMapOfShapeShape theFEIter( theFreeEdges );
|
||||
theFEIter.More(); theFEIter.Next() ) {
|
||||
// Get pair (face / free edge)
|
||||
theEdge = theFEIter.Key(), theFace = theFEIter.Value();
|
||||
// Process faces with bad connectivities only
|
||||
if (myConnected.IsBound(theFace) &&
|
||||
!BRep_Tool::Degenerated(TopoDS::Edge(theEdge))) {
|
||||
// Add to the map of original free edges
|
||||
if (myOriFreeEdges.IsBound(theFace)) {
|
||||
// Append free edge to the existing list
|
||||
myOriFreeEdges(theFace).Append(theEdge);
|
||||
}
|
||||
else {
|
||||
// Append free edge to the new list
|
||||
TopTools_ListOfShape theNewList;
|
||||
theNewList.Append(theEdge);
|
||||
myOriFreeEdges.Bind(theFace,theNewList);
|
||||
}
|
||||
// Add to the maps of intermediate free and resulting edges
|
||||
if (!myResFreeEdges.IsBound(theEdge)) {
|
||||
TopTools_ListOfShape theFree, theShared;
|
||||
theFree.Append(theEdge);
|
||||
myResFreeEdges.Bind(theEdge,theFree);
|
||||
myResSharEdges.Bind(theEdge,theShared);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clear the temporary map of free edges
|
||||
theFreeEdges.Clear();
|
||||
|
||||
#ifdef DEB
|
||||
//-------------------------------
|
||||
//szv debug - preparation results
|
||||
//-------------------------------
|
||||
if (!myOriFreeEdges.IsEmpty()) {
|
||||
cout<<endl<<"FACE CONNECT PREPARATION RESULTS:"<<endl;
|
||||
cout<<"---------------------------------"<<endl;
|
||||
Standard_Integer freenum = 0, facenum = 0;
|
||||
for ( TopTools_DataMapIteratorOfDataMapOfShapeListOfShape theOFIter( myOriFreeEdges );
|
||||
theOFIter.More(); theOFIter.Next() ) {
|
||||
freenum += theOFIter.Value().Extent();
|
||||
facenum++;
|
||||
}
|
||||
cout<<"TOTAL: "<<facenum<<" faces containing "<<freenum<<" free edges"<<endl;
|
||||
}
|
||||
//-------------------------------
|
||||
#endif
|
||||
|
||||
/***************************************************************
|
||||
/ APPLY SEWING ON CONNECTED FACES
|
||||
/ Change maps of original free edges and resulting shared edges
|
||||
***************************************************************/
|
||||
|
||||
if (!myOriFreeEdges.IsEmpty()) {
|
||||
|
||||
// Allocate array of faces to be sewed
|
||||
TopoDS_Shape theFirstFace, theSecondFace;
|
||||
TopTools_Array1OfShape theFacesToSew(1,2);
|
||||
Standard_Integer theNumOfFacesToSew = 0;
|
||||
Standard_Boolean skip_pair = Standard_False;
|
||||
|
||||
TopTools_ListIteratorOfListOfShape theOriginalIter, theResultsIter;
|
||||
TopoDS_Shape theAuxE, theOrigE, theAuxF;
|
||||
|
||||
BRep_Builder theBuilder;
|
||||
|
||||
TopTools_DataMapOfShapeListOfShape theProcessed;
|
||||
|
||||
for ( TopTools_DataMapIteratorOfDataMapOfShapeListOfShape theConnectedIter( myConnected );
|
||||
theConnectedIter.More(); theConnectedIter.Next() ) {
|
||||
// Process first face only if it is in the map of faces / free edges
|
||||
theFirstFace = theConnectedIter.Key();
|
||||
if (myOriFreeEdges.IsBound(theFirstFace)) {
|
||||
|
||||
// Place first face into the array
|
||||
theFacesToSew.SetValue(1,theFirstFace);
|
||||
theNumOfFacesToSew = 1;
|
||||
// Create the list of processed faces
|
||||
TopTools_ListOfShape theProcessedList;
|
||||
|
||||
// Explore the list of connected faces
|
||||
const TopTools_ListOfShape& theConnectedList = theConnectedIter.Value();
|
||||
TopTools_ListIteratorOfListOfShape theConnectedListIter;
|
||||
for ( theConnectedListIter.Initialize(theConnectedList);
|
||||
theConnectedListIter.More(); theConnectedListIter.Next() ) {
|
||||
// Process second face only if it is in the map of faces / free edges
|
||||
theSecondFace = theConnectedListIter.Value();
|
||||
if (myOriFreeEdges.IsBound(theSecondFace)) {
|
||||
|
||||
// Place second face into the array
|
||||
theFacesToSew.SetValue(2,theSecondFace);
|
||||
// Add second face to the list of processed faces
|
||||
theProcessedList.Append(theSecondFace);
|
||||
|
||||
// Skip the pair if already processed
|
||||
skip_pair = Standard_False;
|
||||
if (theProcessed.IsBound(theSecondFace)) {
|
||||
TopTools_ListOfShape& theProcCnxList = theProcessed(theSecondFace);
|
||||
TopTools_ListIteratorOfListOfShape theProcCnxListIter;
|
||||
for ( theProcCnxListIter.Initialize(theProcCnxList);
|
||||
theProcCnxListIter.More() && !skip_pair; theProcCnxListIter.Next() )
|
||||
if (theFirstFace.IsSame(theProcCnxListIter.Value()))
|
||||
skip_pair = Standard_True;
|
||||
}
|
||||
if (!skip_pair) {
|
||||
|
||||
// Process second face for the pair of different faces only
|
||||
if (theFirstFace.IsSame(theSecondFace)) {
|
||||
#ifdef DEB
|
||||
cout<<"Warning: ShapeFix_FaceConnect::Build: Self-connected face"<<endl;
|
||||
#endif
|
||||
}
|
||||
else theNumOfFacesToSew = 2;
|
||||
|
||||
TopTools_DataMapOfShapeShape theSewerWires;
|
||||
BRepBuilderAPI_Sewing theSewer(sewtoler);
|
||||
|
||||
// Prepare set of faces containing free edges
|
||||
Standard_Integer i = 1;
|
||||
for (i=1; i<=theNumOfFacesToSew; i++) {
|
||||
// Prepare empty face to fill with free edges
|
||||
TopoDS_Shape theFaceToSew = theFacesToSew(i);
|
||||
theAuxF = theFaceToSew.EmptyCopied();
|
||||
// Fill empty face with free edges
|
||||
for ( theOriginalIter.Initialize(myOriFreeEdges(theFaceToSew));
|
||||
theOriginalIter.More(); theOriginalIter.Next() ) {
|
||||
for ( theResultsIter.Initialize(myResFreeEdges(theOriginalIter.Value()));
|
||||
theResultsIter.More(); theResultsIter.Next() ) {
|
||||
// Bind free edge to wire to find results later
|
||||
theAuxE = theResultsIter.Value();
|
||||
TopoDS_Wire theAuxW;
|
||||
theBuilder.MakeWire(theAuxW);
|
||||
theBuilder.Add(theAuxW,theAuxE);
|
||||
theBuilder.Add(theAuxF,theAuxW);
|
||||
theSewerWires.Bind(theAuxE,theAuxW);
|
||||
theSewer.Add(theAuxW);
|
||||
}
|
||||
}
|
||||
// Add constructed face to sewer
|
||||
theSewer.Add(theAuxF);
|
||||
}
|
||||
|
||||
// Perform sewing on the list of free edges
|
||||
Standard_Boolean sewing_ok = Standard_True;
|
||||
{
|
||||
try { OCC_CATCH_SIGNALS theSewer.Perform(); }
|
||||
catch(Standard_Failure) { sewing_ok = Standard_False; }
|
||||
}
|
||||
if ( sewing_ok )
|
||||
if (theSewer.SewedShape().IsNull()) sewing_ok = Standard_False;
|
||||
|
||||
if ( sewing_ok ) {
|
||||
TopTools_DataMapOfShapeShape theResultEdges;
|
||||
|
||||
// Find modified edges for the faces
|
||||
for (i=1; i<=theNumOfFacesToSew; i++) {
|
||||
for ( theOriginalIter.Initialize(myOriFreeEdges(theFacesToSew(i)));
|
||||
theOriginalIter.More(); theOriginalIter.Next() ) {
|
||||
// Get original free edge
|
||||
theOrigE = theOriginalIter.Value();
|
||||
TopTools_ListOfShape& theOldFreeList = myResFreeEdges(theOrigE);
|
||||
theResultsIter.Initialize(theOldFreeList);
|
||||
while ( theResultsIter.More() ) {
|
||||
theAuxE = theSewerWires(theResultsIter.Value());
|
||||
// Process modified edges
|
||||
if (theSewer.IsModified(theAuxE)) {
|
||||
// Fill map of result edges
|
||||
for ( TopExp_Explorer expe(theSewer.Modified(theAuxE),TopAbs_EDGE);
|
||||
expe.More(); expe.Next() ) {
|
||||
theAuxE = expe.Current();
|
||||
// Check edge for being shared
|
||||
if (theResultEdges.IsBound(theAuxE)) {
|
||||
// Edge was shared - move in results list
|
||||
myResSharEdges(theResultEdges(theAuxE)).Append(theAuxE);
|
||||
myResSharEdges(theOrigE).Append(theAuxE);
|
||||
theResultEdges.UnBind(theAuxE);
|
||||
}
|
||||
else theResultEdges.Bind(theAuxE,theOrigE);
|
||||
}
|
||||
// Remove modified free edge from the list
|
||||
theOldFreeList.Remove(theResultsIter);
|
||||
}
|
||||
else theResultsIter.Next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Put free edges back to the lists of results
|
||||
for ( TopTools_DataMapIteratorOfDataMapOfShapeShape theResIter( theResultEdges );
|
||||
theResIter.More(); theResIter.Next() ) {
|
||||
theAuxE = theResIter.Key();
|
||||
myResFreeEdges(theResIter.Value()).Append(theAuxE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bind the list of processed faces to the processed face
|
||||
theProcessed.Bind(theFirstFace,theProcessedList);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear the temporary map of processed faces
|
||||
theProcessed.Clear();
|
||||
|
||||
#ifdef DEB
|
||||
//-------------------------------
|
||||
//szv debug - sewing results
|
||||
//-------------------------------
|
||||
cout<<endl<<"FACE CONNECT SEWING RESULTS:"<<endl;
|
||||
cout<<"----------------------------"<<endl;
|
||||
cout<<"Sewing tolerance was set to "<<sewtoler<<endl;
|
||||
Standard_Integer totfree = 0, totshared = 0;
|
||||
for ( TopTools_DataMapIteratorOfDataMapOfShapeListOfShape theOF2Iter( myOriFreeEdges );
|
||||
theOF2Iter.More(); theOF2Iter.Next() ) {
|
||||
TopTools_ListIteratorOfListOfShape theOFL2Iter;
|
||||
for ( theOFL2Iter.Initialize(theOF2Iter.Value());
|
||||
theOFL2Iter.More(); theOFL2Iter.Next() ) {
|
||||
totfree += myResFreeEdges(theOFL2Iter.Value()).Extent();
|
||||
totshared += myResSharEdges(theOFL2Iter.Value()).Extent();
|
||||
}
|
||||
}
|
||||
cout<<"TOTAL: "<<totfree<<" free, "<<totshared<<" shared edges"<<endl;
|
||||
//-------------------------------
|
||||
#endif
|
||||
|
||||
/***************************************************************
|
||||
/ PERFORM EDGES REPLACEMENT
|
||||
***************************************************************/
|
||||
|
||||
TopTools_DataMapOfShapeShape theRepEdges;
|
||||
TopTools_DataMapOfShapeListOfShape theRepVertices;
|
||||
TopTools_DataMapOfShapeShape theOldVertices;
|
||||
TopTools_DataMapOfShapeListOfShape theNewVertices;
|
||||
|
||||
// Replace old edges by resulting ones
|
||||
TopoDS_Wire theNewW;
|
||||
TopoDS_Vertex theOldV1, theOldV2, theNewV1, theNewV2, theNewV;
|
||||
gp_Pnt theOldP1, theOldP2;
|
||||
Standard_Real dist1, dist2, curdist1, curdist2;
|
||||
for ( TopTools_DataMapIteratorOfDataMapOfShapeListOfShape theOEIter( myOriFreeEdges );
|
||||
theOEIter.More(); theOEIter.Next() ) {
|
||||
// Iterate on original free edges
|
||||
for ( theOriginalIter.Initialize(theOEIter.Value());
|
||||
theOriginalIter.More(); theOriginalIter.Next() ) {
|
||||
TopoDS_Edge theOldE = TopoDS::Edge(theOriginalIter.Value());
|
||||
|
||||
// Prepare empty wire to add new edges for reshape
|
||||
theBuilder.MakeWire(theNewW);
|
||||
|
||||
// Explore new edges and vertices
|
||||
Standard_Boolean emptywire = Standard_True;
|
||||
for (Standard_Integer i = 1; i<=2; i++) {
|
||||
// Select list of free or shared edges
|
||||
if (i==1) theResultsIter.Initialize(myResFreeEdges(theOldE));
|
||||
else theResultsIter.Initialize(myResSharEdges(theOldE));
|
||||
// Iterate on new edges
|
||||
for ( ; theResultsIter.More(); theResultsIter.Next() ) {
|
||||
theAuxE = theResultsIter.Value();
|
||||
if (!theAuxE.IsSame(theOldE)) {
|
||||
// Add new edge to the wire
|
||||
theBuilder.Add(theNewW,theAuxE);
|
||||
emptywire = Standard_False;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!emptywire) {
|
||||
|
||||
// Get vertices on old and new edges
|
||||
TopExp::Vertices(theOldE,theOldV1,theOldV2);
|
||||
theOldP1 = BRep_Tool::Pnt(theOldV1);
|
||||
theOldP2 = BRep_Tool::Pnt(theOldV2);
|
||||
|
||||
// Process vertices for replacing
|
||||
dist1 = -1.; dist2 = -1.;
|
||||
for ( TopExp_Explorer expv(theNewW,TopAbs_VERTEX);
|
||||
expv.More(); expv.Next() ) {
|
||||
TopoDS_Vertex theNewVtx = TopoDS::Vertex(expv.Current());
|
||||
gp_Pnt theNewPt = BRep_Tool::Pnt(theNewVtx);
|
||||
curdist1 = theOldP1.Distance(theNewPt);
|
||||
curdist2 = theOldP2.Distance(theNewPt);
|
||||
if (dist1<0 || curdist1<dist1) { dist1 = curdist1; theNewV1 = theNewVtx; }
|
||||
if (dist2<0 || curdist2<dist2) { dist2 = curdist2; theNewV2 = theNewVtx; }
|
||||
}
|
||||
|
||||
// Place results in map for replacing
|
||||
if (!theOldV1.IsSame(theNewV1)) {
|
||||
if (theRepVertices.IsBound(theOldV1)) {
|
||||
TopTools_ListOfShape& theList1 = theRepVertices(theOldV1);
|
||||
TopTools_ListIteratorOfListOfShape theIter1;
|
||||
Standard_Boolean found = Standard_False;
|
||||
for ( theIter1.Initialize(theList1); theIter1.More(); theIter1.Next() )
|
||||
if (theIter1.Value().IsSame(theNewV1)) { found = Standard_True; break; }
|
||||
if (!found) theList1.Append(theNewV1);
|
||||
}
|
||||
else {
|
||||
TopTools_ListOfShape theNewList1;
|
||||
theNewList1.Append(theNewV1);
|
||||
theRepVertices.Bind(theOldV1,theNewList1);
|
||||
}
|
||||
}
|
||||
if (!theOldV2.IsSame(theNewV2)) {
|
||||
if (theRepVertices.IsBound(theOldV2)) {
|
||||
TopTools_ListOfShape& theList2 = theRepVertices(theOldV2);
|
||||
TopTools_ListIteratorOfListOfShape theIter2;
|
||||
Standard_Boolean found = Standard_False;
|
||||
for ( theIter2.Initialize(theList2); theIter2.More(); theIter2.Next() )
|
||||
if (theIter2.Value().IsSame(theNewV2)) { found = Standard_True; break; }
|
||||
if (!found) theList2.Append(theNewV2);
|
||||
}
|
||||
else {
|
||||
TopTools_ListOfShape theNewList2;
|
||||
theNewList2.Append(theNewV2);
|
||||
theRepVertices.Bind(theOldV2,theNewList2);
|
||||
}
|
||||
}
|
||||
|
||||
// Bind edge to replace
|
||||
theRepEdges.Bind(theOldE,theNewW);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!theRepEdges.IsEmpty()) {
|
||||
|
||||
Handle(ShapeBuild_ReShape) theReShape = new ShapeBuild_ReShape;
|
||||
|
||||
// Replace edges
|
||||
for ( TopTools_DataMapIteratorOfDataMapOfShapeShape theREIter( theRepEdges );
|
||||
theREIter.More(); theREIter.Next() ) {
|
||||
theReShape->Replace(theREIter.Key()/*.Oriented(TopAbs_FORWARD)*/,
|
||||
theREIter.Value()/*.Oriented(TopAbs_FORWARD)*/);
|
||||
}
|
||||
//smh#8
|
||||
TopoDS_Shape tmpReShape = theReShape->Apply(result);
|
||||
result = TopoDS::Shell(tmpReShape);
|
||||
if (theReShape->Status(ShapeExtend_OK)) {
|
||||
#ifdef DEB
|
||||
cout<<"Warning: ShapeFix_FaceConnect::Build: Edges not replaced by ReShape"<<endl;
|
||||
#endif
|
||||
}
|
||||
else if (theReShape->Status(ShapeExtend_FAIL1)) {
|
||||
#ifdef DEB
|
||||
cout<<"Error: ShapeFix_FaceConnect::Build: ReShape failed on edges"<<endl;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
|
||||
Handle(ShapeFix_Wire) SFW = new ShapeFix_Wire;
|
||||
Handle(ShapeFix_Face) SFF = new ShapeFix_Face;
|
||||
ShapeAnalysis_Edge SAE;
|
||||
Standard_Real f,l;
|
||||
Handle(Geom2d_Curve) c2d;
|
||||
Handle(ShapeExtend_WireData) sewd;
|
||||
|
||||
// Perform necessary fixes on subshapes
|
||||
//smh#8
|
||||
TopoDS_Shape emptyCopiedShell = result.EmptyCopied();
|
||||
TopoDS_Shell theShell = TopoDS::Shell(emptyCopiedShell);
|
||||
for ( TopoDS_Iterator itf1(result); itf1.More(); itf1.Next() ) {
|
||||
TopoDS_Face newface = TopoDS::Face(itf1.Value());
|
||||
//smh#8
|
||||
TopoDS_Shape emptyCopiedFace = newface.EmptyCopied();
|
||||
TopoDS_Face EmpFace = TopoDS::Face(emptyCopiedFace);
|
||||
for ( TopoDS_Iterator itw(newface); itw.More(); itw.Next() ) {
|
||||
if(itw.Value().ShapeType() != TopAbs_WIRE)
|
||||
continue;
|
||||
TopoDS_Wire theWire = TopoDS::Wire(itw.Value());
|
||||
|
||||
sewd = new ShapeExtend_WireData( theWire );
|
||||
ShapeAnalysis_WireOrder SAWO(Standard_False, 0);
|
||||
for (Standard_Integer i = 1; i <= sewd->NbEdges(); i++) {
|
||||
|
||||
//smh#8
|
||||
TopoDS_Shape tmpFace = EmpFace.Oriented(TopAbs_FORWARD);
|
||||
if (!SAE.PCurve(sewd->Edge(i),
|
||||
TopoDS::Face(tmpFace),
|
||||
c2d,f,l)) continue;
|
||||
SAWO.Add(c2d->Value(f).XY(),c2d->Value(l).XY());
|
||||
}
|
||||
SAWO.Perform();
|
||||
|
||||
SFW->Load(sewd);
|
||||
SFW->FixReorder(SAWO);
|
||||
SFW->FixReorder();
|
||||
|
||||
SFW->SetFace(EmpFace);
|
||||
SFW->SetPrecision(fixtoler);
|
||||
SFW->SetMaxTolerance(sewtoler);
|
||||
|
||||
SFW->FixEdgeCurves();
|
||||
SFW->FixSelfIntersection();
|
||||
theWire = SFW->Wire();
|
||||
theBuilder.Add(EmpFace,theWire);
|
||||
}
|
||||
// #ifdef AIX CKY : applies to all platforms
|
||||
SFF->Init(EmpFace);
|
||||
// SFF->Init(TopoDS::Face(EmpFace));
|
||||
|
||||
TopTools_DataMapOfShapeListOfShape MapWires;
|
||||
MapWires.Clear();
|
||||
if (SFF->FixOrientation(MapWires)) EmpFace = SFF->Face();
|
||||
theBuilder.Add(theShell,EmpFace);
|
||||
}
|
||||
result = theShell;
|
||||
|
||||
if (!theRepVertices.IsEmpty()) {
|
||||
|
||||
// Prepare vertices to replace
|
||||
TopoDS_Shape theOld, theNew, theRep, theAux;
|
||||
for ( TopTools_DataMapIteratorOfDataMapOfShapeListOfShape theRV1Iter( theRepVertices );
|
||||
theRV1Iter.More(); theRV1Iter.Next() ) {
|
||||
// Get the old vertex, create empty list of replaced vertices
|
||||
theOld = theRV1Iter.Key();
|
||||
TopTools_ListOfShape theNewList;
|
||||
// Explore the list of new vertices
|
||||
TopTools_ListIteratorOfListOfShape theN1Iter;
|
||||
for ( theN1Iter.Initialize(theRV1Iter.Value()); theN1Iter.More(); theN1Iter.Next() ) {
|
||||
theNew = theN1Iter.Value();
|
||||
if (theOldVertices.IsBound(theNew)) {
|
||||
// Vertex has a replacing vertex in the map
|
||||
theRep = theOldVertices(theNew);
|
||||
if (!theRep.IsSame(theOld)) {
|
||||
// Vertex is not in current list
|
||||
theOldVertices.Bind(theRep,theOld);
|
||||
theNewList.Append(theRep);
|
||||
TopTools_ListIteratorOfListOfShape theN3Iter;
|
||||
for ( theN3Iter.Initialize(theNewVertices(theRep));
|
||||
theN3Iter.More(); theN3Iter.Next() ) {
|
||||
theAux = theN3Iter.Value();
|
||||
theOldVertices(theAux) = theOld;
|
||||
theNewList.Append(theAux);
|
||||
}
|
||||
theNewVertices.UnBind(theRep);
|
||||
}
|
||||
}
|
||||
else {
|
||||
theOldVertices.Bind(theNew,theOld);
|
||||
theNewList.Append(theNew);
|
||||
}
|
||||
}
|
||||
theNewVertices.Bind(theOld,theNewList);
|
||||
}
|
||||
|
||||
// Update vertices positions and tolerances
|
||||
TopoDS_Vertex theNewVert, theOldVert;
|
||||
for ( TopTools_DataMapIteratorOfDataMapOfShapeListOfShape theRV2Iter( theNewVertices );
|
||||
theRV2Iter.More(); theRV2Iter.Next() ) {
|
||||
theNewVert = TopoDS::Vertex(theRV2Iter.Key());
|
||||
// Calculate the vertex position
|
||||
gp_Pnt theLBound, theRBound, thePosition;
|
||||
theLBound = theRBound = BRep_Tool::Pnt(theNewVert);
|
||||
TopTools_ListIteratorOfListOfShape theN2Iter;
|
||||
for ( theN2Iter.Initialize(theRV2Iter.Value()); theN2Iter.More(); theN2Iter.Next() ) {
|
||||
thePosition = BRep_Tool::Pnt(TopoDS::Vertex(theN2Iter.Value()));
|
||||
Standard_Real val = thePosition.X();
|
||||
if ( val < theLBound.X() ) theLBound.SetX( val );
|
||||
else if ( val > theRBound.X() ) theRBound.SetX( val );
|
||||
val = thePosition.Y();
|
||||
if ( val < theLBound.Y() ) theLBound.SetY( val );
|
||||
else if ( val > theRBound.Y() ) theRBound.SetY( val );
|
||||
val = thePosition.Z();
|
||||
if ( val < theLBound.Z() ) theLBound.SetZ( val );
|
||||
else if ( val > theRBound.Z() ) theRBound.SetZ( val );
|
||||
}
|
||||
thePosition = gp_Pnt((theLBound.XYZ() + theRBound.XYZ())/2.);
|
||||
Standard_Real theTolerance = 0., curtoler;
|
||||
// Calculate the vertex tolerance
|
||||
for ( theN2Iter.Initialize(theRV2Iter.Value()); theN2Iter.More(); theN2Iter.Next() ) {
|
||||
theOldVert = TopoDS::Vertex(theN2Iter.Value());
|
||||
curtoler = thePosition.Distance(BRep_Tool::Pnt(theOldVert)) +
|
||||
BRep_Tool::Tolerance(theOldVert);
|
||||
if (curtoler > theTolerance) theTolerance = curtoler;
|
||||
}
|
||||
curtoler = thePosition.Distance(BRep_Tool::Pnt(theNewVert)) +
|
||||
BRep_Tool::Tolerance(theNewVert);
|
||||
if (curtoler > theTolerance) theTolerance = curtoler;
|
||||
theBuilder.UpdateVertex( theNewVert, thePosition, theTolerance );
|
||||
}
|
||||
|
||||
// Replace vertices
|
||||
theReShape->Clear();
|
||||
for ( TopTools_DataMapIteratorOfDataMapOfShapeShape theNVIter( theOldVertices );
|
||||
theNVIter.More(); theNVIter.Next() )
|
||||
theReShape->Replace(theNVIter.Key().Oriented(TopAbs_FORWARD),
|
||||
theNVIter.Value().Oriented(TopAbs_FORWARD));
|
||||
//smh#8
|
||||
TopoDS_Shape tmpshape = theReShape->Apply(result);
|
||||
result = TopoDS::Shell(tmpshape);
|
||||
|
||||
if (theReShape->Status(ShapeExtend_FAIL1)) {
|
||||
#ifdef DEB
|
||||
cout<<"Error: ShapeFix_FaceConnect::Build: ReShape failed on vertices"<<endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEB
|
||||
//-------------------------------
|
||||
//szv debug - reshape results
|
||||
//-------------------------------
|
||||
cout<<endl<<"FACE CONNECT REPLACEMENT RESULTS:"<<endl;
|
||||
cout<<"---------------------------------"<<endl;
|
||||
TopTools_MapOfShape theTmpMap;
|
||||
Standard_Integer toteold = 0, totenew = 0;
|
||||
for ( TopTools_DataMapIteratorOfDataMapOfShapeShape theR1Iter( theRepEdges );
|
||||
theR1Iter.More(); theR1Iter.Next() ) {
|
||||
toteold++;
|
||||
if (!theTmpMap.Contains(theR1Iter.Value())) {
|
||||
theTmpMap.Add(theR1Iter.Value());
|
||||
for ( TopoDS_Iterator itw(TopoDS::Wire(theR1Iter.Value()));
|
||||
itw.More(); itw.Next() ) totenew++;
|
||||
}
|
||||
}
|
||||
Standard_Integer totvold = 0, totvnew = 0;
|
||||
for ( TopTools_DataMapIteratorOfDataMapOfShapeShape theR2Iter( theOldVertices );
|
||||
theR2Iter.More(); theR2Iter.Next() ) {
|
||||
totvold++;
|
||||
if (!theTmpMap.Contains(theR2Iter.Value())) {
|
||||
theTmpMap.Add(theR2Iter.Value());
|
||||
totvnew++;
|
||||
}
|
||||
}
|
||||
cout<<"TOTAL: "<<toteold<<" edges, "<<totvold<<" vertices replaced by "
|
||||
<<totenew<<" edges, "<<totvnew<<" vertices"<<endl<<endl;
|
||||
//-------------------------------
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Clear
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_FaceConnect::Clear()
|
||||
{
|
||||
myConnected.Clear();
|
||||
myOriFreeEdges.Clear();
|
||||
myResFreeEdges.Clear();
|
||||
myResSharEdges.Clear();
|
||||
}
|
87
src/ShapeFix/ShapeFix_FixSmallFace.cdl
Executable file
87
src/ShapeFix/ShapeFix_FixSmallFace.cdl
Executable file
@@ -0,0 +1,87 @@
|
||||
-- File: ShapeFix_FixSmallFace.cdl
|
||||
-- Created: Mon Sep 13 10:12:42 1999
|
||||
-- Author: data exchange team
|
||||
-- <det@nnov.matra-dtv.fr>
|
||||
---Copyright: Matra Datavision 1999
|
||||
|
||||
|
||||
class FixSmallFace from ShapeFix inherits Root from ShapeFix
|
||||
|
||||
---Purpose:
|
||||
|
||||
uses
|
||||
Shape from TopoDS,
|
||||
Face from TopoDS,
|
||||
Edge from TopoDS,
|
||||
Compound from TopoDS,
|
||||
CheckSmallFace from ShapeAnalysis
|
||||
|
||||
is
|
||||
Create returns FixSmallFace;
|
||||
---Purpose :
|
||||
Init(me: mutable; S : Shape from TopoDS);
|
||||
---Purpose :
|
||||
|
||||
Perform(me:mutable);
|
||||
---Purpose :
|
||||
-- Fixing case of spot face
|
||||
FixSpotFace (me: mutable) returns Shape from TopoDS;
|
||||
---Purpose : Fixing case of spot face, if tol = -1 used local tolerance.
|
||||
ReplaceVerticesInCaseOfSpot(me; F : in out Face from TopoDS; tol : Real) returns Boolean;
|
||||
---Purpose : Compute average vertex and replacing vertices by new one.
|
||||
|
||||
RemoveFacesInCaseOfSpot(me; F : Face from TopoDS) returns Boolean;
|
||||
---Purpose : Remove spot face from compound
|
||||
--
|
||||
|
||||
-- Fixing case of strip face
|
||||
FixStripFace(me: mutable; wasdone: Boolean = Standard_False) returns Shape from TopoDS;
|
||||
---Purpose : Fixing case of strip face, if tol = -1 used local tolerance
|
||||
|
||||
ReplaceInCaseOfStrip(me;F : in out Face from TopoDS; E1 : in out Edge from TopoDS; E2 : in out Edge from TopoDS;tol : Real) returns Boolean;
|
||||
---Purpose : Replace veretces and edges.
|
||||
--
|
||||
RemoveFacesInCaseOfStrip(me; F : Face from TopoDS) returns Boolean;
|
||||
---Purpose : Remove strip face from compound.
|
||||
|
||||
ComputeSharedEdgeForStripFace(me; F : Face from TopoDS; E1 : Edge from TopoDS; E2 : Edge from TopoDS;
|
||||
F1 : Face from TopoDS; tol : Real )
|
||||
returns Edge from TopoDS;
|
||||
---Purpose : Compute average edge for strip face
|
||||
|
||||
-- Fixing case split
|
||||
|
||||
FixSplitFace(me: mutable; S: Shape from TopoDS) returns Shape from TopoDS;
|
||||
---Purpose :
|
||||
--
|
||||
|
||||
SplitFaces(me: mutable) returns Shape from TopoDS;
|
||||
---Purpose : Split faces by splitting vertices
|
||||
--
|
||||
|
||||
SplitOneFace(me: mutable; F : in out Face from TopoDS;theSplittedFaces: in out Compound from TopoDS) returns Boolean;
|
||||
---Purpose : Compute data for face splitting.
|
||||
--
|
||||
|
||||
RemoveSmallFaces(me:mutable) returns Shape from TopoDS;
|
||||
---Purpose : Remove small faces from compound.
|
||||
|
||||
--Fixes after removing
|
||||
FixFace(me: mutable; F: Face from TopoDS) returns Face from TopoDS;
|
||||
FixShape(me: mutable) returns Shape from TopoDS;
|
||||
|
||||
Shape(me : mutable) returns Shape from TopoDS;
|
||||
|
||||
FixPinFace (me: mutable;F : in out Face from TopoDS) returns Boolean;
|
||||
|
||||
fields
|
||||
|
||||
myShape : Shape from TopoDS;
|
||||
myResult : Shape from TopoDS;
|
||||
myStatus : Integer; -- error status
|
||||
myAnalyzer : CheckSmallFace from ShapeAnalysis;
|
||||
|
||||
|
||||
|
||||
|
||||
end FixSmallFace;
|
775
src/ShapeFix/ShapeFix_FixSmallFace.cxx
Executable file
775
src/ShapeFix/ShapeFix_FixSmallFace.cxx
Executable file
@@ -0,0 +1,775 @@
|
||||
#include <ShapeFix_FixSmallFace.ixx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Shell.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopoDS_Iterator.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
|
||||
#include <Geom_Curve.hxx>
|
||||
#include <Geom_Surface.hxx>
|
||||
#include <Geom_BSplineSurface.hxx>
|
||||
#include <Geom_BezierSurface.hxx>
|
||||
|
||||
#include <ShapeAnalysis_Curve.hxx>
|
||||
//#include <GeomLProp_SLProps.hxx>
|
||||
#include <GeomAdaptor_Surface.hxx>
|
||||
#include <Geom_ElementarySurface.hxx>
|
||||
//#include <TColStd_Array2OfReal.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
//#include <TColStd_Array1OfReal.hxx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TopTools_Array1OfShape.hxx>
|
||||
|
||||
#include <TColgp_Array2OfPnt.hxx>
|
||||
|
||||
#include <TColgp_SequenceOfXYZ.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <ShapeBuild_ReShape.hxx>
|
||||
#include <BRepTools.hxx>
|
||||
#include <ShapeFix_Edge.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <TopoDS_Wire.hxx>
|
||||
#include <ShapeFix_Wire.hxx>
|
||||
#include <Geom_Line.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <ElCLib.hxx>
|
||||
#include <TopoDS_Builder.hxx>
|
||||
#include <TopoDS_Compound.hxx>
|
||||
#include <Poly_Polygon3D.hxx>
|
||||
#include <Geom2d_Curve.hxx>
|
||||
#include <BRepLib.hxx>
|
||||
#include <GeomLib.hxx>
|
||||
#include <ShapeFix_Face.hxx>
|
||||
#include <ShapeFix_Wire.hxx>
|
||||
#include <Geom_TrimmedCurve.hxx>
|
||||
#include <GeomAdaptor_Curve.hxx>
|
||||
#include <ShapeFix_Shape.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopTools_DataMapOfShapeListOfShape.hxx>
|
||||
#include <ShapeAnalysis_DataMapOfShapeListOfReal.hxx>
|
||||
#include <TopoDS_Compound.hxx>
|
||||
#include <TopoDS_Iterator.hxx>
|
||||
|
||||
ShapeFix_FixSmallFace::ShapeFix_FixSmallFace()
|
||||
{
|
||||
myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
|
||||
SetPrecision(Precision::Confusion());
|
||||
|
||||
}
|
||||
|
||||
void ShapeFix_FixSmallFace::Init(const TopoDS_Shape& S)
|
||||
{
|
||||
myShape = S;
|
||||
if ( Context().IsNull() )
|
||||
SetContext ( new ShapeBuild_ReShape );
|
||||
myResult = myShape;
|
||||
Context()->Apply(myShape);
|
||||
}
|
||||
|
||||
|
||||
void ShapeFix_FixSmallFace::Perform()
|
||||
{
|
||||
FixSpotFace();
|
||||
FixStripFace();
|
||||
}
|
||||
|
||||
TopoDS_Shape ShapeFix_FixSmallFace::FixSpotFace()
|
||||
{
|
||||
|
||||
// gp_Pnt spot;
|
||||
// Standard_Real spotol;
|
||||
Standard_Boolean done = Standard_False;
|
||||
TopAbs_ShapeEnum st = myShape.ShapeType();
|
||||
if (st == TopAbs_COMPOUND || st == TopAbs_COMPSOLID || st == TopAbs_SOLID || st == TopAbs_SHELL || st == TopAbs_FACE) {
|
||||
for (TopExp_Explorer itf (myShape,TopAbs_FACE); itf.More(); itf.Next()) {
|
||||
//smh#8
|
||||
TopoDS_Shape tmpFace = Context()->Apply(itf.Current());
|
||||
TopoDS_Face F = TopoDS::Face (tmpFace);
|
||||
if(F.IsNull()) continue;
|
||||
if (myAnalyzer.CheckSpotFace (F,Precision()))
|
||||
{
|
||||
ReplaceVerticesInCaseOfSpot(F,Precision());
|
||||
RemoveFacesInCaseOfSpot(F);
|
||||
myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
|
||||
done = Standard_True;
|
||||
}
|
||||
}
|
||||
myShape = Context()->Apply(myShape);
|
||||
Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire;
|
||||
if (done)
|
||||
{
|
||||
if (myShape.IsNull()) return myShape;
|
||||
/*ShapeFix_Wire sfw;
|
||||
sfw.SetContext(Context());
|
||||
sfw.SetPrecision(Precision::Confusion());
|
||||
if (myShape.IsNull()) return myShape;
|
||||
for (TopExp_Explorer itfw (myShape,TopAbs_FACE); itfw.More(); itfw.Next()) {
|
||||
for (TopExp_Explorer itw (myShape,TopAbs_WIRE); itw.More(); itw.Next()) {
|
||||
TopoDS_Wire w = TopoDS::Wire(itw.Current());
|
||||
sfw.Init(w, TopoDS::Face(itfw.Current()), Precision::Confusion());
|
||||
sfw->FixNotchedEdgesMode() = 0;
|
||||
if(sfw.Perform())
|
||||
Context()->Replace(w, sfw.Wire());
|
||||
}
|
||||
}*/
|
||||
myShape = FixShape();
|
||||
}
|
||||
|
||||
//myShape = Context()->Apply(myShape);
|
||||
myResult = myShape;
|
||||
}
|
||||
return myShape;
|
||||
}
|
||||
|
||||
Standard_Boolean ShapeFix_FixSmallFace::ReplaceVerticesInCaseOfSpot(TopoDS_Face& F,const Standard_Real /*tol*/) const
|
||||
{
|
||||
|
||||
TColgp_SequenceOfXYZ thePositions;
|
||||
gp_XYZ thePosition;
|
||||
BRep_Builder theBuilder;
|
||||
Standard_Real theMaxDev;
|
||||
Standard_Real theMaxTol = 0.0;
|
||||
thePositions.Clear();
|
||||
gp_Pnt thePoint;
|
||||
//smh#8
|
||||
TopoDS_Shape tmpFace = Context()->Apply(F);
|
||||
F = TopoDS::Face(tmpFace);
|
||||
// gka Mar2000 Protection against faces without wires
|
||||
// but they occur due to bugs in the algorithm itself, it needs to be fixed
|
||||
Standard_Boolean isWir = Standard_False;
|
||||
for(TopoDS_Iterator itw(F,Standard_False) ; itw.More();itw.Next()) {
|
||||
if(itw.Value().ShapeType() != TopAbs_WIRE)
|
||||
continue;
|
||||
TopoDS_Wire w1 = TopoDS::Wire(itw.Value());
|
||||
if (!w1.IsNull()) {isWir = Standard_True; break;}
|
||||
}
|
||||
if(!isWir) return Standard_True;
|
||||
//Accumulating positions and maximal vertex tolerance
|
||||
for (TopExp_Explorer iter_vertex(F,TopAbs_VERTEX); iter_vertex.More(); iter_vertex.Next()) {
|
||||
TopoDS_Vertex V = TopoDS::Vertex (iter_vertex.Current());
|
||||
thePoint = BRep_Tool::Pnt(V);
|
||||
if (theMaxTol <= (BRep_Tool::Tolerance(V))) theMaxTol = BRep_Tool::Tolerance(V);
|
||||
thePositions.Append(thePoint.XYZ());
|
||||
}
|
||||
//Calculate common vertex position
|
||||
thePosition = gp_XYZ(0.,0.,0.);
|
||||
Standard_Integer theNbPos = thePositions.Length();
|
||||
Standard_Integer i; // svv Jan11 2000 : porting on DEC
|
||||
for ( i = 1; i <= theNbPos; i++ ) thePosition += thePositions.Value(i);
|
||||
if ( theNbPos > 1 ) thePosition /= theNbPos;
|
||||
|
||||
// Calculate maximal deviation
|
||||
theMaxDev = 0.;
|
||||
for ( i = 1; i <= theNbPos; i++ ) {
|
||||
Standard_Real theDeviation = (thePosition-thePositions.Value(i)).Modulus();
|
||||
if ( theDeviation > theMaxDev ) theMaxDev = theDeviation;
|
||||
}
|
||||
theMaxDev *= 1.00001;
|
||||
|
||||
//Cretate new vertex with mean point
|
||||
TopoDS_Vertex theSharedVertex;
|
||||
theBuilder.MakeVertex(theSharedVertex);
|
||||
theBuilder.UpdateVertex( theSharedVertex, gp_Pnt(thePosition), theMaxDev+theMaxTol/2 );
|
||||
//Use external tolerance
|
||||
// if (tol!=-1.0) theBuilder.UpdateVertex( theSharedVertex, tol);
|
||||
//Replacing all vertices in the face by new one
|
||||
TopoDS_Vertex theNewVertex;
|
||||
for ( TopExp_Explorer iter_vert(F,TopAbs_VERTEX); iter_vert.More(); iter_vert.Next()) {
|
||||
TopoDS_Vertex V = TopoDS::Vertex (iter_vert.Current());
|
||||
if (V.Orientation()==TopAbs_FORWARD)
|
||||
//smh#8
|
||||
{
|
||||
TopoDS_Shape tmpVertexFwd = theSharedVertex.Oriented(TopAbs_FORWARD);
|
||||
theNewVertex = TopoDS::Vertex(tmpVertexFwd);
|
||||
}
|
||||
else
|
||||
//smh#8
|
||||
{
|
||||
TopoDS_Shape tmpVertexRev = theSharedVertex.Oriented(TopAbs_REVERSED);
|
||||
theNewVertex = TopoDS::Vertex(tmpVertexRev);
|
||||
}
|
||||
Context()->Replace(V, theNewVertex);
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Boolean ShapeFix_FixSmallFace::RemoveFacesInCaseOfSpot(const TopoDS_Face& F) const
|
||||
{
|
||||
for ( TopExp_Explorer iter_vert(F,TopAbs_EDGE); iter_vert.More(); iter_vert.Next()) {
|
||||
TopoDS_Edge Ed = TopoDS::Edge (iter_vert.Current());
|
||||
Context()->Remove(Ed);
|
||||
}
|
||||
Context()->Remove(F);
|
||||
return Standard_True;
|
||||
|
||||
|
||||
}
|
||||
|
||||
TopoDS_Shape ShapeFix_FixSmallFace::FixStripFace(const Standard_Boolean wasdone)
|
||||
{
|
||||
if(myShape.IsNull()) return myShape;
|
||||
TopAbs_ShapeEnum st = myShape.ShapeType();
|
||||
// BRep_Builder theBuilder;
|
||||
Standard_Boolean done = wasdone;
|
||||
if (st == TopAbs_COMPOUND || st == TopAbs_COMPSOLID ||st == TopAbs_SOLID || st == TopAbs_SHELL || st == TopAbs_FACE) {
|
||||
for (TopExp_Explorer itf (myShape,TopAbs_FACE); itf.More(); itf.Next()) {
|
||||
TopoDS_Face F = TopoDS::Face (itf.Current());
|
||||
//smh#8
|
||||
TopoDS_Shape tmpFace = Context()->Apply(F);
|
||||
F= TopoDS::Face(tmpFace);
|
||||
if(F.IsNull()) continue;
|
||||
// Standard_Real dmax = 1;
|
||||
TopoDS_Edge E1,E2;
|
||||
if (myAnalyzer.CheckStripFace (F, E1,E2,Precision()))
|
||||
{
|
||||
if(ReplaceInCaseOfStrip(F,E1,E2, Precision()))
|
||||
RemoveFacesInCaseOfStrip(F);
|
||||
myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
|
||||
done = Standard_True;
|
||||
}
|
||||
}
|
||||
myShape = Context()->Apply(myShape);
|
||||
//Particular case of empty shell
|
||||
if (!myShape.IsNull())
|
||||
{
|
||||
for (TopExp_Explorer exp_s (myShape,TopAbs_SHELL); exp_s.More(); exp_s.Next()) {
|
||||
TopoDS_Shell Sh = TopoDS::Shell (exp_s.Current());
|
||||
TopExp_Explorer ex_sh(Sh,TopAbs_FACE);
|
||||
if (!ex_sh.More()) { Context()->Remove(Sh);
|
||||
// cout << "Empty shell was removed" << endl;
|
||||
}
|
||||
}
|
||||
myShape = Context()->Apply(myShape);
|
||||
//Fixing of missing pcurves on new edges, if thay were inserted
|
||||
if (done)
|
||||
{
|
||||
if (myShape.IsNull()) return myShape;
|
||||
TopoDS_Shape theResult;
|
||||
myShape = FixShape();
|
||||
//myShape = Context()->Apply(myShape);
|
||||
myResult = myShape;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return myShape;
|
||||
|
||||
}
|
||||
|
||||
Standard_Boolean ShapeFix_FixSmallFace::ReplaceInCaseOfStrip(TopoDS_Face& F,TopoDS_Edge& E1,TopoDS_Edge& E2, const Standard_Real tol) const
|
||||
{
|
||||
if(E1.IsNull() || E2.IsNull()) return Standard_False;
|
||||
TopoDS_Edge theSharedEdge;
|
||||
TopoDS_Face F1,F2;
|
||||
//smh#8
|
||||
TopoDS_Shape tmpFace = Context()->Apply(F);
|
||||
F= TopoDS::Face(tmpFace);
|
||||
for(TopExp_Explorer expf(myShape,TopAbs_FACE); expf.More(); expf.Next()) {
|
||||
//smh#8
|
||||
TopoDS_Shape tmpShape = Context()->Apply(expf.Current());
|
||||
TopoDS_Face tempF = TopoDS::Face (tmpShape);
|
||||
if(tempF.IsNull() || tempF.IsSame(F)) continue;
|
||||
for(TopExp_Explorer expe(tempF,TopAbs_EDGE); expe.More(); expe.Next()) {
|
||||
TopoDS_Edge tempE = TopoDS::Edge (expe.Current());
|
||||
if(tempE.IsSame(E1)) F1 = tempF;
|
||||
if(tempE.IsSame(E2)) F2 = tempF;
|
||||
if(!F1.IsNull()) break; // && !F2.IsNull()) break;
|
||||
}
|
||||
}
|
||||
|
||||
//Compute shared edge for this face
|
||||
if(F1.IsNull() && F2.IsNull()) return Standard_True;
|
||||
TopoDS_Edge E1tmp = E1;
|
||||
TopoDS_Edge E2tmp = E2;
|
||||
if(F1.IsNull()) {
|
||||
E1tmp = E2;
|
||||
E2tmp = E1;
|
||||
F1 = F2;
|
||||
}
|
||||
theSharedEdge = ComputeSharedEdgeForStripFace(F, E1tmp, E2tmp, F1, tol);
|
||||
//Replace two long edges by new one
|
||||
if (theSharedEdge.IsNull()) return Standard_False;
|
||||
if (E1.Orientation()==TopAbs_REVERSED) {
|
||||
Context()->Replace(E1tmp, theSharedEdge.Oriented(TopAbs_REVERSED));
|
||||
if(F.Orientation() == F1.Orientation())
|
||||
Context()->Replace(E2tmp, theSharedEdge);
|
||||
else
|
||||
Context()->Replace(E2tmp, theSharedEdge.Oriented(TopAbs_REVERSED));
|
||||
}
|
||||
else
|
||||
{
|
||||
Context()->Replace(E1tmp, theSharedEdge);
|
||||
if(F.Orientation() == F1.Orientation())
|
||||
Context()->Replace(E2tmp, theSharedEdge.Oriented(TopAbs_REVERSED));
|
||||
else
|
||||
Context()->Replace(E2tmp, theSharedEdge);
|
||||
}
|
||||
|
||||
//Remove short edges
|
||||
for (TopExp_Explorer exp_e (F,TopAbs_EDGE); exp_e.More(); exp_e.Next()) {
|
||||
TopoDS_Edge shortedge = TopoDS::Edge (exp_e.Current());
|
||||
if (!shortedge.IsSame(E1tmp) && !shortedge.IsSame(E2tmp)) Context()->Remove(shortedge);
|
||||
}
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Boolean ShapeFix_FixSmallFace::RemoveFacesInCaseOfStrip(const TopoDS_Face& F) const
|
||||
{
|
||||
Context()->Remove(F);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
TopoDS_Edge ShapeFix_FixSmallFace::ComputeSharedEdgeForStripFace(const TopoDS_Face& /*F*/,const TopoDS_Edge& E1,const TopoDS_Edge& E2,const TopoDS_Face& F1,const Standard_Real tol) const
|
||||
{
|
||||
|
||||
BRep_Builder theBuilder;
|
||||
//Compute deviation between two vertices and create new vertices
|
||||
TopoDS_Edge theNewEdge;
|
||||
TopoDS_Vertex V1,V2, V3, V4;
|
||||
TopExp::Vertices (E1,V1,V2);
|
||||
TopExp::Vertices (E2,V3,V4);
|
||||
gp_Pnt p1, p2;
|
||||
Standard_Real dev;
|
||||
p1 = BRep_Tool::Pnt(V1);
|
||||
p2 = BRep_Tool::Pnt(V3);
|
||||
dev = p1.Distance(p2);
|
||||
TopoDS_Vertex theFirstVer;
|
||||
TopoDS_Vertex theSecondVer;
|
||||
theBuilder.MakeVertex(theFirstVer);
|
||||
theBuilder.MakeVertex(theSecondVer);
|
||||
gp_XYZ thePosition;
|
||||
TopoDS_Shape temp;
|
||||
|
||||
if ((dev<=BRep_Tool::Tolerance (V1)) || (dev<=BRep_Tool::Tolerance (V3)) || (dev<=tol)) {
|
||||
if (V1.IsSame(V3))
|
||||
// #ifdef AIX CKY : applies to all platforms
|
||||
theFirstVer = V1;
|
||||
// theFirstVer = TopoDS::Vertex(V1);
|
||||
|
||||
else {
|
||||
dev = (dev/2)*1.0001;
|
||||
thePosition = (p1.XYZ()+p2.XYZ())/2;
|
||||
theBuilder.UpdateVertex(theFirstVer, gp_Pnt(thePosition), dev );
|
||||
//if(Context()->Status(V1, temp) != 0) theFirstVer = TopoDS::Vertex (temp); //If this vertex already recorded in map
|
||||
//else //take recorded vertex
|
||||
// if(theRepVert->Status(V3, temp) != 0) theFirstVer = TopoDS::Vertex (temp);
|
||||
if (V1.Orientation()==TopAbs_FORWARD) Context()->Replace(V1, theFirstVer.Oriented(TopAbs_FORWARD));
|
||||
else Context()->Replace(V1, theFirstVer.Oriented(TopAbs_REVERSED));
|
||||
if (V3.Orientation()==TopAbs_FORWARD) Context()->Replace(V3, theFirstVer.Oriented(TopAbs_FORWARD));
|
||||
else Context()->Replace(V3, theFirstVer.Oriented(TopAbs_REVERSED));
|
||||
|
||||
}
|
||||
if(V1.IsSame(V2) || V3.IsSame(V4))
|
||||
theSecondVer = theFirstVer;
|
||||
else {
|
||||
if (!V2.IsSame(V4)) {
|
||||
// #ifdef AIX CKY : applies to all platforms
|
||||
|
||||
p1 = BRep_Tool::Pnt(V2);
|
||||
p2 = BRep_Tool::Pnt(V4);
|
||||
dev = p1.Distance(p2);
|
||||
thePosition = (p1.XYZ()+p2.XYZ())/2;
|
||||
theBuilder.UpdateVertex(theSecondVer, gp_Pnt(thePosition), dev );
|
||||
//if(theRepVert->Status(V2, temp) != 0) theSecondVer = TopoDS::Vertex (temp); //If this vertex already recorded in map
|
||||
//else
|
||||
// if(theRepVert->Status(V4, temp) != 0) theSecondVer = TopoDS::Vertex (temp);
|
||||
}
|
||||
else theSecondVer = V2;
|
||||
|
||||
}
|
||||
if (!V2.IsSame(theSecondVer)) {
|
||||
if (V2.Orientation()==TopAbs_FORWARD) Context()->Replace(V2, theSecondVer.Oriented(TopAbs_FORWARD));
|
||||
else Context()->Replace(V2, theSecondVer.Oriented(TopAbs_REVERSED));
|
||||
if (V4.Orientation()==TopAbs_FORWARD) Context()->Replace(V4, theSecondVer.Oriented(TopAbs_FORWARD));
|
||||
else Context()->Replace(V4, theSecondVer.Oriented(TopAbs_REVERSED));
|
||||
}
|
||||
}
|
||||
else {
|
||||
p2 = BRep_Tool::Pnt(V4);
|
||||
dev = p1.Distance(p2);
|
||||
if ((dev<=BRep_Tool::Tolerance (V1)) || (dev<=BRep_Tool::Tolerance (V4)) || (dev<=tol)) {
|
||||
if (V1.IsSame(V4))
|
||||
// #ifdef AIX CKY : applies to all platforms
|
||||
theFirstVer = V1;
|
||||
// theFirstVer = TopoDS::Vertex(V1);
|
||||
|
||||
else {
|
||||
dev = (dev/2)*1.0001;
|
||||
thePosition = (p1.XYZ()+p2.XYZ())/2;
|
||||
theBuilder.UpdateVertex(theFirstVer, gp_Pnt(thePosition), dev );
|
||||
// if(theRepVert->Status(V1, temp) != 0) theFirstVer = TopoDS::Vertex (temp); //If this vertex already recorded in map
|
||||
// else
|
||||
// if(theRepVert->Status(V4, temp) != 0) theFirstVer = TopoDS::Vertex (temp);
|
||||
if (V1.Orientation()==TopAbs_FORWARD) Context()->Replace(V1, theFirstVer.Oriented(TopAbs_FORWARD));
|
||||
else Context()->Replace(V1, theFirstVer.Oriented(TopAbs_REVERSED));
|
||||
if (V4.Orientation()==TopAbs_FORWARD) Context()->Replace(V4, theFirstVer.Oriented(TopAbs_FORWARD));
|
||||
else Context()->Replace(V4, theFirstVer.Oriented(TopAbs_REVERSED));
|
||||
}
|
||||
if(V1.IsSame(V2) || V3.IsSame(V4))
|
||||
theSecondVer = theFirstVer;
|
||||
else {
|
||||
|
||||
if (!V2.IsSame(V3)) {
|
||||
p1 = BRep_Tool::Pnt(V2);
|
||||
p2 = BRep_Tool::Pnt(V3);
|
||||
dev = p1.Distance(p2);
|
||||
thePosition = (p1.XYZ()+p2.XYZ())/2;
|
||||
theBuilder.UpdateVertex(theSecondVer, gp_Pnt(thePosition), dev );
|
||||
}
|
||||
else theSecondVer = V2;
|
||||
}
|
||||
// if(theRepVert->Status(V2, temp) != 0) theSecondVer = TopoDS::Vertex (temp); //If this vertex already recorded in map
|
||||
// else
|
||||
// if(theRepVert->Status(V3, temp) != 0) theSecondVer = TopoDS::Vertex (temp);
|
||||
if (!V2.IsSame(theSecondVer)) {
|
||||
if (V2.Orientation()==TopAbs_FORWARD) Context()->Replace(V2, theSecondVer.Oriented(TopAbs_FORWARD));
|
||||
else Context()->Replace(V2, theSecondVer.Oriented(TopAbs_REVERSED));
|
||||
if (V3.Orientation()==TopAbs_FORWARD) Context()->Replace(V3, theSecondVer.Oriented(TopAbs_FORWARD));
|
||||
else Context()->Replace(V3, theSecondVer.Oriented(TopAbs_REVERSED));
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
#ifdef DEB
|
||||
cout << "The face is not strip face" << endl;
|
||||
#endif
|
||||
return theNewEdge;
|
||||
}
|
||||
}
|
||||
if (theFirstVer.IsNull() || theSecondVer.IsNull()) return theNewEdge;
|
||||
//Cretate new edge
|
||||
theBuilder.MakeEdge(theNewEdge);
|
||||
Standard_Real f, l, fp1, lp1/*, fp2, lp2*/;
|
||||
TopLoc_Location loc;
|
||||
Handle(Geom_Curve) the3dcurve;
|
||||
the3dcurve = BRep_Tool::Curve(E1, f, l);
|
||||
Handle(Geom2d_Curve) the2dcurve1, the2dcurve2, thenew1, thenew2;
|
||||
if (!F1.IsNull())
|
||||
{
|
||||
the2dcurve1 = BRep_Tool::CurveOnSurface(E1, F1, fp1, lp1);
|
||||
if(!the2dcurve1.IsNull() && fp1!=f && lp1!=l) GeomLib::SameRange(Precision::Confusion(), the2dcurve1, fp1, lp1, f, l, thenew1);
|
||||
}
|
||||
|
||||
/* if (!F2.IsNull())
|
||||
{
|
||||
the2dcurve2 = BRep_Tool::CurveOnSurface(E2, F2, fp2, lp2);
|
||||
if(!the2dcurve2.IsNull()) GeomLib::SameRange(Precision::Confusion(), the2dcurve2, fp2, lp2, f, l, thenew2);
|
||||
}*/
|
||||
|
||||
Standard_Real maxdev;
|
||||
if ((BRep_Tool::Tolerance(theFirstVer))<=(BRep_Tool::Tolerance(theSecondVer)))
|
||||
maxdev = (BRep_Tool::Tolerance(theSecondVer));
|
||||
else maxdev = (BRep_Tool::Tolerance(theFirstVer));
|
||||
theBuilder.UpdateVertex(theFirstVer, maxdev);
|
||||
theBuilder.UpdateVertex(theSecondVer, maxdev);
|
||||
//Standard_Boolean IsFree = Standard_True;
|
||||
theBuilder.SameParameter(theNewEdge, Standard_False);
|
||||
the3dcurve = BRep_Tool::Curve(E1, f, l);
|
||||
theBuilder.UpdateEdge(theNewEdge, the3dcurve, maxdev);
|
||||
theBuilder.Range(theNewEdge, f, l);
|
||||
if (!F1.IsNull() && !thenew1.IsNull())
|
||||
{
|
||||
theBuilder.UpdateEdge(theNewEdge, thenew1, F1, maxdev);
|
||||
//IsFree = Standard_False;
|
||||
}
|
||||
/*if (!F2.IsNull() && !thenew2.IsNull())
|
||||
{
|
||||
theBuilder.UpdateEdge(theNewEdge, thenew2, F2, maxdev);
|
||||
IsFree = Standard_False;
|
||||
}*/
|
||||
theBuilder.Add(theNewEdge, theFirstVer.Oriented(TopAbs_FORWARD));
|
||||
theBuilder.Add(theNewEdge, theSecondVer.Oriented(TopAbs_REVERSED));
|
||||
//Call fixsameparameter for computing distance between 3d and pcurves, if edge is not free
|
||||
// if (!IsFree)
|
||||
// {
|
||||
// ShapeFix_Edge sfe;
|
||||
// if (!F1.IsNull() && !thenew1.IsNull()) sfe.FixReversed2d(theNewEdge, F1);
|
||||
// if (!F2.IsNull() && !thenew2.IsNull()) sfe.FixReversed2d(theNewEdge, F2);
|
||||
// sfe.FixSameParameter(theNewEdge, maxdev);
|
||||
// }
|
||||
return theNewEdge;
|
||||
|
||||
|
||||
}
|
||||
|
||||
TopoDS_Shape ShapeFix_FixSmallFace::FixSplitFace(const TopoDS_Shape& /*S*/)
|
||||
{
|
||||
if (myShape.IsNull()) return myShape;
|
||||
TopAbs_ShapeEnum st = myShape.ShapeType();
|
||||
Standard_Boolean done = Standard_False;
|
||||
TopoDS_Compound theSplittedFaces;
|
||||
BRep_Builder theBuilder;
|
||||
if (st == TopAbs_COMPOUND || st == TopAbs_COMPSOLID ||
|
||||
st == TopAbs_SOLID || st == TopAbs_SHELL || st == TopAbs_FACE) {
|
||||
for (TopExp_Explorer itf (myShape,TopAbs_FACE); itf.More(); itf.Next()) {
|
||||
TopoDS_Face F = TopoDS::Face (itf.Current());
|
||||
TopoDS_Compound CompSplittedFaces;
|
||||
theBuilder.MakeCompound(CompSplittedFaces);
|
||||
if(SplitOneFace(F, CompSplittedFaces)) {
|
||||
done = Standard_True;
|
||||
Context()->Replace(F, CompSplittedFaces);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(done) myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
|
||||
myShape = Context()->Apply(myShape);
|
||||
myResult = myShape;
|
||||
return myShape;
|
||||
}
|
||||
|
||||
TopoDS_Shape ShapeFix_FixSmallFace::SplitFaces()
|
||||
{
|
||||
myShape = RemoveSmallFaces();
|
||||
myResult = myShape;
|
||||
return myShape;
|
||||
|
||||
}
|
||||
|
||||
Standard_Boolean ShapeFix_FixSmallFace::SplitOneFace(TopoDS_Face& F,TopoDS_Compound& theSplittedFaces)
|
||||
{
|
||||
TopTools_DataMapOfShapeListOfShape MapEdges;
|
||||
ShapeAnalysis_DataMapOfShapeListOfReal MapParam;
|
||||
TopoDS_Compound theAllVert;
|
||||
BRep_Builder theBuilder;
|
||||
theBuilder.MakeCompound(theAllVert);
|
||||
//smh#8
|
||||
TopoDS_Shape tmpShape = Context()->Apply(F);
|
||||
F = TopoDS::Face(tmpShape);
|
||||
if (myAnalyzer.CheckSplittingVertices(F,MapEdges,MapParam,theAllVert) != 0)
|
||||
{
|
||||
TopoDS_Wire tempwire;
|
||||
//Take information about splitting vertices
|
||||
if (theAllVert.IsNull()) return Standard_False;
|
||||
//Standard_Integer i;
|
||||
TopoDS_Vertex V;
|
||||
TopExp_Explorer itc(theAllVert,TopAbs_VERTEX); V = TopoDS::Vertex (itc.Current());
|
||||
if (V.IsNull()) return Standard_False;
|
||||
gp_Pnt proj;
|
||||
gp_Pnt vp = BRep_Tool::Pnt(V);
|
||||
TopoDS_Vertex theNewVertex;
|
||||
TopoDS_Edge E;
|
||||
TopoDS_Edge theFirstEdge, theSecondEdge;
|
||||
|
||||
{
|
||||
//If one vertex presents do splitting by two faces
|
||||
ShapeAnalysis_Curve SAC;
|
||||
for (TopExp_Explorer ite(F,TopAbs_EDGE); ite.More(); ite.Next()) {
|
||||
E = TopoDS::Edge (ite.Current());
|
||||
TopoDS_Vertex V1,V2;
|
||||
TopExp::Vertices (E,V1,V2);
|
||||
Standard_Real cf,cl;
|
||||
Handle(Geom_Curve) C3D = BRep_Tool::Curve (E,cf,cl);
|
||||
if (C3D.IsNull()) continue;
|
||||
if (V.IsSame(V1) || V.IsSame(V2)) continue;
|
||||
Standard_Real vt = BRep_Tool::Tolerance (V);
|
||||
Standard_Real param;
|
||||
Standard_Real dist = SAC.Project (C3D,vp,vt*10.,proj,param,cf,cl);
|
||||
if (dist==0) continue; //Projection on same curve but on other edge ?
|
||||
if ( dist <= vt )
|
||||
{
|
||||
theBuilder.MakeVertex(theNewVertex);
|
||||
theBuilder.UpdateVertex(theNewVertex, proj, Precision::Confusion());
|
||||
theBuilder.MakeEdge(theFirstEdge);
|
||||
theBuilder.MakeEdge(theSecondEdge);
|
||||
Standard_Real f, l;
|
||||
Handle(Geom_Curve) the3dcurve = BRep_Tool::Curve(E, f, l);
|
||||
theBuilder.UpdateEdge(theFirstEdge, the3dcurve,Precision::Confusion());
|
||||
theBuilder.UpdateEdge(theSecondEdge, the3dcurve,Precision::Confusion());
|
||||
if (V1.Orientation()==TopAbs_FORWARD)
|
||||
{
|
||||
theBuilder.Add(theFirstEdge, V1);
|
||||
theBuilder.Add(theFirstEdge,theNewVertex.Oriented(TopAbs_REVERSED));
|
||||
theBuilder.Add(theSecondEdge,theNewVertex.Oriented(TopAbs_FORWARD));
|
||||
theBuilder.Add(theSecondEdge, V2);
|
||||
}
|
||||
else {
|
||||
theBuilder.Add(theFirstEdge,V2);
|
||||
theBuilder.Add(theFirstEdge,theNewVertex.Oriented(TopAbs_REVERSED));
|
||||
theBuilder.Add(theSecondEdge,theNewVertex.Oriented(TopAbs_FORWARD));
|
||||
theBuilder.Add(theSecondEdge, V1);
|
||||
}
|
||||
theBuilder.Range(theFirstEdge, cf, param);
|
||||
theBuilder.Range(theSecondEdge, param, cl);
|
||||
//Replace old edge by two new edges
|
||||
TopoDS_Wire twoedges;
|
||||
theBuilder.MakeWire(twoedges);
|
||||
if (E.Orientation() == TopAbs_FORWARD)
|
||||
{
|
||||
theBuilder.Add(twoedges, theFirstEdge.Oriented(TopAbs_FORWARD));
|
||||
theBuilder.Add(twoedges, theSecondEdge.Oriented(TopAbs_FORWARD));
|
||||
}
|
||||
else
|
||||
{
|
||||
theBuilder.Add(twoedges, theFirstEdge.Oriented(TopAbs_REVERSED));
|
||||
theBuilder.Add(twoedges, theSecondEdge.Oriented(TopAbs_REVERSED));
|
||||
}
|
||||
Context()->Replace(E, twoedges);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (theNewVertex.IsNull()) return Standard_False;
|
||||
//Create split edge
|
||||
TopoDS_Edge theSplitEdge;
|
||||
gp_Lin lin(vp, gp_Dir(gp_Vec( vp, proj)));
|
||||
Standard_Real firstparam = ElCLib::Parameter(lin, vp);
|
||||
Standard_Real lastparam = ElCLib::Parameter(lin, proj);
|
||||
Handle(Geom_Line) L = new Geom_Line( vp, gp_Vec( vp, proj));
|
||||
Handle(Geom_Curve) the3dc = L;
|
||||
theBuilder.MakeEdge(theSplitEdge, the3dc, Precision::Confusion());
|
||||
theBuilder.Add(theSplitEdge, V.Oriented(TopAbs_FORWARD));
|
||||
theBuilder.Add(theSplitEdge, theNewVertex.Oriented(TopAbs_REVERSED));
|
||||
theBuilder.Range(theSplitEdge, firstparam, lastparam);
|
||||
//Add pcurve in new edge
|
||||
Handle(ShapeFix_Edge) sfe = new ShapeFix_Edge;
|
||||
sfe->FixAddPCurve(theSplitEdge, F, Standard_False);
|
||||
//Reorder the wire
|
||||
TopoDS_Wire wireonface;
|
||||
//Inher loop is not support yet !!!
|
||||
TopExp_Explorer itw(F,TopAbs_WIRE);
|
||||
wireonface = TopoDS::Wire (itw.Current());
|
||||
itw.Next();
|
||||
if (itw.More()) return Standard_False; //if face contains more than one wire
|
||||
Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire;
|
||||
sfw->Init(wireonface, F, Precision::Confusion());
|
||||
sfw->FixReorder();
|
||||
wireonface = sfw->Wire();
|
||||
|
||||
//Create two new wires
|
||||
TopoDS_Wire w1, w2;
|
||||
theBuilder.MakeWire(w1);
|
||||
theBuilder.MakeWire(w2);
|
||||
theBuilder.MakeWire(tempwire);
|
||||
for (TopExp_Explorer itnew(wireonface, TopAbs_EDGE ); itnew.More(); itnew.Next())
|
||||
{
|
||||
TopoDS_Edge ce = TopoDS::Edge (itnew.Current());
|
||||
if (ce.IsSame(E))
|
||||
{
|
||||
theBuilder.Remove(wireonface, ce);
|
||||
theBuilder.Add(wireonface, theFirstEdge.Oriented(TopAbs_FORWARD));
|
||||
theBuilder.Add(wireonface, theSecondEdge.Oriented(TopAbs_FORWARD));
|
||||
}
|
||||
}
|
||||
sfw->Init(wireonface, F, Precision::Confusion());
|
||||
sfw->FixReorder();
|
||||
wireonface = sfw->Wire();
|
||||
|
||||
for (TopExp_Explorer itere(wireonface, TopAbs_EDGE); itere.More(); itere.Next())
|
||||
{
|
||||
TopoDS_Edge ce = TopoDS::Edge (itere.Current());
|
||||
TopoDS_Vertex thecontrol;
|
||||
if (ce.Orientation () == TopAbs_FORWARD) thecontrol = TopExp::LastVertex(ce);
|
||||
else thecontrol = TopExp::FirstVertex(ce);
|
||||
theBuilder.Add(w1, ce);
|
||||
if (thecontrol.IsSame(V))
|
||||
{
|
||||
theBuilder.Add(w1, theSplitEdge.Oriented(TopAbs_FORWARD));
|
||||
TopoDS_Wire wtemp = w1;
|
||||
w1 = w2;
|
||||
w2 = wtemp;
|
||||
}
|
||||
if (thecontrol.IsSame(theNewVertex))
|
||||
{
|
||||
theBuilder.Add(w1, theSplitEdge.Oriented(TopAbs_REVERSED));
|
||||
TopoDS_Wire wtemp = w1;
|
||||
w1 = w2;
|
||||
w2 = wtemp;
|
||||
}
|
||||
}
|
||||
if ( w1.IsNull()|| w2.IsNull() ) return Standard_False;
|
||||
//Create two new faces and replace old one
|
||||
TopoDS_Face F1;
|
||||
TopoDS_Face F2;
|
||||
theBuilder.MakeFace(F1, BRep_Tool::Surface(F), Precision::Confusion());
|
||||
theBuilder.MakeFace(F2, BRep_Tool::Surface(F), Precision::Confusion());
|
||||
theBuilder.Add(F1, w1);
|
||||
theBuilder.Add(F2, w2);
|
||||
TopoDS_Compound tf;
|
||||
theBuilder.MakeCompound(tf);
|
||||
theBuilder.Add(tf,F1);
|
||||
theBuilder.Add(tf, F2);
|
||||
//Call recursive spliteoneface() for each face
|
||||
if(!SplitOneFace(F1, theSplittedFaces)) theBuilder.Add(theSplittedFaces, F1);
|
||||
if(!SplitOneFace(F2, theSplittedFaces)) theBuilder.Add(theSplittedFaces, F2);
|
||||
}
|
||||
return Standard_True ;
|
||||
}
|
||||
return Standard_False ;
|
||||
}
|
||||
|
||||
|
||||
TopoDS_Shape ShapeFix_FixSmallFace::RemoveSmallFaces()
|
||||
{
|
||||
myShape = SplitFaces();
|
||||
myShape = FixSpotFace();
|
||||
myShape = FixStripFace ();
|
||||
return myShape;
|
||||
|
||||
}
|
||||
|
||||
TopoDS_Face ShapeFix_FixSmallFace::FixFace(const TopoDS_Face& F)
|
||||
{
|
||||
//smh#8
|
||||
TopoDS_Shape emptyCopied = F.EmptyCopied();
|
||||
TopoDS_Face theFixedFace = TopoDS::Face(emptyCopied);
|
||||
// BRep_Builder theBuilder;
|
||||
|
||||
// Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire;
|
||||
// sfw->SetContext(Context());
|
||||
// for (TopExp_Explorer exp_w (F,TopAbs_WIRE); exp_w.More(); exp_w.Next()) {
|
||||
// TopoDS_Wire theCurWire = TopoDS::Wire (exp_w.Current());
|
||||
|
||||
// sfw->Init(theCurWire, F, Precision::Confusion());
|
||||
// if(sfw->NbEdges() == 0) continue;
|
||||
// sfw->FixNotchedEdgesMode() = 0;
|
||||
// sfw->Perform();
|
||||
// theCurWire = sfw->Wire();
|
||||
// theBuilder.Add(theFixedFace, theCurWire);
|
||||
// }
|
||||
Handle(ShapeFix_Face) sff = new ShapeFix_Face;
|
||||
sff->SetContext(Context());
|
||||
sff->Init(F);
|
||||
sff->Perform();
|
||||
//sff->Init(theFixedFace);
|
||||
//sff->FixOrientation();
|
||||
theFixedFace = sff->Face();
|
||||
return theFixedFace;
|
||||
}
|
||||
|
||||
TopoDS_Shape ShapeFix_FixSmallFace::FixShape()
|
||||
{
|
||||
TopoDS_Shape FixSh;
|
||||
if(myShape.IsNull()) return FixSh;
|
||||
/*ShapeFix_Shape sfs;
|
||||
sfs.SetContext(Context());
|
||||
|
||||
sfs.SetPrecision(Precision::Confusion());
|
||||
sfs.Init(myShape);
|
||||
sfs.Perform();
|
||||
FixSh = sfs.Shape();*/
|
||||
for(TopExp_Explorer expf(myShape,TopAbs_FACE) ; expf.More(); expf.Next()) {
|
||||
TopoDS_Face F = TopoDS::Face(expf.Current());
|
||||
//smh#8
|
||||
TopoDS_Shape tmpFace = Context()->Apply(F);
|
||||
F= TopoDS::Face(tmpFace);
|
||||
TopoDS_Face newF = FixFace(F);
|
||||
Context()->Replace(F,newF);
|
||||
}
|
||||
FixSh = Context()->Apply(myShape);
|
||||
return FixSh;
|
||||
|
||||
}
|
||||
TopoDS_Shape ShapeFix_FixSmallFace::Shape()
|
||||
{
|
||||
return myShape;
|
||||
}
|
||||
|
||||
Standard_Boolean ShapeFix_FixSmallFace::FixPinFace (TopoDS_Face& /*F*/)
|
||||
{
|
||||
return Standard_True;
|
||||
}
|
97
src/ShapeFix/ShapeFix_FreeBounds.cdl
Executable file
97
src/ShapeFix/ShapeFix_FreeBounds.cdl
Executable file
@@ -0,0 +1,97 @@
|
||||
-- File: ShapeFix_FreeBounds.cdl
|
||||
-- Created: Wed Sep 16 12:44:57 1998
|
||||
-- Author: Roman LYGIN <rln@nnov.matra-dtv.fr>
|
||||
-- Pavel DURANDIN <pdn@nnov.matra-dtv.fr>
|
||||
---Copyright: Matra Datavision 1998
|
||||
|
||||
|
||||
class FreeBounds from ShapeFix
|
||||
|
||||
---Purpose: This class is intended to output free bounds of the shape
|
||||
-- (free bounds are the wires consisting of edges referenced by the
|
||||
-- only face).
|
||||
-- For building free bounds it uses ShapeAnalysis_FreeBounds class.
|
||||
-- This class complements it with the feature to reduce the number
|
||||
-- of open wires.
|
||||
-- This reduction is performed with help of connecting several
|
||||
-- adjacent open wires one to another what can lead to:
|
||||
-- 1. making an open wire with greater length out of several
|
||||
-- open wires
|
||||
-- 2. making closed wire out of several open wires
|
||||
--
|
||||
-- The connecting open wires is performed with a user-given
|
||||
-- tolerance.
|
||||
--
|
||||
-- When connecting several open wires into one wire their previous
|
||||
-- end vertices are replaced with new connecting vertices. After
|
||||
-- that all the edges in the shape sharing previous vertices inside
|
||||
-- the shape are updated with new vertices. Thus source shape can
|
||||
-- be modified.
|
||||
--
|
||||
-- Since interface of this class is the same as one of
|
||||
-- ShapeAnalysis_FreeBounds refer to its CDL for details.
|
||||
|
||||
|
||||
uses
|
||||
Shape from TopoDS,
|
||||
Compound from TopoDS
|
||||
|
||||
is
|
||||
|
||||
Create returns FreeBounds from ShapeFix;
|
||||
---Purpose: Empty constructor
|
||||
|
||||
Create (shape : Shape from TopoDS;
|
||||
sewtoler : Real;
|
||||
closetoler : Real;
|
||||
splitclosed: Boolean;
|
||||
splitopen : Boolean)
|
||||
returns FreeBounds from ShapeFix;
|
||||
---Purpose: Builds forecasting free bounds of the <shape> and connects
|
||||
-- open wires with tolerance <closetoler>.
|
||||
-- <shape> should be a compound of faces.
|
||||
-- Tolerance <closetoler> should be greater than tolerance
|
||||
-- <sewtoler> used for initializing sewing analyzer, otherwise
|
||||
-- connection of open wires is not performed.
|
||||
|
||||
Create (shape : Shape from TopoDS;
|
||||
closetoler : Real;
|
||||
splitclosed: Boolean;
|
||||
splitopen : Boolean)
|
||||
returns FreeBounds from ShapeFix;
|
||||
---Purpose: Builds actual free bounds of the <shape> and connects
|
||||
-- open wires with tolerance <closetoler>.
|
||||
-- <shape> should be a compound of shells.
|
||||
|
||||
GetClosedWires (me) returns Compound from TopoDS;
|
||||
---Purpose: Returns compound of closed wires out of free edges.
|
||||
---C++: inline
|
||||
---C++: return const &
|
||||
|
||||
GetOpenWires (me) returns Compound from TopoDS;
|
||||
---Purpose: Returns compound of open wires out of free edges.
|
||||
---C++: inline
|
||||
---C++: return const &
|
||||
|
||||
GetShape (me) returns Shape from TopoDS;
|
||||
---Purpose: Returns modified source shape.
|
||||
---C++: inline
|
||||
---C++: return const &
|
||||
|
||||
|
||||
---Level: Internal
|
||||
Perform (me: in out) returns Boolean is private;
|
||||
|
||||
fields
|
||||
|
||||
myWires: Compound from TopoDS;
|
||||
myEdges: Compound from TopoDS;
|
||||
myShape: Shape from TopoDS;
|
||||
|
||||
myShared : Boolean;
|
||||
mySewToler : Real;
|
||||
myCloseToler : Real;
|
||||
mySplitClosed: Boolean;
|
||||
mySplitOpen : Boolean;
|
||||
|
||||
end FreeBounds;
|
105
src/ShapeFix/ShapeFix_FreeBounds.cxx
Executable file
105
src/ShapeFix/ShapeFix_FreeBounds.cxx
Executable file
@@ -0,0 +1,105 @@
|
||||
// File: ShapeFix_FreeBounds.cxx
|
||||
// Created: Wed Sep 16 17:27:59 1998
|
||||
// Author: Roman LYGIN <rln@nnov.matra-dtv.fr>
|
||||
// Pavel DURANDIN <pdn@nnov.matra-dtv.fr>
|
||||
// 25.12.98 pdn: renaming methods GetWires and GetEdges to GetClosedWires
|
||||
// and GetOpenWires respectively
|
||||
|
||||
#include <ShapeFix_FreeBounds.ixx>
|
||||
|
||||
#include <BRep_Builder.hxx>
|
||||
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Iterator.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopTools_DataMapOfShapeShape.hxx>
|
||||
|
||||
#include <ShapeExtend_Explorer.hxx>
|
||||
#include <ShapeAnalysis_FreeBounds.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeFix_FreeBounds
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
ShapeFix_FreeBounds::ShapeFix_FreeBounds() {}
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeFix_FreeBounds
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
ShapeFix_FreeBounds::ShapeFix_FreeBounds(const TopoDS_Shape& shape,
|
||||
const Standard_Real sewtoler,
|
||||
const Standard_Real closetoler,
|
||||
const Standard_Boolean splitclosed,
|
||||
const Standard_Boolean splitopen) :
|
||||
myShared (Standard_False), mySewToler (sewtoler), myCloseToler (closetoler),
|
||||
mySplitClosed (splitclosed), mySplitOpen (splitopen)
|
||||
{
|
||||
myShape = shape;
|
||||
Perform();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeFix_FreeBounds
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
ShapeFix_FreeBounds::ShapeFix_FreeBounds(const TopoDS_Shape& shape,
|
||||
const Standard_Real closetoler,
|
||||
const Standard_Boolean splitclosed,
|
||||
const Standard_Boolean splitopen):
|
||||
myShared (Standard_True), mySewToler (0.), myCloseToler (closetoler),
|
||||
mySplitClosed (splitclosed), mySplitOpen (splitopen)
|
||||
{
|
||||
myShape = shape;
|
||||
Perform();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_FreeBounds::Perform()
|
||||
{
|
||||
ShapeAnalysis_FreeBounds safb;
|
||||
if (myShared)
|
||||
safb = ShapeAnalysis_FreeBounds (myShape, mySplitClosed, mySplitOpen);
|
||||
else
|
||||
safb = ShapeAnalysis_FreeBounds (myShape, mySewToler, mySplitClosed, mySplitOpen);
|
||||
|
||||
myWires = safb.GetClosedWires();
|
||||
myEdges = safb.GetOpenWires();
|
||||
|
||||
if (myCloseToler > mySewToler) {
|
||||
ShapeExtend_Explorer see;
|
||||
Handle(TopTools_HSequenceOfShape) newwires,
|
||||
open = see.SeqFromCompound (myEdges,
|
||||
Standard_False);
|
||||
TopTools_DataMapOfShapeShape vertices;
|
||||
ShapeAnalysis_FreeBounds::ConnectWiresToWires (open, myCloseToler, myShared,
|
||||
newwires, vertices);
|
||||
myEdges.Nullify();
|
||||
ShapeAnalysis_FreeBounds::DispatchWires (newwires, myWires, myEdges);
|
||||
|
||||
for( TopExp_Explorer exp (myShape, TopAbs_EDGE); exp.More(); exp.Next()) {
|
||||
TopoDS_Edge Edge = TopoDS::Edge(exp.Current());
|
||||
for( TopoDS_Iterator iter (Edge); iter.More(); iter.Next()) {
|
||||
TopoDS_Vertex V = TopoDS::Vertex (iter.Value());
|
||||
BRep_Builder B;
|
||||
TopoDS_Vertex newV;
|
||||
if( vertices.IsBound(V)) {
|
||||
newV = TopoDS::Vertex (vertices.Find(V));
|
||||
newV.Orientation(V.Orientation());
|
||||
B.Remove(Edge, V);
|
||||
B.Add(Edge, newV);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
38
src/ShapeFix/ShapeFix_FreeBounds.lxx
Executable file
38
src/ShapeFix/ShapeFix_FreeBounds.lxx
Executable file
@@ -0,0 +1,38 @@
|
||||
// File: ShapeFix_FreeBounds.lxx
|
||||
// Created: Wed Sep 16 19:09:52 1998
|
||||
// Author: data exchange team
|
||||
// <det@nnov.matra-dtv.fr>
|
||||
|
||||
//=======================================================================
|
||||
//function : GetClosedWires
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline const TopoDS_Compound& ShapeFix_FreeBounds::GetClosedWires() const
|
||||
{
|
||||
return myWires;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : GetOpenWires
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline const TopoDS_Compound& ShapeFix_FreeBounds::GetOpenWires() const
|
||||
{
|
||||
return myEdges;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : GetShape
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline const TopoDS_Shape& ShapeFix_FreeBounds::GetShape() const
|
||||
{
|
||||
return myShape;
|
||||
}
|
||||
|
||||
|
100
src/ShapeFix/ShapeFix_IntersectionTool.cdl
Executable file
100
src/ShapeFix/ShapeFix_IntersectionTool.cdl
Executable file
@@ -0,0 +1,100 @@
|
||||
-- File: ShapeFix_IntersectionTool.cdl
|
||||
-- Created: Fri Mar 5 18:36:52 2004
|
||||
-- Author: Sergey KUUL
|
||||
-- <skl@petrox.nnov.matra-dtv.fr>
|
||||
---Copyright: Matra Datavision 2004
|
||||
|
||||
class IntersectionTool from ShapeFix
|
||||
|
||||
---Purpose: Tool for fixing selfintersecting wire
|
||||
-- and intersecting wires
|
||||
|
||||
uses
|
||||
|
||||
Face from TopoDS,
|
||||
Edge from TopoDS,
|
||||
Vertex from TopoDS,
|
||||
ReShape from ShapeBuild,
|
||||
WireData from ShapeExtend,
|
||||
DataMapOfShapeBox2d from ShapeFix,
|
||||
Curve from Geom2d,
|
||||
Box2d from Bnd
|
||||
|
||||
is
|
||||
Create(context: ReShape from ShapeBuild;
|
||||
preci: Real; maxtol: Real =1.0) returns IntersectionTool from ShapeFix;
|
||||
---Purpose: Constructor
|
||||
|
||||
Context (me) returns ReShape from ShapeBuild;
|
||||
---Purpose: Returns context
|
||||
---C++: inline
|
||||
|
||||
SplitEdge(me; edge: Edge from TopoDS; param: Real from Standard;
|
||||
vert: Vertex from TopoDS; face: Face from TopoDS;
|
||||
newE1: in out Edge from TopoDS; newE2: in out Edge from TopoDS;
|
||||
preci: Real from Standard)
|
||||
returns Boolean from Standard;
|
||||
---Purpose: Split edge on two new edges using new vertex "vert"
|
||||
-- and "param" - parameter for splitting
|
||||
-- The "face" is necessary for pcurves and using TransferParameterProj
|
||||
|
||||
CutEdge(me; edge: Edge from TopoDS; pend: Real from Standard;
|
||||
cut: Real from Standard; face: Face from TopoDS;
|
||||
iscutline: in out Boolean from Standard)
|
||||
returns Boolean from Standard;
|
||||
---Purpose: Cut edge by parameters pend and cut
|
||||
|
||||
SplitEdge1(me; sewd: WireData from ShapeExtend;
|
||||
face: Face from TopoDS;
|
||||
num: Integer from Standard;
|
||||
param: Real from Standard;
|
||||
vert: Vertex from TopoDS;
|
||||
preci: Real from Standard;
|
||||
boxes: in out DataMapOfShapeBox2d from ShapeFix)
|
||||
returns Boolean from Standard is private;
|
||||
|
||||
SplitEdge2(me; sewd: WireData from ShapeExtend;
|
||||
face: Face from TopoDS;
|
||||
num: Integer from Standard;
|
||||
param1: Real from Standard;
|
||||
param2: Real from Standard;
|
||||
vert: Vertex from TopoDS;
|
||||
preci: Real from Standard;
|
||||
boxes: in out DataMapOfShapeBox2d from ShapeFix)
|
||||
returns Boolean from Standard is private;
|
||||
|
||||
UnionVertexes(me; sewd: WireData from ShapeExtend;
|
||||
edge1: in out Edge from TopoDS;
|
||||
edge2: in out Edge from TopoDS;
|
||||
num2: Integer from Standard;
|
||||
boxes: in out DataMapOfShapeBox2d from ShapeFix;
|
||||
B2: Box2d from Bnd)
|
||||
returns Boolean from Standard is private;
|
||||
|
||||
FindVertAndSplitEdge(me; param1: Real from Standard;
|
||||
edge1,edge2: Edge from TopoDS;
|
||||
Crv1: Curve from Geom2d;
|
||||
MaxTolVert: in out Real from Standard;
|
||||
num1: in out Integer from Standard;
|
||||
sewd: WireData from ShapeExtend;
|
||||
face: Face from TopoDS;
|
||||
boxes: in out DataMapOfShapeBox2d from ShapeFix;
|
||||
aTmpKey: Boolean from Standard)
|
||||
returns Boolean from Standard is private;
|
||||
|
||||
FixSelfIntersectWire(me; sewd: in out WireData from ShapeExtend;
|
||||
face: Face from TopoDS;
|
||||
NbSplit: in out Integer; NbCut: in out Integer;
|
||||
NbRemoved: in out Integer)
|
||||
returns Boolean from Standard;
|
||||
|
||||
FixIntersectingWires(me; face: in out Face from TopoDS)
|
||||
returns Boolean from Standard;
|
||||
|
||||
fields
|
||||
|
||||
myContext : ReShape from ShapeBuild;
|
||||
myPreci : Real from Standard;
|
||||
myMaxTol : Real from Standard;
|
||||
|
||||
end IntersectionTool;
|
1927
src/ShapeFix/ShapeFix_IntersectionTool.cxx
Executable file
1927
src/ShapeFix/ShapeFix_IntersectionTool.cxx
Executable file
File diff suppressed because it is too large
Load Diff
10
src/ShapeFix/ShapeFix_IntersectionTool.lxx
Executable file
10
src/ShapeFix/ShapeFix_IntersectionTool.lxx
Executable file
@@ -0,0 +1,10 @@
|
||||
//=======================================================================
|
||||
//function : Context
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Handle(ShapeBuild_ReShape) ShapeFix_IntersectionTool::Context() const
|
||||
{
|
||||
return myContext;
|
||||
}
|
||||
|
118
src/ShapeFix/ShapeFix_Root.cdl
Executable file
118
src/ShapeFix/ShapeFix_Root.cdl
Executable file
@@ -0,0 +1,118 @@
|
||||
-- File: ShapeFix_Root.cdl
|
||||
-- Created: Mon Aug 9 16:41:59 1999
|
||||
-- Author: Galina KULIKOVA
|
||||
-- <gka@nnov.matra-dtv.fr>
|
||||
---Copyright: Matra Datavision 1999
|
||||
|
||||
|
||||
class Root from ShapeFix inherits TShared from MMgt
|
||||
|
||||
---Purpose: Root class for fixing operations
|
||||
-- Provides context for recording changes (optional),
|
||||
-- basic precision value and limit (minimal and
|
||||
-- maximal) values for tolerances,
|
||||
-- and message registrator
|
||||
|
||||
uses
|
||||
|
||||
Shape from TopoDS,
|
||||
ReShape from ShapeBuild,
|
||||
BasicMsgRegistrator from ShapeExtend,
|
||||
Msg from Message,
|
||||
Gravity from Message
|
||||
|
||||
is
|
||||
Create returns Root from ShapeFix;
|
||||
---Purpose: Empty Constructor (no context is created)
|
||||
|
||||
Set (me: mutable; Root: Root from ShapeFix) is virtual;
|
||||
---Purpose: Copy all fields from another Root object
|
||||
|
||||
SetContext (me:mutable; context : ReShape from ShapeBuild) is virtual;
|
||||
---Purpose: Sets context
|
||||
|
||||
Context (me) returns ReShape from ShapeBuild;
|
||||
---Purpose: Returns context
|
||||
---C++: inline
|
||||
|
||||
SetMsgRegistrator (me:mutable; msgreg: BasicMsgRegistrator from ShapeExtend) is virtual;
|
||||
---Purpose: Sets message registrator
|
||||
|
||||
MsgRegistrator (me) returns BasicMsgRegistrator from ShapeExtend;
|
||||
---Purpose: Returns message registrator
|
||||
---C++: inline
|
||||
|
||||
SetPrecision (me:mutable; preci: Real) is virtual;
|
||||
---Purpose: Sets basic precision value
|
||||
|
||||
Precision (me) returns Real;
|
||||
---Purpose: Returns basic precision value
|
||||
---C++: inline
|
||||
|
||||
SetMinTolerance (me:mutable; mintol: Real) is virtual;
|
||||
---Purpose: Sets minimal allowed tolerance
|
||||
|
||||
MinTolerance (me) returns Real;
|
||||
---Purpose: Returns minimal allowed tolerance
|
||||
---C++: inline
|
||||
|
||||
SetMaxTolerance (me:mutable; maxtol: Real) is virtual;
|
||||
---Purpose: Sets maximal allowed tolerance
|
||||
|
||||
MaxTolerance (me) returns Real;
|
||||
---Purpose: Returns maximal allowed tolerance
|
||||
---C++: inline
|
||||
|
||||
LimitTolerance (me; toler: Real) returns Real;
|
||||
---Purpose: Returns tolerance limited by [myMinTol,myMaxTol]
|
||||
---C++: inline
|
||||
|
||||
-- Methods for sending messages
|
||||
|
||||
SendMsg (me; shape : Shape from TopoDS;
|
||||
message: Msg from Message;
|
||||
gravity: Gravity from Message = Message_Info);
|
||||
---Purpose: Sends a message to be attached to the shape.
|
||||
-- Calls corresponding message of message registrator.
|
||||
|
||||
SendMsg (me; message: Msg from Message;
|
||||
gravity: Gravity from Message = Message_Info);
|
||||
---Purpose: Sends a message to be attached to myShape.
|
||||
-- Calls previous method.
|
||||
---C++ : inline
|
||||
|
||||
SendWarning (me; shape: Shape from TopoDS; message: Msg from Message);
|
||||
---Purpose: Sends a warning to be attached to the shape.
|
||||
-- Calls SendMsg with gravity set to Message_Warning.
|
||||
---C++ : inline
|
||||
|
||||
SendWarning (me; message: Msg from Message);
|
||||
---Purpose: Calls previous method for myShape.
|
||||
---C++ : inline
|
||||
|
||||
SendFail (me; shape: Shape from TopoDS; message: Msg from Message);
|
||||
---Purpose: Sends a fail to be attached to the shape.
|
||||
-- Calls SendMsg with gravity set to Message_Fail.
|
||||
---C++ : inline
|
||||
|
||||
SendFail (me; message: Msg from Message);
|
||||
---Purpose: Calls previous method for myShape.
|
||||
---C++ : inline
|
||||
|
||||
|
||||
NeedFix (myclass; flag: Integer; def: Boolean = Standard_True)
|
||||
returns Boolean is protected;
|
||||
---Purpose: Auxiliary method for work with three-position
|
||||
-- (on/off/default) flags (modes) in ShapeFix.
|
||||
---C++: inline
|
||||
|
||||
fields
|
||||
|
||||
myContext : ReShape from ShapeBuild;
|
||||
myMsgReg : BasicMsgRegistrator from ShapeExtend;
|
||||
myPrecision: Real; -- basic precision
|
||||
myMinTol : Real; -- minimal allowed tolerance
|
||||
myMaxTol : Real; -- maximal allowed tolerance
|
||||
myShape : Shape from TopoDS is protected; -- current processed shape
|
||||
|
||||
end Root;
|
91
src/ShapeFix/ShapeFix_Root.cxx
Executable file
91
src/ShapeFix/ShapeFix_Root.cxx
Executable file
@@ -0,0 +1,91 @@
|
||||
#include <ShapeFix_Root.ixx>
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeFix_Root
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
ShapeFix_Root::ShapeFix_Root()
|
||||
{
|
||||
myPrecision = myMinTol = myMaxTol = Precision::Confusion();
|
||||
myMsgReg = new ShapeExtend_BasicMsgRegistrator;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Set
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_Root::Set (const Handle(ShapeFix_Root)& Root)
|
||||
{
|
||||
myContext = Root->myContext;
|
||||
myMsgReg = Root->myMsgReg;
|
||||
myPrecision = Root->myPrecision;
|
||||
myMinTol = Root->myMinTol;
|
||||
myMaxTol = Root->myMaxTol;
|
||||
myShape = Root->myShape;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetContext
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_Root::SetContext (const Handle(ShapeBuild_ReShape)& context)
|
||||
{
|
||||
myContext = context;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetMsgRegistrator
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_Root::SetMsgRegistrator(const Handle(ShapeExtend_BasicMsgRegistrator)& msgreg)
|
||||
{
|
||||
myMsgReg = msgreg;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetPrecision
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_Root::SetPrecision (const Standard_Real preci)
|
||||
{
|
||||
myPrecision = preci;
|
||||
if(myMaxTol < myPrecision) myMaxTol = myPrecision;
|
||||
if(myMinTol > myPrecision) myMinTol = myPrecision;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetMinTolerance
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_Root::SetMinTolerance (const Standard_Real mintol)
|
||||
{
|
||||
myMinTol = mintol;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetMaxTolerance
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_Root::SetMaxTolerance (const Standard_Real maxtol)
|
||||
{
|
||||
myMaxTol = maxtol;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SendMsg
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_Root::SendMsg(const TopoDS_Shape& shape,
|
||||
const Message_Msg& message,
|
||||
const Message_Gravity gravity) const
|
||||
{
|
||||
myMsgReg->Send (shape, message, gravity);
|
||||
}
|
130
src/ShapeFix/ShapeFix_Root.lxx
Executable file
130
src/ShapeFix/ShapeFix_Root.lxx
Executable file
@@ -0,0 +1,130 @@
|
||||
#include <Precision.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : Context
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Handle(ShapeBuild_ReShape) ShapeFix_Root::Context() const
|
||||
{
|
||||
return myContext;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : MsgRegistrator
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Handle(ShapeExtend_BasicMsgRegistrator) ShapeFix_Root::MsgRegistrator() const
|
||||
{
|
||||
return myMsgReg;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Precision
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Real ShapeFix_Root::Precision() const
|
||||
{
|
||||
return myPrecision;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : MinTolerance
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Real ShapeFix_Root::MinTolerance() const
|
||||
{
|
||||
return myMinTol;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : MaxTolerance
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Real ShapeFix_Root::MaxTolerance() const
|
||||
{
|
||||
return myMaxTol;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : LimitTolerance
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Real ShapeFix_Root::LimitTolerance(const Standard_Real toler) const
|
||||
{
|
||||
//only maximal restriction implemented.
|
||||
return Min(myMaxTol,toler);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SendMsg
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline void ShapeFix_Root::SendMsg(const Message_Msg& message,const Message_Gravity gravity) const
|
||||
{
|
||||
SendMsg (myShape, message, gravity);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : SendWarning
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline void ShapeFix_Root::SendWarning(const TopoDS_Shape& shape,const Message_Msg& message) const
|
||||
{
|
||||
SendMsg (shape, message, Message_Warning);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : SendWarning
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline void ShapeFix_Root::SendWarning(const Message_Msg& message) const
|
||||
{
|
||||
SendWarning (myShape, message);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : SendFail
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline void ShapeFix_Root::SendFail(const TopoDS_Shape& shape,const Message_Msg& message) const
|
||||
{
|
||||
SendMsg (shape, message, Message_Fail);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : SendFail
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline void ShapeFix_Root::SendFail(const Message_Msg& message) const
|
||||
{
|
||||
SendFail (myShape, message);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : NeedFix
|
||||
//purpose : Function used to define if the fixing method needs to be called
|
||||
// according to its specific flag if it is set, or
|
||||
// to some additional criteria (if Flag is default)
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean ShapeFix_Root::NeedFix (const Standard_Integer Flag,
|
||||
const Standard_Boolean need)
|
||||
{
|
||||
return Flag <0 ? need : ( Flag >0 );
|
||||
}
|
135
src/ShapeFix/ShapeFix_Shape.cdl
Executable file
135
src/ShapeFix/ShapeFix_Shape.cdl
Executable file
@@ -0,0 +1,135 @@
|
||||
-- File: ShapeFix_Shape.cdl
|
||||
-- Created: Wed Aug 12 11:42:02 1998
|
||||
-- Author: DATA EXCHANGE TEAM
|
||||
-- <det@nnov.matra-dtv.fr>
|
||||
---Copyright: Matra Datavision 1998
|
||||
|
||||
|
||||
class Shape from ShapeFix inherits Root from ShapeFix
|
||||
|
||||
---Purpose: Fixing shape in general
|
||||
|
||||
uses
|
||||
|
||||
Shape from TopoDS,
|
||||
Solid from ShapeFix,
|
||||
Shell from ShapeFix,
|
||||
Face from ShapeFix,
|
||||
Wire from ShapeFix,
|
||||
Edge from ShapeFix,
|
||||
Status from ShapeExtend,
|
||||
MapOfShape from TopTools,
|
||||
BasicMsgRegistrator from ShapeExtend
|
||||
|
||||
is
|
||||
|
||||
Create returns Shape from ShapeFix;
|
||||
---Purpose: Empty Constructor
|
||||
|
||||
Create (shape: Shape from TopoDS)
|
||||
returns Shape from ShapeFix;
|
||||
---Purpose: Initislises by shape.
|
||||
|
||||
Init (me: mutable; shape: Shape from TopoDS);
|
||||
---Purpose: Initislises by shape.
|
||||
|
||||
Perform (me: mutable) returns Boolean;
|
||||
---Purpose: Iterates on sub- shape and performs fixes
|
||||
|
||||
SameParameter (me: mutable; shape: Shape from TopoDS; force: Boolean) is protected;
|
||||
|
||||
Shape (me) returns Shape from TopoDS;
|
||||
---Purpose: Returns resulting shape
|
||||
|
||||
FixSolidTool (me) returns Solid from ShapeFix;
|
||||
---Purpose: Returns tool for fixing solids.
|
||||
---C++:inline
|
||||
|
||||
FixShellTool (me) returns Shell from ShapeFix;
|
||||
---Purpose: Returns tool for fixing shells.
|
||||
---C++:inline
|
||||
|
||||
FixFaceTool (me) returns Face from ShapeFix;
|
||||
---Purpose: Returns tool for fixing faces.
|
||||
---C++:inline
|
||||
|
||||
FixWireTool (me) returns Wire from ShapeFix;
|
||||
---Purpose: Returns tool for fixing wires.
|
||||
---C++:inline
|
||||
|
||||
FixEdgeTool (me) returns Edge from ShapeFix;
|
||||
---Purpose: Returns tool for fixing edges.
|
||||
---C++:inline
|
||||
|
||||
Status (me; status : Status from ShapeExtend) returns Boolean;
|
||||
---Purpose: Returns the status of the last Fix.
|
||||
-- This can be a combination of the following flags:
|
||||
-- ShapeExtend_DONE1: some free edges were fixed
|
||||
-- ShapeExtend_DONE2: some free wires were fixed
|
||||
-- ShapeExtend_DONE3: some free faces were fixed
|
||||
-- ShapeExtend_DONE4: some free shells were fixed
|
||||
-- ShapeExtend_DONE5: some free solids were fixed
|
||||
-- ShapeExtend_DONE6: shapes in compound(s) were fixed
|
||||
|
||||
SetMsgRegistrator (me: mutable; msgreg: BasicMsgRegistrator from ShapeExtend) is redefined;
|
||||
---Purpose: Sets message registrator
|
||||
|
||||
SetPrecision (me: mutable; preci: Real) is redefined;
|
||||
---Purpose: Sets basic precision value (also to FixSolidTool)
|
||||
|
||||
SetMinTolerance (me: mutable; mintol: Real) is redefined;
|
||||
---Purpose: Sets minimal allowed tolerance (also to FixSolidTool)
|
||||
|
||||
SetMaxTolerance (me: mutable; maxtol: Real) is redefined;
|
||||
---Purpose: Sets maximal allowed tolerance (also to FixSolidTool)
|
||||
|
||||
FixSolidMode (me: mutable) returns Integer;
|
||||
---C++: return &
|
||||
---C++: inline
|
||||
---Purpose: Returns (modifiable) the mode for applying fixes of
|
||||
-- ShapeFix_Solid, by default True.
|
||||
|
||||
FixFreeShellMode (me: mutable) returns Integer;
|
||||
---C++: return &
|
||||
---C++: inline
|
||||
---Purpose: Returns (modifiable) the mode for applying fixes of
|
||||
-- ShapeFix_Shell, by default True.
|
||||
|
||||
FixFreeFaceMode (me: mutable) returns Integer;
|
||||
---C++: return &
|
||||
---C++: inline
|
||||
---Purpose: Returns (modifiable) the mode for applying fixes of
|
||||
-- ShapeFix_Face, by default True.
|
||||
|
||||
FixFreeWireMode (me: mutable) returns Integer;
|
||||
---C++: return &
|
||||
---C++: inline
|
||||
---Purpose: Returns (modifiable) the mode for applying fixes of
|
||||
-- ShapeFix_Wire, by default True.
|
||||
|
||||
FixSameParameterMode (me: mutable) returns Integer;
|
||||
---C++: return &
|
||||
---C++: inline
|
||||
---Purpose: Returns (modifiable) the mode for applying
|
||||
-- ShapeFix::SameParameter after all fixes, by default True.
|
||||
|
||||
FixVertexPositionMode (me: mutable) returns Integer;
|
||||
---C++: return &
|
||||
---C++: inline
|
||||
---Purpose: Returns (modifiable) the mode for applying
|
||||
-- ShapeFix::FixVertexPosition before all fixes, by default False.
|
||||
fields
|
||||
|
||||
myResult : Shape from TopoDS is protected;
|
||||
myFixSolid : Solid from ShapeFix is protected;
|
||||
myMapFixingShape : MapOfShape from TopTools is protected;
|
||||
|
||||
myFixSolidMode : Integer is protected;
|
||||
myFixShellMode : Integer is protected;
|
||||
myFixFaceMode : Integer is protected;
|
||||
myFixWireMode : Integer is protected;
|
||||
myFixSameParameterMode : Integer is protected;
|
||||
myFixVertexPositionMode : Integer is protected;
|
||||
myStatus : Integer is protected;
|
||||
|
||||
end Shape;
|
286
src/ShapeFix/ShapeFix_Shape.cxx
Executable file
286
src/ShapeFix/ShapeFix_Shape.cxx
Executable file
@@ -0,0 +1,286 @@
|
||||
// File: ShapeFix_Shape.cxx
|
||||
// Created: Wed Aug 09 12:27:47 1999
|
||||
// Author: Galina Kulikova
|
||||
// <gka@nnov.matra-dtv.fr>
|
||||
|
||||
#include <ShapeFix_Shape.ixx>
|
||||
|
||||
#include <Precision.hxx>
|
||||
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Wire.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Iterator.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopAbs.hxx>
|
||||
#include <TopAbs_ShapeEnum.hxx>
|
||||
#include <BRepTools.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
|
||||
#include <ShapeFix.hxx>
|
||||
#include <ShapeBuild_ReShape.hxx>
|
||||
#include <ShapeFix_Edge.hxx>
|
||||
#include <ShapeFix_Wire.hxx>
|
||||
#include <ShapeFix_Face.hxx>
|
||||
#include <ShapeFix_Shell.hxx>
|
||||
#include <ShapeFix_Solid.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeFix_Shape
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
ShapeFix_Shape::ShapeFix_Shape()
|
||||
{
|
||||
myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
|
||||
myFixSolidMode = -1;
|
||||
myFixShellMode = -1;
|
||||
myFixFaceMode = -1;
|
||||
myFixWireMode = -1;
|
||||
myFixSameParameterMode = -1;
|
||||
myFixVertexPositionMode =0;
|
||||
myFixSolid = new ShapeFix_Solid;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeFix_Shape
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
ShapeFix_Shape::ShapeFix_Shape(const TopoDS_Shape& shape)
|
||||
{
|
||||
myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
|
||||
myFixSolidMode = -1;
|
||||
myFixShellMode = -1;
|
||||
myFixFaceMode = -1;
|
||||
myFixWireMode = -1;
|
||||
myFixSameParameterMode = -1;
|
||||
myFixSolid = new ShapeFix_Solid;
|
||||
myFixVertexPositionMode =0;
|
||||
Init(shape);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Init
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_Shape::Init(const TopoDS_Shape& shape)
|
||||
{
|
||||
myShape = shape;
|
||||
if ( Context().IsNull() ) {
|
||||
SetContext ( new ShapeBuild_ReShape );
|
||||
Context()->ModeConsiderLocation() = Standard_True;
|
||||
}
|
||||
myResult = myShape;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_Shape::Perform()
|
||||
{
|
||||
Standard_Integer savFixSmallAreaWireMode = 0;
|
||||
|
||||
Handle(ShapeFix_Face) fft = Handle(ShapeFix_Face)::DownCast ( FixFaceTool() );
|
||||
if ( !fft.IsNull() ) {
|
||||
savFixSmallAreaWireMode = fft->FixSmallAreaWireMode();
|
||||
if ( savFixSmallAreaWireMode == -1 &&
|
||||
myShape.ShapeType() == TopAbs_FACE ) {
|
||||
fft->FixSmallAreaWireMode() = Standard_True;
|
||||
}
|
||||
}
|
||||
|
||||
myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
|
||||
Standard_Boolean status = Standard_False;
|
||||
TopAbs_ShapeEnum st;
|
||||
|
||||
//gka fix for sharing assembly
|
||||
TopLoc_Location nullLoc,L;
|
||||
L = myShape.Location();
|
||||
TopoDS_Shape aShapeNullLoc = myShape;
|
||||
aShapeNullLoc.Location(nullLoc);
|
||||
if(myMapFixingShape.Contains(aShapeNullLoc)) {
|
||||
myShape.Location(L);
|
||||
myResult = Context()->Apply(myShape);
|
||||
status = Standard_True;
|
||||
return status;
|
||||
}
|
||||
else myMapFixingShape.Add(aShapeNullLoc);
|
||||
//---------------------------------------
|
||||
myShape.Location(L);
|
||||
TopoDS_Shape S = Context()->Apply(myShape);
|
||||
if ( NeedFix ( myFixVertexPositionMode ) )
|
||||
ShapeFix::FixVertexPosition(S,Precision(),Context());
|
||||
|
||||
st = S.ShapeType();
|
||||
switch ( st ) {
|
||||
case TopAbs_COMPOUND:
|
||||
case TopAbs_COMPSOLID: {
|
||||
TopoDS_Shape shape = myShape;
|
||||
Standard_Boolean savFixSameParameterMode = myFixSameParameterMode;
|
||||
myFixSameParameterMode = Standard_False;
|
||||
for( TopoDS_Iterator iter(S); iter.More(); iter.Next()) {
|
||||
myShape = iter.Value();
|
||||
if ( Perform() ) status = Standard_True;
|
||||
}
|
||||
myFixSameParameterMode = savFixSameParameterMode;
|
||||
myShape = shape;
|
||||
// myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE5 );
|
||||
break;
|
||||
}
|
||||
case TopAbs_SOLID: {
|
||||
if ( ! NeedFix ( myFixSolidMode ) ) break;
|
||||
myFixSolid->Init(TopoDS::Solid(S));
|
||||
myFixSolid->SetContext(Context());
|
||||
if(myFixSolid->Perform()) {
|
||||
// Context()->Replace(S,myFixSolid->Solid());
|
||||
status = Standard_True;
|
||||
}
|
||||
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
|
||||
break;
|
||||
}
|
||||
case TopAbs_SHELL: {
|
||||
if ( ! NeedFix ( myFixShellMode ) ) break;
|
||||
Handle(ShapeFix_Shell) sfsh = FixShellTool();
|
||||
sfsh->Init(TopoDS::Shell(S));
|
||||
sfsh->SetContext(Context());
|
||||
if(sfsh->Perform()) {
|
||||
// Context()->Replace(S,sfsh->Shell());
|
||||
status = Standard_True;
|
||||
}
|
||||
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
|
||||
break;
|
||||
}
|
||||
case TopAbs_FACE: {
|
||||
if ( ! NeedFix ( myFixFaceMode ) ) break;
|
||||
Handle(ShapeFix_Face) sff = FixFaceTool();
|
||||
Standard_Integer savTopoMode = sff->FixWireTool()->ModifyTopologyMode();
|
||||
sff->FixWireTool()->ModifyTopologyMode() = Standard_True;
|
||||
sff->Init(TopoDS::Face(S));
|
||||
sff->SetContext(Context());
|
||||
if(sff->Perform()) {
|
||||
// Context()->Replace(S,sff->Face());
|
||||
status = Standard_True;
|
||||
}
|
||||
sff->FixWireTool()->ModifyTopologyMode() = savTopoMode;
|
||||
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
|
||||
break;
|
||||
}
|
||||
case TopAbs_WIRE: {
|
||||
if ( ! NeedFix ( myFixWireMode ) ) break;
|
||||
Handle(ShapeFix_Wire) sfw = FixWireTool();
|
||||
Standard_Integer savTopoMode = sfw->ModifyTopologyMode();
|
||||
Standard_Integer savClosedMode = sfw->ClosedWireMode();
|
||||
sfw->ModifyTopologyMode() = Standard_True;
|
||||
if ( ! S.Closed() )
|
||||
sfw->ClosedWireMode() = Standard_False;
|
||||
// sfw->FixEdgeCurvesMode() =0;
|
||||
sfw->SetFace(TopoDS_Face());
|
||||
sfw->Load(TopoDS::Wire(S));
|
||||
sfw->SetContext(Context());
|
||||
if(sfw->Perform()) {
|
||||
status = Standard_True;
|
||||
Context()->Replace(S,sfw->Wire()); // replace for wire only
|
||||
}
|
||||
sfw->ModifyTopologyMode() = savTopoMode;
|
||||
sfw->ClosedWireMode() = savClosedMode;
|
||||
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
|
||||
break;
|
||||
}
|
||||
case TopAbs_EDGE: {
|
||||
Handle(ShapeFix_Edge) sfe = FixEdgeTool();
|
||||
if(sfe->FixVertexTolerance(TopoDS::Edge(S)))
|
||||
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
|
||||
break;
|
||||
}
|
||||
case TopAbs_VERTEX:
|
||||
case TopAbs_SHAPE :
|
||||
default : break;
|
||||
}
|
||||
|
||||
myResult = Context()->Apply(S);
|
||||
if ( NeedFix ( myFixSameParameterMode ) )
|
||||
SameParameter (myResult,Standard_False);
|
||||
|
||||
if ( !fft.IsNull() )
|
||||
fft->FixSmallAreaWireMode() = savFixSmallAreaWireMode;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SameParameter
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_Shape::SameParameter(const TopoDS_Shape& sh, const Standard_Boolean enforce)
|
||||
{
|
||||
ShapeFix::SameParameter(sh, enforce);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Shape
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
TopoDS_Shape ShapeFix_Shape::Shape() const
|
||||
{
|
||||
return myResult;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetMsgRegistrator
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_Shape::SetMsgRegistrator(const Handle(ShapeExtend_BasicMsgRegistrator)& msgreg)
|
||||
{
|
||||
ShapeFix_Root::SetMsgRegistrator ( msgreg );
|
||||
myFixSolid->SetMsgRegistrator ( msgreg );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetPrecision
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_Shape::SetPrecision (const Standard_Real preci)
|
||||
{
|
||||
ShapeFix_Root::SetPrecision ( preci );
|
||||
myFixSolid->SetPrecision ( preci );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetMinTolerance
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_Shape::SetMinTolerance (const Standard_Real mintol)
|
||||
{
|
||||
ShapeFix_Root::SetMinTolerance ( mintol );
|
||||
myFixSolid->SetMinTolerance ( mintol );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetMaxTolerance
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_Shape::SetMaxTolerance (const Standard_Real maxtol)
|
||||
{
|
||||
ShapeFix_Root::SetMaxTolerance ( maxtol );
|
||||
myFixSolid->SetMaxTolerance ( maxtol );
|
||||
}
|
||||
//=======================================================================
|
||||
//function : Status
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_Shape::Status (const ShapeExtend_Status status) const
|
||||
{
|
||||
return ShapeExtend::DecodeStatus ( myStatus, status );
|
||||
}
|
113
src/ShapeFix/ShapeFix_Shape.lxx
Executable file
113
src/ShapeFix/ShapeFix_Shape.lxx
Executable file
@@ -0,0 +1,113 @@
|
||||
// File: ShapeFix_Shape.lxx
|
||||
// Created: Fri Jun 25 13:16:36 1999
|
||||
// Author: data exchange team
|
||||
// <det@nnov>
|
||||
|
||||
#include <ShapeFix_Solid.hxx>
|
||||
#include <ShapeFix_Shell.hxx>
|
||||
#include <ShapeFix_Face.hxx>
|
||||
#include <ShapeFix_Wire.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : FixSolidTool
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Handle(ShapeFix_Solid) ShapeFix_Shape::FixSolidTool() const
|
||||
{
|
||||
return myFixSolid;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixShellTool
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Handle(ShapeFix_Shell) ShapeFix_Shape::FixShellTool() const
|
||||
{
|
||||
return myFixSolid->FixShellTool();
|
||||
}
|
||||
//=======================================================================
|
||||
//function : FixFaceTool
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Handle(ShapeFix_Face) ShapeFix_Shape::FixFaceTool() const
|
||||
{
|
||||
return myFixSolid->FixShellTool()->FixFaceTool();
|
||||
}
|
||||
//=======================================================================
|
||||
//function : FixWireTool
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Handle(ShapeFix_Wire) ShapeFix_Shape::FixWireTool() const
|
||||
{
|
||||
return myFixSolid->FixShellTool()->FixFaceTool()->FixWireTool();
|
||||
}
|
||||
//=======================================================================
|
||||
//function : FixEdgeTool
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Handle(ShapeFix_Edge) ShapeFix_Shape::FixEdgeTool() const
|
||||
{
|
||||
return myFixSolid->FixShellTool()->FixFaceTool()->FixWireTool()->FixEdgeTool();
|
||||
}
|
||||
//=======================================================================
|
||||
//function : FixSolidMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Shape::FixSolidMode()
|
||||
{
|
||||
return myFixSolidMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixFreeShellMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Shape::FixFreeShellMode()
|
||||
{
|
||||
return myFixShellMode;
|
||||
}
|
||||
//=======================================================================
|
||||
//function : FixFreeFaceMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Shape::FixFreeFaceMode()
|
||||
{
|
||||
return myFixFaceMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixFreeWireMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Shape::FixFreeWireMode()
|
||||
{
|
||||
return myFixWireMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixSameParameterMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Shape::FixSameParameterMode()
|
||||
{
|
||||
return myFixSameParameterMode;
|
||||
}
|
||||
//=======================================================================
|
||||
//function : FixVertexPositionMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Shape::FixVertexPositionMode()
|
||||
{
|
||||
return myFixVertexPositionMode;
|
||||
}
|
50
src/ShapeFix/ShapeFix_ShapeTolerance.cdl
Executable file
50
src/ShapeFix/ShapeFix_ShapeTolerance.cdl
Executable file
@@ -0,0 +1,50 @@
|
||||
-- File: ShapeFix_ShapeTolerance.cdl
|
||||
-- Created: Wed Jul 22 17:46:14 1998
|
||||
-- Author: data exchange team
|
||||
-- <det@nnov.matra-dtv.fr>
|
||||
---Copyright: Matra Datavision 1998
|
||||
|
||||
|
||||
class ShapeTolerance from ShapeFix
|
||||
|
||||
---Purpose: Modifies tolerances of sub-shapes (vertices, edges, faces)
|
||||
|
||||
uses
|
||||
|
||||
Shape from TopoDS,
|
||||
ShapeEnum from TopAbs
|
||||
|
||||
is
|
||||
|
||||
Create returns ShapeTolerance from ShapeFix;
|
||||
|
||||
LimitTolerance (me; shape: Shape from TopoDS;
|
||||
tmin : Real;
|
||||
tmax : Real = 0.0;
|
||||
styp : ShapeEnum from TopAbs = TopAbs_SHAPE)
|
||||
returns Boolean;
|
||||
---Purpose: Limits tolerances in a shape as follows :
|
||||
-- tmin = tmax -> as SetTolerance (forces)
|
||||
-- tmin = 0 -> maximum tolerance will be <tmax>
|
||||
-- tmax = 0 or not given (more generally, tmax < tmin) ->
|
||||
-- <tmax> ignored, minimum will be <tmin>
|
||||
-- else, maximum will be <max> and minimum will be <min>
|
||||
-- styp = VERTEX : only vertices are set
|
||||
-- styp = EDGE : only edges are set
|
||||
-- styp = FACE : only faces are set
|
||||
-- styp = WIRE : to have edges and their vertices set
|
||||
-- styp = other value : all (vertices,edges,faces) are set
|
||||
-- Returns True if at least one tolerance of the sub-shape has
|
||||
-- been modified
|
||||
|
||||
SetTolerance (me; shape: Shape from TopoDS;
|
||||
preci: Real;
|
||||
styp : ShapeEnum from TopAbs = TopAbs_SHAPE);
|
||||
---Purpose: Sets (enforces) tolerances in a shape to the given value
|
||||
-- styp = VERTEX : only vertices are set
|
||||
-- styp = EDGE : only edges are set
|
||||
-- styp = FACE : only faces are set
|
||||
-- styp = WIRE : to have edges and their vertices set
|
||||
-- styp = other value : all (vertices,edges,faces) are set
|
||||
|
||||
end ShapeTolerance;
|
155
src/ShapeFix/ShapeFix_ShapeTolerance.cxx
Executable file
155
src/ShapeFix/ShapeFix_ShapeTolerance.cxx
Executable file
@@ -0,0 +1,155 @@
|
||||
// 25.12.98 pdn: adding empty constructor
|
||||
|
||||
#include <ShapeFix_ShapeTolerance.ixx>
|
||||
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRep_TVertex.hxx>
|
||||
#include <BRep_TEdge.hxx>
|
||||
#include <BRep_TFace.hxx>
|
||||
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : Constructor
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
ShapeFix_ShapeTolerance::ShapeFix_ShapeTolerance()
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : LimitTolerance
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_ShapeTolerance::LimitTolerance(const TopoDS_Shape& shape,
|
||||
const Standard_Real tmin,
|
||||
const Standard_Real tmax,
|
||||
const TopAbs_ShapeEnum styp) const
|
||||
{
|
||||
if (shape.IsNull() || tmin < 0) return Standard_False;
|
||||
Standard_Boolean iamax = (tmax >= tmin);
|
||||
Standard_Real prec;
|
||||
Standard_Boolean fait = Standard_False;
|
||||
if (styp == TopAbs_VERTEX || styp == TopAbs_EDGE || styp == TopAbs_FACE) {
|
||||
for (TopExp_Explorer ex(shape,styp); ex.More(); ex.Next()) {
|
||||
TopoDS_Shape sh = ex.Current();
|
||||
int newtol = 0;
|
||||
if (styp == TopAbs_VERTEX) {
|
||||
TopoDS_Vertex V = TopoDS::Vertex (sh);
|
||||
prec = BRep_Tool::Tolerance (V);
|
||||
if (iamax && prec > tmax) newtol = 1;
|
||||
else if (prec < tmin) newtol = -1;
|
||||
if (newtol) {
|
||||
const Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*)&V.TShape());
|
||||
TV->Tolerance( (newtol > 0 ? tmax : tmin) );
|
||||
fait = Standard_True;
|
||||
}
|
||||
} else if (styp == TopAbs_EDGE) {
|
||||
TopoDS_Edge E = TopoDS::Edge (sh);
|
||||
prec = BRep_Tool::Tolerance (E);
|
||||
if (iamax && prec > tmax) newtol = 1;
|
||||
else if (prec < tmin) newtol = -1;
|
||||
if (newtol) {
|
||||
const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
|
||||
TE->Tolerance( (newtol > 0 ? tmax : tmin) );
|
||||
fait = Standard_True;
|
||||
}
|
||||
} else if (styp == TopAbs_FACE) {
|
||||
TopoDS_Face F = TopoDS::Face (sh);
|
||||
prec = BRep_Tool::Tolerance (F);
|
||||
if (iamax && prec > tmax) newtol = 1;
|
||||
else if (prec < tmin) newtol = -1;
|
||||
if (newtol) {
|
||||
const Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*)&F.TShape());
|
||||
TF->Tolerance( (newtol > 0 ? tmax : tmin) );
|
||||
fait = Standard_True;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (styp == TopAbs_WIRE) {
|
||||
for (TopExp_Explorer ex(shape,TopAbs_EDGE); ex.More(); ex.Next()) {
|
||||
TopoDS_Shape sh = ex.Current();
|
||||
TopoDS_Edge E = TopoDS::Edge (sh);
|
||||
LimitTolerance (E,tmin,tmax,TopAbs_EDGE);
|
||||
TopoDS_Vertex V1,V2;
|
||||
TopExp::Vertices (E,V1,V2);
|
||||
if (!V1.IsNull()) fait |= LimitTolerance (V1,tmin,tmax,TopAbs_VERTEX);
|
||||
if (!V2.IsNull()) fait |= LimitTolerance (V2,tmin,tmax,TopAbs_VERTEX);
|
||||
}
|
||||
} else {
|
||||
fait |= LimitTolerance (shape,tmin,tmax,TopAbs_VERTEX);
|
||||
fait |= LimitTolerance (shape,tmin,tmax,TopAbs_EDGE);
|
||||
fait |= LimitTolerance (shape,tmin,tmax,TopAbs_FACE);
|
||||
}
|
||||
return fait;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetTolerance
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_ShapeTolerance::SetTolerance(const TopoDS_Shape& shape,
|
||||
const Standard_Real preci,
|
||||
const TopAbs_ShapeEnum styp) const
|
||||
{
|
||||
// VERTEX ou EDGE ou FACE : ces types seulement
|
||||
// WIRE : EDGE + VERTEX
|
||||
// Autres : TOUT (donc == WIRE + FACE)
|
||||
if (shape.IsNull() || preci <= 0) return;
|
||||
if (styp == TopAbs_VERTEX || styp == TopAbs_EDGE || styp == TopAbs_FACE) {
|
||||
for (TopExp_Explorer ex(shape,styp); ex.More(); ex.Next()) {
|
||||
TopoDS_Shape sh = ex.Current();
|
||||
if (styp == TopAbs_VERTEX) {
|
||||
TopoDS_Vertex V = TopoDS::Vertex (sh);
|
||||
// B.UpdateVertex (V,preci);
|
||||
const Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*)&V.TShape());
|
||||
TV->Tolerance(preci);
|
||||
} else if (styp == TopAbs_EDGE) {
|
||||
TopoDS_Edge E = TopoDS::Edge (sh);
|
||||
// B.UpdateEdge (E,preci);
|
||||
const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
|
||||
TE->Tolerance(preci);
|
||||
} else if (styp == TopAbs_FACE) {
|
||||
TopoDS_Face F = TopoDS::Face (sh);
|
||||
// B.UpdateFace (F,preci);
|
||||
const Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*)&F.TShape());
|
||||
TF->Tolerance(preci);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (styp == TopAbs_WIRE) {
|
||||
for (TopExp_Explorer ex(shape,TopAbs_EDGE); ex.More(); ex.Next()) {
|
||||
TopoDS_Shape sh = ex.Current();
|
||||
TopoDS_Edge E = TopoDS::Edge (sh);
|
||||
// B.UpdateEdge (E,preci);
|
||||
const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
|
||||
TE->Tolerance(preci);
|
||||
TopoDS_Vertex V1,V2;
|
||||
TopExp::Vertices (E,V1,V2);
|
||||
if (!V1.IsNull()) {
|
||||
// B.UpdateVertex (V1,preci);
|
||||
const Handle(BRep_TVertex)& TV= *((Handle(BRep_TVertex)*)&V1.TShape());
|
||||
TV->Tolerance(preci);
|
||||
}
|
||||
if (!V2.IsNull()) {
|
||||
// B.UpdateVertex (V2,preci);
|
||||
const Handle(BRep_TVertex)& TV= *((Handle(BRep_TVertex)*)&V2.TShape());
|
||||
TV->Tolerance(preci);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
SetTolerance (shape,preci,TopAbs_VERTEX);
|
||||
SetTolerance (shape,preci,TopAbs_EDGE);
|
||||
SetTolerance (shape,preci,TopAbs_FACE);
|
||||
}
|
||||
}
|
112
src/ShapeFix/ShapeFix_Shell.cdl
Executable file
112
src/ShapeFix/ShapeFix_Shell.cdl
Executable file
@@ -0,0 +1,112 @@
|
||||
-- File: ShapeFix_Shell.cdl
|
||||
-- Created: Wed Aug 12 10:26:46 1998
|
||||
-- Author: Galina KULIKOVA
|
||||
-- <gka@nnov.matra-dtv.fr>
|
||||
---Copyright: Matra Datavision 1998
|
||||
|
||||
|
||||
class Shell from ShapeFix inherits Root from ShapeFix
|
||||
|
||||
---Purpose: Fixing orientation of faces in shell
|
||||
|
||||
uses
|
||||
|
||||
Compound from TopoDS,
|
||||
Shell from TopoDS,
|
||||
Shape from TopoDS,
|
||||
Status from ShapeExtend,
|
||||
BasicMsgRegistrator from ShapeExtend,
|
||||
Face from ShapeFix
|
||||
is
|
||||
|
||||
Create returns Shell from ShapeFix;
|
||||
---Purpose: Empty constructor
|
||||
|
||||
Create (shape: Shell from TopoDS)
|
||||
returns Shell from ShapeFix;
|
||||
---Purpose: Initializes by shell.
|
||||
|
||||
Init (me: mutable; shell: Shell from TopoDS);
|
||||
---Purpose: Initializes by shell.
|
||||
|
||||
Perform (me: mutable) returns Boolean;
|
||||
---Purpose: Iterates on subshapes and performs fixes
|
||||
-- (for each face calls ShapeFix_Face::Perform and
|
||||
-- then calls FixFaceOrientation)
|
||||
|
||||
FixFaceOrientation (me : mutable; shell : Shell from TopoDS;
|
||||
isAccountMultiConex : Boolean = Standard_True;
|
||||
NonManifold : Boolean = Standard_False ) returns Boolean;
|
||||
---Purpose: Fixes orientation of faces in shell.
|
||||
-- Changes orientation of face in the shell, if it is oriented opposite
|
||||
-- to neigbouring faces. If it is not possible to orient all faces in the
|
||||
-- shell (like in case of mebious band), this method orients only subset
|
||||
-- of faces. Other faces are stored in Error compound.
|
||||
-- Modes :
|
||||
-- isAccountMultiConex - mode for account cases of multiconnexity.
|
||||
-- If this mode is equal to Standard_True, separate shells will be created
|
||||
-- in the cases of multiconnexity. If this mode is equal to Standard_False,
|
||||
-- one shell will be created without account of multiconnexity.By defautt - Standard_True;
|
||||
-- NonManifold - mode for creation of non-manifold shells.
|
||||
-- If this mode is equal to Standard_True one non-manifold will be created from shell
|
||||
-- contains multishared edges. Else if this mode is equal to Standard_False only
|
||||
-- manifold shells will be created. By default - Standard_False.
|
||||
--
|
||||
---Returns: If resulting shell is ok returns TRUE, else returns FALSE.
|
||||
---Status : OK - faces in shall were oriented correcty.
|
||||
-- DONE - faces in shell oriented succesfully
|
||||
-- FAIL - faces orientation process has been failed
|
||||
|
||||
Shell(me : mutable) returns Shell from TopoDS;
|
||||
---Purpose: Returns fixed shell (or subset of oriented faces).
|
||||
|
||||
Shape(me : mutable) returns Shape from TopoDS;
|
||||
---Purpose: In case of multiconnexity returns compound of fixed shells
|
||||
-- else returns one shell..
|
||||
NbShells(me) returns Integer;
|
||||
---Purpose: Returns Number of obtainrd shells;
|
||||
|
||||
ErrorFaces(me) returns Compound from TopoDS;
|
||||
---Purpose: Returns not oriented subset of faces.
|
||||
|
||||
Status (me; status : Status from ShapeExtend) returns Boolean;
|
||||
---Purpose: Returns the status of the last Fix.
|
||||
|
||||
FixFaceTool (me:mutable) returns Face from ShapeFix;
|
||||
---Purpose: Returns tool for fixing faces.
|
||||
---C++:inline
|
||||
|
||||
SetMsgRegistrator (me: mutable; msgreg: BasicMsgRegistrator from ShapeExtend) is redefined;
|
||||
---Purpose: Sets message registrator
|
||||
|
||||
SetPrecision (me: mutable; preci: Real) is redefined;
|
||||
---Purpose: Sets basic precision value (also to FixWireTool)
|
||||
|
||||
SetMinTolerance (me: mutable; mintol: Real) is redefined;
|
||||
---Purpose: Sets minimal allowed tolerance (also to FixWireTool)
|
||||
|
||||
SetMaxTolerance (me: mutable; maxtol: Real) is redefined;
|
||||
---Purpose: Sets maximal allowed tolerance (also to FixWireTool)
|
||||
|
||||
FixFaceMode (me: mutable) returns Integer;
|
||||
---C++: return &
|
||||
---C++: inline
|
||||
---Purpose: Returns (modifiable) the mode for applying fixes of
|
||||
-- ShapeFix_Face, by default True.
|
||||
|
||||
FixOrientationMode (me: mutable) returns Integer;
|
||||
---C++: return &
|
||||
---C++: inline
|
||||
---Purpose: Returns (modifiable) the mode for applying
|
||||
-- FixFaceOrientation, by default True.
|
||||
|
||||
fields
|
||||
|
||||
myShell : Shell from TopoDS is protected;
|
||||
myErrFaces : Compound from TopoDS is protected;
|
||||
myStatus : Integer is protected;
|
||||
myFixFace : Face from ShapeFix is protected;
|
||||
myFixFaceMode : Integer is protected;
|
||||
myFixOrientationMode : Integer is protected;
|
||||
myNbShells : Integer is protected;
|
||||
end Shell;
|
1045
src/ShapeFix/ShapeFix_Shell.cxx
Executable file
1045
src/ShapeFix/ShapeFix_Shell.cxx
Executable file
File diff suppressed because it is too large
Load Diff
34
src/ShapeFix/ShapeFix_Shell.lxx
Executable file
34
src/ShapeFix/ShapeFix_Shell.lxx
Executable file
@@ -0,0 +1,34 @@
|
||||
// File: ShapeFix_Shell.lxx
|
||||
// Created: Tue Aug 10 11:47:36 1999
|
||||
// Author: Galina KULIKOVA
|
||||
// <gka@nnov.matra-dtv.fr>
|
||||
|
||||
//=======================================================================
|
||||
//function : FixFaceTool
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Handle(ShapeFix_Face) ShapeFix_Shell::FixFaceTool()
|
||||
{
|
||||
return myFixFace;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixFaceMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Shell::FixFaceMode()
|
||||
{
|
||||
return myFixFaceMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixOrientationMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Shell::FixOrientationMode()
|
||||
{
|
||||
return myFixOrientationMode;
|
||||
}
|
86
src/ShapeFix/ShapeFix_Solid.cdl
Executable file
86
src/ShapeFix/ShapeFix_Solid.cdl
Executable file
@@ -0,0 +1,86 @@
|
||||
-- File: ShapeFix_Solid.cdl
|
||||
-- Created: Wed Jun 3 12:33:37 1998
|
||||
-- Author: data exchange team
|
||||
-- <det@nnov.matra-dtv.fr>
|
||||
---Copyright: Matra Datavision 1998
|
||||
|
||||
|
||||
class Solid from ShapeFix inherits Root from ShapeFix
|
||||
|
||||
---Purpose: Provides method to build a solid from a shells and
|
||||
-- orients them in order to have a valid solid with finite volume
|
||||
|
||||
uses
|
||||
|
||||
Shell from TopoDS,
|
||||
Solid from TopoDS,
|
||||
Shape from TopoDS,
|
||||
Shell from ShapeFix,
|
||||
Status from ShapeExtend,
|
||||
BasicMsgRegistrator from ShapeExtend
|
||||
|
||||
is
|
||||
Create returns Solid from ShapeFix;
|
||||
---Purpose: Empty constructor;
|
||||
|
||||
Create (solid : Solid from TopoDS) returns Solid from ShapeFix;
|
||||
---Purpose: Initializes by solid.
|
||||
|
||||
Init(me: mutable; solid : Solid from TopoDS) is virtual;
|
||||
---Purpose: Initializes by solid .
|
||||
|
||||
Perform(me: mutable) returns Boolean is virtual;
|
||||
---Purpose: Iterates on shells and performs fixes
|
||||
-- (calls ShapeFix_Shell for each subshell)
|
||||
|
||||
SolidFromShell (me: mutable; shell: Shell from TopoDS)
|
||||
returns Solid from TopoDS;
|
||||
---Purpose: Calls MakeSolid and orients the solid to be "not infinite"
|
||||
|
||||
Status (me; status : Status from ShapeExtend) returns Boolean;
|
||||
---Purpose: Returns the status of the last Fix.
|
||||
|
||||
Solid (me) returns Shape from TopoDS;
|
||||
---Purpose: Returns resulting solid.
|
||||
|
||||
FixShellTool (me) returns Shell from ShapeFix;
|
||||
---Purpose: Returns tool for fixing shells.
|
||||
---C++:inline
|
||||
|
||||
SetMsgRegistrator (me: mutable; msgreg: BasicMsgRegistrator from ShapeExtend) is redefined;
|
||||
---Purpose: Sets message registrator
|
||||
|
||||
SetPrecision (me: mutable; preci: Real) is redefined;
|
||||
---Purpose: Sets basic precision value (also to FixShellTool)
|
||||
|
||||
SetMinTolerance (me: mutable; mintol: Real) is redefined;
|
||||
---Purpose: Sets minimal allowed tolerance (also to FixShellTool)
|
||||
|
||||
SetMaxTolerance (me: mutable; maxtol: Real) is redefined;
|
||||
---Purpose: Sets maximal allowed tolerance (also to FixShellTool)
|
||||
|
||||
FixShellMode (me: mutable) returns Integer;
|
||||
---C++: return &
|
||||
---C++: inline
|
||||
---Purpose: Returns (modifiable) the mode for applying fixes of
|
||||
-- ShapeFix_Shell, by default True.
|
||||
CreateOpenSolidMode(me: mutable) returns Boolean;
|
||||
---C++: return &
|
||||
---C++: inline
|
||||
---Purpose: Returns (modifiable) the mode for creation of solids.
|
||||
-- If mode myCreateOpenSolidMode is equal to true
|
||||
-- solids are created from open shells
|
||||
-- else solids are created from closed shells only.
|
||||
-- ShapeFix_Shell, by default False.
|
||||
Shape(me : mutable) returns Shape from TopoDS;
|
||||
---Purpose: In case of multiconnexity returns compound of fixed solids
|
||||
-- else returns one solid.
|
||||
fields
|
||||
|
||||
mySolid : Shape from TopoDS is protected;
|
||||
myFixShell : Shell from ShapeFix is protected;
|
||||
myStatus : Integer is protected;
|
||||
myFixShellMode : Integer is protected;
|
||||
myCreateOpenSolidMode : Boolean;
|
||||
|
||||
end Solid;
|
581
src/ShapeFix/ShapeFix_Solid.cxx
Executable file
581
src/ShapeFix/ShapeFix_Solid.cxx
Executable file
@@ -0,0 +1,581 @@
|
||||
#include <ShapeFix_Solid.ixx>
|
||||
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
#include <Standard_Failure.hxx>
|
||||
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRepClass3d_SolidClassifier.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <ShapeBuild_ReShape.hxx>
|
||||
#include <TopoDS_Iterator.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <ShapeExtend.hxx>
|
||||
#include <ShapeAnalysis_Edge.hxx>
|
||||
#include <ShapeAnalysis_Curve.hxx>
|
||||
#include <TopoDS_Wire.hxx>
|
||||
#include <ShapeExtend_WireData.hxx>
|
||||
#include <TopTools_MapIteratorOfMapOfShape.hxx>
|
||||
#include <TopoDS_Iterator.hxx>
|
||||
#include <TopTools_MapOfShape.hxx>
|
||||
#include <TopTools_DataMapOfShapeListOfShape.hxx>
|
||||
#include <TopTools_SequenceOfShape.hxx>
|
||||
#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <Bnd_Box2d.hxx>
|
||||
#include <ShapeAnalysis.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <Geom_Surface.hxx>
|
||||
#include <TopTools_ListOfShape.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <TopAbs.hxx>
|
||||
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
||||
#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
|
||||
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
||||
#include <TopoDS_Solid.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <TopoDS_CompSolid.hxx>
|
||||
#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
|
||||
#include <TopAbs.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <TopTools_IndexedMapOfShape.hxx>
|
||||
#include <TopTools_IndexedDataMapOfShapeShape.hxx>
|
||||
#include <Message_Msg.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopTools_IndexedMapOfShape.hxx>
|
||||
|
||||
#include <TopTools_DataMapOfShapeInteger.hxx>
|
||||
#include <Geom_Curve.hxx>
|
||||
#include <ShapeAnalysis_FreeBounds.hxx>
|
||||
|
||||
|
||||
//======================================================
|
||||
//function : ShapeFix_Solid
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
ShapeFix_Solid::ShapeFix_Solid()
|
||||
{
|
||||
myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
|
||||
myFixShellMode = -1;
|
||||
myFixShell = new ShapeFix_Shell;
|
||||
myCreateOpenSolidMode = Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeFix_Solid
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
ShapeFix_Solid::ShapeFix_Solid(const TopoDS_Solid& solid)
|
||||
{
|
||||
myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
|
||||
myFixShellMode = -1;
|
||||
myFixShell = new ShapeFix_Shell;
|
||||
myCreateOpenSolidMode = Standard_False;
|
||||
Init(solid);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Init
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_Solid::Init(const TopoDS_Solid& solid)
|
||||
{
|
||||
mySolid = solid;
|
||||
//mySolid = TopoDS::Solid(shape.EmptyCopied());
|
||||
//BRep_Builder B;
|
||||
// for( TopoDS_Iterator iter(solid); iter.More(); iter.Next())
|
||||
// B.Add(mySolid,TopoDS::Shell(iter.Value()));
|
||||
myShape = solid;
|
||||
}
|
||||
//=======================================================================
|
||||
//function : CollectSolids
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
static void GetMiddlePoint(const TopoDS_Shape& aShape, gp_Pnt& pmid)
|
||||
{
|
||||
TopExp_Explorer aExp(aShape,TopAbs_EDGE);
|
||||
gp_XYZ center(0.0,0.0,0.0);
|
||||
Standard_Integer numpoints =0;
|
||||
for( ; aExp.More(); aExp.Next()) {
|
||||
TopoDS_Edge e1 = TopoDS::Edge(aExp.Current());
|
||||
Standard_Real f,l;
|
||||
Handle(Geom_Curve) c3d = BRep_Tool::Curve(e1,f,l);
|
||||
if(!c3d.IsNull()) {
|
||||
for(Standard_Integer i =1 ; i <=5; i++) {
|
||||
Standard_Real param = f+(l-f)/4*(i-1);
|
||||
gp_Pnt pt;
|
||||
numpoints++;
|
||||
c3d->D0(param,pt);
|
||||
center+=pt.XYZ();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
center /= numpoints;
|
||||
pmid.SetXYZ(center);
|
||||
}
|
||||
static void CollectSolids(const TopTools_SequenceOfShape& aSeqShells ,
|
||||
TopTools_DataMapOfShapeListOfShape& aMapShellHoles,
|
||||
TopTools_DataMapOfShapeInteger& theMapStatus)
|
||||
{
|
||||
TopTools_MapOfShape aMapHoles;
|
||||
for ( Standard_Integer i1 = 1; i1 <= aSeqShells.Length(); i1++ ) {
|
||||
TopoDS_Shell aShell1 = TopoDS::Shell(aSeqShells.Value(i1));
|
||||
TopTools_ListOfShape lshells;
|
||||
aMapShellHoles.Bind(aShell1,lshells);
|
||||
}
|
||||
//Finds roots shells and hole shells.
|
||||
for ( Standard_Integer i = 1; i <= aSeqShells.Length(); i++ ) {
|
||||
TopoDS_Shell aShell1 = TopoDS::Shell(aSeqShells.Value(i));
|
||||
TopExp_Explorer aExpEdges(aShell1,TopAbs_EDGE);
|
||||
if(!BRep_Tool::IsClosed(aShell1) || !aExpEdges.More()) continue;
|
||||
TopoDS_Solid solid;
|
||||
BRep_Builder B;
|
||||
B.MakeSolid (solid);
|
||||
B.Add (solid,aShell1);
|
||||
try {
|
||||
OCC_CATCH_SIGNALS
|
||||
TopAbs_State infinstatus = TopAbs_UNKNOWN;
|
||||
BRepClass3d_SolidClassifier bsc3d (solid);
|
||||
Standard_Integer st = 0;
|
||||
if(!theMapStatus.IsBound(aShell1)) {
|
||||
|
||||
bsc3d.PerformInfinitePoint(Precision::Confusion());
|
||||
infinstatus = bsc3d.State();
|
||||
|
||||
if(infinstatus != TopAbs_UNKNOWN && infinstatus !=TopAbs_ON)
|
||||
st = (infinstatus == TopAbs_IN ? 1 :2);
|
||||
theMapStatus.Bind(aShell1,st);
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
st = theMapStatus.Find(aShell1);
|
||||
if(st)
|
||||
infinstatus = (theMapStatus.Find(aShell1) == 1 ? TopAbs_IN : TopAbs_OUT);
|
||||
}
|
||||
if(!st) continue;
|
||||
for ( Standard_Integer j = 1; j <= aSeqShells.Length(); j++ ) {
|
||||
if(i==j) continue;
|
||||
TopoDS_Shape aShell2 = aSeqShells.Value(j);
|
||||
if(!BRep_Tool::IsClosed(aShell2)) continue;
|
||||
if(aMapHoles.Contains(aShell2)) continue;
|
||||
if(aMapShellHoles.IsBound(aShell2)) {
|
||||
Standard_Boolean isAnalysis = Standard_False;
|
||||
const TopTools_ListOfShape& ls = aMapShellHoles.Find(aShell2);
|
||||
for(TopTools_ListIteratorOfListOfShape li(ls); li.More() && !isAnalysis; li.Next())
|
||||
isAnalysis = li.Value().IsSame(aShell1);
|
||||
if(isAnalysis) continue;
|
||||
}
|
||||
TopAbs_State pointstatus = TopAbs_UNKNOWN;
|
||||
Standard_Integer numon =0;
|
||||
TopTools_IndexedMapOfShape amapVert;
|
||||
for(TopExp_Explorer aExpVert(aShell2,TopAbs_VERTEX); aExpVert.More() && amapVert.Extent() < 10; aExpVert.Next())
|
||||
amapVert.Add(aExpVert.Current());
|
||||
for(Standard_Integer k = 1; k <= amapVert.Extent() &&
|
||||
(pointstatus ==TopAbs_UNKNOWN || (pointstatus ==TopAbs_ON && numon < 3)); k++) {
|
||||
TopoDS_Vertex aV = TopoDS::Vertex(amapVert.FindKey(k));
|
||||
gp_Pnt aPf = BRep_Tool::Pnt(aV);
|
||||
bsc3d.Perform(aPf,Precision::Confusion());
|
||||
pointstatus =bsc3d.State();
|
||||
if(pointstatus ==TopAbs_ON) numon++;
|
||||
}
|
||||
|
||||
if(numon == 3 && pointstatus ==TopAbs_ON) {
|
||||
//gp_Pnt pmid;
|
||||
//GetMiddlePoint(aShell2,pmid);
|
||||
//bsc3d.Perform(pmid,Precision::Confusion());
|
||||
pointstatus = /*(bsc3d.State() == TopAbs_IN ? TopAbs_IN :*/TopAbs_OUT;
|
||||
}
|
||||
if(pointstatus != infinstatus) {
|
||||
aMapShellHoles.ChangeFind(aShell1).Append(aShell2);
|
||||
if( aMapHoles.Contains(aShell2))
|
||||
aMapHoles.Remove(aShell2);
|
||||
else aMapHoles.Add(aShell2);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Standard_Failure) {
|
||||
#ifdef DEB
|
||||
cout << "Warning: ShapeFix_Solid::SolidFromShell: Exception: ";
|
||||
Standard_Failure::Caught()->Print(cout); cout << endl;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
}
|
||||
TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItShellHoles( aMapShellHoles);
|
||||
for(; aItShellHoles.More();aItShellHoles.Next()) {
|
||||
if(aMapHoles.Contains(aItShellHoles.Key())) continue;
|
||||
const TopTools_ListOfShape& lHoles =aItShellHoles.Value();
|
||||
if(lHoles.IsEmpty()) continue;
|
||||
for(TopTools_ListIteratorOfListOfShape lItHoles(lHoles);lItHoles.More(); lItHoles.Next()) {
|
||||
if(aMapHoles.Contains(lItHoles.Value())) {
|
||||
const TopTools_ListOfShape& lUnHoles = aMapShellHoles.Find(lItHoles.Value());
|
||||
for(TopTools_ListIteratorOfListOfShape lItUnHoles(lUnHoles);lItUnHoles.More(); lItUnHoles.Next())
|
||||
aMapHoles.Remove(lItUnHoles.Value());
|
||||
}
|
||||
}
|
||||
}
|
||||
for(TopTools_MapIteratorOfMapOfShape aIterHoles(aMapHoles);aIterHoles.More(); aIterHoles.Next())
|
||||
aMapShellHoles.UnBind(aIterHoles.Key());
|
||||
|
||||
}
|
||||
//=======================================================================
|
||||
//function : CreateSolids
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
static Standard_Boolean CreateSolids(const TopoDS_Shape aShape,TopTools_IndexedMapOfShape& aMapSolids)
|
||||
{
|
||||
TopTools_SequenceOfShape aSeqShells;
|
||||
Standard_Boolean isDone = Standard_False;
|
||||
|
||||
for(TopExp_Explorer aExpShell(aShape,TopAbs_SHELL); aExpShell.More(); aExpShell.Next()) {
|
||||
aSeqShells.Append(aExpShell.Current());
|
||||
}
|
||||
TopTools_DataMapOfShapeListOfShape aMapShellHoles;
|
||||
TopTools_DataMapOfShapeInteger aMapStatus;
|
||||
CollectSolids(aSeqShells,aMapShellHoles,aMapStatus);
|
||||
TopTools_IndexedDataMapOfShapeShape ShellSolid;
|
||||
TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItShellHoles( aMapShellHoles);
|
||||
//Defines correct orientation of shells
|
||||
for(; aItShellHoles.More();aItShellHoles.Next()) {
|
||||
TopoDS_Shell aShell = TopoDS::Shell(aItShellHoles.Key());
|
||||
TopExp_Explorer aExpEdges(aShell,TopAbs_EDGE);
|
||||
if(!BRep_Tool::IsClosed(aShell) || !aExpEdges.More()) {
|
||||
ShellSolid.Add(aShell,aShell);
|
||||
isDone = Standard_True;
|
||||
continue;
|
||||
}
|
||||
BRep_Builder B;
|
||||
TopAbs_State infinstatus = TopAbs_UNKNOWN;
|
||||
TopoDS_Solid aSolid;
|
||||
B.MakeSolid (aSolid);
|
||||
B.Add (aSolid,aShell);
|
||||
if(aMapStatus.IsBound(aShell)) {
|
||||
Standard_Integer st = aMapStatus.Find(aShell);
|
||||
if(st)
|
||||
infinstatus = (aMapStatus.Find(aShell) == 1 ? TopAbs_IN : TopAbs_OUT);
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
try {
|
||||
OCC_CATCH_SIGNALS
|
||||
BRepClass3d_SolidClassifier bsc3d (aSolid);
|
||||
bsc3d.PerformInfinitePoint(Precision::Confusion());
|
||||
infinstatus = bsc3d.State();
|
||||
}
|
||||
catch(Standard_Failure) {
|
||||
#ifdef DEB
|
||||
cout << "Warning: ShapeFix_Solid::SolidFromShell: Exception: ";
|
||||
Standard_Failure::Caught()->Print(cout); cout << endl;
|
||||
#endif
|
||||
ShellSolid.Add(aShell,aSolid);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (infinstatus == TopAbs_IN) {
|
||||
isDone = Standard_True;
|
||||
aShell.Reverse();
|
||||
TopoDS_Solid aTmpSolid;
|
||||
B.MakeSolid (aTmpSolid);
|
||||
B.Add (aTmpSolid,aShell);
|
||||
aSolid = aTmpSolid;
|
||||
}
|
||||
|
||||
const TopTools_ListOfShape& lHoles = aItShellHoles.Value();
|
||||
for(TopTools_ListIteratorOfListOfShape lItHoles(lHoles); lItHoles.More();lItHoles.Next()) {
|
||||
TopoDS_Shell aShellHole = TopoDS::Shell(lItHoles.Value());
|
||||
if(aMapStatus.IsBound(aShellHole)) {
|
||||
infinstatus = (aMapStatus.Find(aShellHole) == 1 ? TopAbs_IN : TopAbs_OUT);
|
||||
}
|
||||
else {
|
||||
TopoDS_Solid solid;
|
||||
B.MakeSolid (solid);
|
||||
B.Add (solid,aShellHole);
|
||||
BRepClass3d_SolidClassifier bsc3dHol (solid);
|
||||
bsc3dHol.PerformInfinitePoint(Precision::Confusion());
|
||||
infinstatus = bsc3dHol.State();
|
||||
}
|
||||
if (infinstatus == TopAbs_OUT) {
|
||||
aShellHole.Reverse();
|
||||
isDone = Standard_True;
|
||||
}
|
||||
B.Add(aSolid,aShellHole);
|
||||
}
|
||||
ShellSolid.Add(aShell,aSolid);
|
||||
}
|
||||
//Creation of compsolid from shells containing shared faces.
|
||||
TopTools_IndexedDataMapOfShapeListOfShape aMapFaceShells;
|
||||
TopExp::MapShapesAndAncestors(aShape,TopAbs_FACE,TopAbs_SHELL,aMapFaceShells);
|
||||
for(Standard_Integer i =1; i <= aMapFaceShells.Extent(); i++) {
|
||||
const TopTools_ListOfShape& lshells = aMapFaceShells.FindFromIndex(i);
|
||||
if(lshells.Extent() <2) continue;
|
||||
TopoDS_CompSolid aCompSolid;
|
||||
BRep_Builder aB;
|
||||
aB.MakeCompSolid(aCompSolid);
|
||||
isDone = (aShape.ShapeType() != TopAbs_COMPSOLID || isDone);
|
||||
for(TopTools_ListIteratorOfListOfShape lItSh(lshells);lItSh.More(); lItSh.Next()) {
|
||||
if(ShellSolid.Contains(lItSh.Value())) {
|
||||
for(TopExp_Explorer aExpSol(ShellSolid.FindFromKey(lItSh.Value()),TopAbs_SOLID);aExpSol.More(); aExpSol.Next())
|
||||
aB.Add(aCompSolid,aExpSol.Current());
|
||||
ShellSolid.ChangeFromKey(lItSh.Value()) = aCompSolid;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(Standard_Integer kk =1 ; kk <= ShellSolid.Extent();kk++)
|
||||
if(!aMapSolids.Contains(ShellSolid.FindFromIndex(kk)))
|
||||
aMapSolids.Add(ShellSolid.FindFromIndex(kk));
|
||||
isDone = (aMapSolids.Extent() >1 || isDone);
|
||||
return isDone;
|
||||
}
|
||||
//=======================================================================
|
||||
//function : Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_Solid::Perform()
|
||||
{
|
||||
|
||||
Standard_Boolean status = Standard_False;
|
||||
if(Context().IsNull())
|
||||
SetContext ( new ShapeBuild_ReShape );
|
||||
myFixShell->SetContext(Context());
|
||||
Standard_Integer NbShells =0;
|
||||
TopoDS_Shape S = Context()->Apply ( myShape );
|
||||
if ( NeedFix ( myFixShellMode ) ) {
|
||||
|
||||
// call FixShell
|
||||
for( TopoDS_Iterator iter(S); iter.More(); iter.Next()) {
|
||||
TopoDS_Shape sh = iter.Value();
|
||||
if(sh.ShapeType() != TopAbs_SHELL)
|
||||
continue;
|
||||
myFixShell->Init(TopoDS::Shell(sh));
|
||||
if(myFixShell->Perform()) {
|
||||
// Context()->Replace(sh,myFixShell->Shell());
|
||||
status = Standard_True;
|
||||
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
|
||||
}
|
||||
NbShells+= myFixShell->NbShells();
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(TopExp_Explorer aExpSh(myShape,TopAbs_SHELL); aExpSh.More(); aExpSh.Next())
|
||||
NbShells++;
|
||||
}
|
||||
//if(!status) return status;
|
||||
|
||||
if(NbShells ==1) {
|
||||
TopoDS_Shape tmpShape = Context()->Apply(myShape);
|
||||
TopExp_Explorer aExp(tmpShape,TopAbs_SHELL);
|
||||
Standard_Boolean isClosed = Standard_False;
|
||||
if(aExp.More()) {
|
||||
TopoDS_Shell aShtmp = TopoDS::Shell(aExp.Current());
|
||||
ShapeAnalysis_FreeBounds sfb(aShtmp);
|
||||
TopoDS_Compound aC1 = sfb.GetClosedWires();
|
||||
TopoDS_Compound aC2 = sfb.GetOpenWires();
|
||||
Standard_Integer numedge =0;
|
||||
TopExp_Explorer aExp1(aC1,TopAbs_EDGE);
|
||||
for( ; aExp1.More(); aExp1.Next())
|
||||
numedge++;
|
||||
for(aExp1.Init(aC2,TopAbs_EDGE) ; aExp1.More(); aExp1.Next())
|
||||
numedge++;
|
||||
isClosed = (!numedge);
|
||||
aShtmp.Closed(isClosed);
|
||||
}
|
||||
|
||||
if(isClosed || myCreateOpenSolidMode) {
|
||||
if(BRep_Tool::IsClosed(tmpShape)) {
|
||||
TopoDS_Iterator itersh(tmpShape);
|
||||
TopoDS_Shell aShell;
|
||||
if(itersh.More() && itersh.Value().ShapeType() == TopAbs_SHELL)
|
||||
aShell = TopoDS::Shell(itersh.Value());
|
||||
if(!aShell.IsNull()) {
|
||||
TopoDS_Solid aSol = SolidFromShell(aShell);
|
||||
if(ShapeExtend::DecodeStatus(myStatus,ShapeExtend_DONE2)) {
|
||||
SendWarning (Message_Msg ("FixAdvSolid.FixOrientation.MSG20"));// Orientaion of shell was corrected.
|
||||
Context()->Replace(tmpShape,aSol);
|
||||
tmpShape = aSol;
|
||||
}
|
||||
}
|
||||
}
|
||||
mySolid = TopoDS::Solid(tmpShape);
|
||||
}
|
||||
else {
|
||||
TopoDS_Iterator aIt(tmpShape,Standard_False);
|
||||
Context()->Replace(tmpShape,aIt.Value());
|
||||
SendFail (Message_Msg ("FixAdvSolid.FixShell.MSG10")); // Solid can not be created from open shell.
|
||||
}
|
||||
}
|
||||
else {
|
||||
TopoDS_Shape aResShape = Context()->Apply(myShape);
|
||||
TopTools_SequenceOfShape aSeqShells;
|
||||
TopTools_IndexedMapOfShape aMapSolids;
|
||||
if(CreateSolids(aResShape,aMapSolids)) {
|
||||
SendWarning (Message_Msg ("FixAdvSolid.FixOrientation.MSG20"));// Orientaion of shell was corrected..
|
||||
if(aMapSolids.Extent() ==1) {
|
||||
TopoDS_Shape aResSol = aMapSolids.FindKey(1);
|
||||
if(aResShape.ShapeType() == TopAbs_SHELL && myCreateOpenSolidMode) {
|
||||
TopoDS_Solid solid;
|
||||
BRep_Builder B;
|
||||
B.MakeSolid (solid);
|
||||
B.Add (solid,aResSol);
|
||||
mySolid = solid;
|
||||
}
|
||||
else {
|
||||
mySolid =aResSol;
|
||||
if(aResSol.ShapeType() == TopAbs_SHELL)
|
||||
SendFail (Message_Msg ("FixAdvSolid.FixShell.MSG10")); // Solid can not be created from open shell.
|
||||
}
|
||||
Context()->Replace(aResShape,mySolid);
|
||||
}
|
||||
else if(aMapSolids.Extent() >1) {
|
||||
SendWarning (Message_Msg ("FixAdvSolid.FixOrientation.MSG30"));// Bad connected solid a few solids were created.
|
||||
BRep_Builder aB;
|
||||
TopoDS_Compound aComp;
|
||||
aB.MakeCompound(aComp);
|
||||
for(Standard_Integer i =1; i <= aMapSolids.Extent(); i++) {
|
||||
TopoDS_Shape aResSh =aMapSolids.FindKey(i);
|
||||
if(aResShape.ShapeType() == TopAbs_SHELL && myCreateOpenSolidMode) {
|
||||
aResSh.Closed(Standard_False);
|
||||
TopoDS_Solid solid;
|
||||
BRep_Builder B;
|
||||
B.MakeSolid (solid);
|
||||
B.Add (solid,aResSh);
|
||||
aResSh = solid;
|
||||
}
|
||||
else if (aResShape.ShapeType() == TopAbs_SHELL)
|
||||
SendFail(Message_Msg ("FixAdvSolid.FixShell.MSG10")); // Solid can not be created from open shell.
|
||||
aB.Add(aComp,aResSh);
|
||||
|
||||
}
|
||||
Context()->Replace(aResShape,aComp);
|
||||
}
|
||||
}
|
||||
}
|
||||
myShape = Context()->Apply(myShape);
|
||||
return status;
|
||||
}
|
||||
//=======================================================================
|
||||
//function : Shape
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
TopoDS_Shape ShapeFix_Solid::Shape()
|
||||
{
|
||||
return myShape;
|
||||
}
|
||||
//=======================================================================
|
||||
//function : SolidFromShell
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
TopoDS_Solid ShapeFix_Solid::SolidFromShell (const TopoDS_Shell& shell)
|
||||
{
|
||||
TopoDS_Shell sh = shell;
|
||||
if (!sh.Free ()) sh.Free(Standard_True);
|
||||
|
||||
TopoDS_Solid solid;
|
||||
BRep_Builder B;
|
||||
B.MakeSolid (solid);
|
||||
B.Add (solid,sh);
|
||||
// Pas encore fini : il faut une bonne orientation
|
||||
try {
|
||||
OCC_CATCH_SIGNALS
|
||||
BRepClass3d_SolidClassifier bsc3d (solid);
|
||||
Standard_Real t = Precision::Confusion(); // tolerance moyenne
|
||||
bsc3d.PerformInfinitePoint(t);
|
||||
|
||||
if (bsc3d.State() == TopAbs_IN) {
|
||||
// Ensuite, inverser C-A-D REPRENDRE LES SHELLS
|
||||
// (l inversion du solide n est pas bien prise en compte)
|
||||
sh = shell;
|
||||
if (!sh.Free ()) sh.Free(Standard_True);
|
||||
TopoDS_Solid soli2;
|
||||
B.MakeSolid (soli2); // on recommence
|
||||
sh.Reverse();
|
||||
B.Add (soli2,sh);
|
||||
solid = soli2;
|
||||
myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
|
||||
}
|
||||
}
|
||||
catch(Standard_Failure) {
|
||||
#ifdef DEB
|
||||
cout << "Warning: ShapeFix_Solid::SolidFromShell: Exception: ";
|
||||
Standard_Failure::Caught()->Print(cout); cout << endl;
|
||||
#endif
|
||||
return solid;
|
||||
}
|
||||
return solid;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Status
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_Solid::Status(const ShapeExtend_Status /*status*/) const
|
||||
{
|
||||
return myStatus;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Solid
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
TopoDS_Shape ShapeFix_Solid::Solid() const
|
||||
{
|
||||
return mySolid;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetMsgRegistrator
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_Solid::SetMsgRegistrator(const Handle(ShapeExtend_BasicMsgRegistrator)& msgreg)
|
||||
{
|
||||
ShapeFix_Root::SetMsgRegistrator ( msgreg );
|
||||
myFixShell->SetMsgRegistrator ( msgreg );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetPrecision
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_Solid::SetPrecision (const Standard_Real preci)
|
||||
{
|
||||
ShapeFix_Root::SetPrecision ( preci );
|
||||
myFixShell->SetPrecision ( preci );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetMinTolerance
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_Solid::SetMinTolerance (const Standard_Real mintol)
|
||||
{
|
||||
ShapeFix_Root::SetMinTolerance ( mintol );
|
||||
myFixShell->SetMinTolerance ( mintol );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetMaxTolerance
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_Solid::SetMaxTolerance (const Standard_Real maxtol)
|
||||
{
|
||||
ShapeFix_Root::SetMaxTolerance ( maxtol );
|
||||
myFixShell->SetMaxTolerance ( maxtol );
|
||||
}
|
28
src/ShapeFix/ShapeFix_Solid.lxx
Executable file
28
src/ShapeFix/ShapeFix_Solid.lxx
Executable file
@@ -0,0 +1,28 @@
|
||||
//=======================================================================
|
||||
//function : FixShellTool
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Handle(ShapeFix_Shell) ShapeFix_Solid::FixShellTool() const
|
||||
{
|
||||
return myFixShell;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixShellMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Solid::FixShellMode()
|
||||
{
|
||||
return myFixShellMode;
|
||||
}
|
||||
//=======================================================================
|
||||
//function : CreateOpenSolidMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean& ShapeFix_Solid::CreateOpenSolidMode()
|
||||
{
|
||||
return myCreateOpenSolidMode;
|
||||
}
|
35
src/ShapeFix/ShapeFix_SplitCommonVertex.cdl
Executable file
35
src/ShapeFix/ShapeFix_SplitCommonVertex.cdl
Executable file
@@ -0,0 +1,35 @@
|
||||
-- File: ShapeFix_SplitCommonVertex.cdl
|
||||
-- Created: Wed Feb 4 12:35:52 2004
|
||||
-- Author: Sergey KUUL
|
||||
-- <skl@popox.nnov.matra-dtv.fr>
|
||||
---Copyright: Matra Datavision 2004
|
||||
|
||||
class SplitCommonVertex from ShapeFix inherits Root from ShapeFix
|
||||
|
||||
---Purpose: Two wires have common vertex - this case is valid in BRep model
|
||||
-- and isn't valid in STEP => before writing into STEP it is necessary
|
||||
-- to split this vertex (each wire must has one vertex)
|
||||
|
||||
uses
|
||||
Shape from TopoDS
|
||||
|
||||
is
|
||||
Create returns SplitCommonVertex;
|
||||
---Purpose :
|
||||
|
||||
Init(me: mutable; S : Shape from TopoDS);
|
||||
---Purpose :
|
||||
|
||||
Perform(me:mutable);
|
||||
---Purpose :
|
||||
|
||||
Shape(me : mutable) returns Shape from TopoDS;
|
||||
---Purpose :
|
||||
|
||||
fields
|
||||
|
||||
myShape : Shape from TopoDS;
|
||||
myResult : Shape from TopoDS;
|
||||
myStatus : Integer; -- error status
|
||||
|
||||
end SplitCommonVertex;
|
138
src/ShapeFix/ShapeFix_SplitCommonVertex.cxx
Executable file
138
src/ShapeFix/ShapeFix_SplitCommonVertex.cxx
Executable file
@@ -0,0 +1,138 @@
|
||||
#include <ShapeFix_SplitCommonVertex.ixx>
|
||||
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <ShapeAnalysis_Edge.hxx>
|
||||
#include <ShapeBuild_ReShape.hxx>
|
||||
#include <ShapeBuild_Edge.hxx>
|
||||
#include <ShapeExtend.hxx>
|
||||
#include <ShapeExtend_WireData.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopoDS_Iterator.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Wire.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopTools_SequenceOfShape.hxx>
|
||||
#include <TopTools_DataMapOfShapeShape.hxx>
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeFix_SplitCommonVertex
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
ShapeFix_SplitCommonVertex::ShapeFix_SplitCommonVertex()
|
||||
{
|
||||
myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
|
||||
SetPrecision(Precision::Confusion());
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Init
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_SplitCommonVertex::Init(const TopoDS_Shape& S)
|
||||
{
|
||||
myShape = S;
|
||||
if ( Context().IsNull() )
|
||||
SetContext ( new ShapeBuild_ReShape );
|
||||
myResult = myShape;
|
||||
Context()->Apply(myShape);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_SplitCommonVertex::Perform()
|
||||
{
|
||||
TopAbs_ShapeEnum st = myShape.ShapeType();
|
||||
if(st>TopAbs_FACE) return;
|
||||
for(TopExp_Explorer itf(myShape,TopAbs_FACE); itf.More(); itf.Next()) {
|
||||
TopoDS_Shape tmpFace = Context()->Apply(itf.Current());
|
||||
TopoDS_Face F = TopoDS::Face(tmpFace);
|
||||
if(F.IsNull()) continue;
|
||||
// analys face and split if necessary
|
||||
TopTools_SequenceOfShape wires;
|
||||
for(TopoDS_Iterator itw(F,Standard_False); itw.More(); itw.Next()) {
|
||||
if(itw.Value().ShapeType() != TopAbs_WIRE)
|
||||
continue;
|
||||
wires.Append(itw.Value());
|
||||
}
|
||||
if(wires.Length()<2) continue;
|
||||
TopTools_DataMapOfShapeShape MapVV;
|
||||
MapVV.Clear();
|
||||
for(Standard_Integer nw1=1; nw1<wires.Length(); nw1++) {
|
||||
TopoDS_Wire w1 = TopoDS::Wire(wires.Value(nw1));
|
||||
Handle(ShapeExtend_WireData) sewd1 = new ShapeExtend_WireData(w1);
|
||||
for(Standard_Integer nw2=nw1+1; nw2<=wires.Length(); nw2++) {
|
||||
TopoDS_Wire w2 = TopoDS::Wire(wires.Value(nw2));
|
||||
Handle(ShapeExtend_WireData) sewd2 = new ShapeExtend_WireData(w2);
|
||||
|
||||
for(TopExp_Explorer expv1(w1,TopAbs_VERTEX); expv1.More(); expv1.Next()) {
|
||||
TopoDS_Vertex V1 = TopoDS::Vertex(expv1.Current());
|
||||
for(TopExp_Explorer expv2(w2,TopAbs_VERTEX); expv2.More(); expv2.Next()) {
|
||||
TopoDS_Vertex V2 = TopoDS::Vertex(expv2.Current());
|
||||
if(V1==V2) {
|
||||
// common vertex exists
|
||||
TopoDS_Vertex Vnew;
|
||||
if(MapVV.IsBound(V2)) {
|
||||
Vnew = TopoDS::Vertex(MapVV.Find(V2));
|
||||
}
|
||||
else {
|
||||
gp_Pnt P = BRep_Tool::Pnt(V2);
|
||||
Standard_Real tol = BRep_Tool::Tolerance(V2);
|
||||
BRep_Builder B;
|
||||
B.MakeVertex(Vnew,P,tol);
|
||||
MapVV.Bind(V2,Vnew);
|
||||
}
|
||||
ShapeBuild_Edge sbe;
|
||||
ShapeAnalysis_Edge sae;
|
||||
for(Standard_Integer ne2=1; ne2<=sewd2->NbEdges(); ne2++) {
|
||||
TopoDS_Edge E = sewd2->Edge(ne2);
|
||||
TopoDS_Vertex FV = sae.FirstVertex(E);
|
||||
TopoDS_Vertex LV = sae.LastVertex(E);
|
||||
Standard_Boolean IsCoinc = Standard_False;
|
||||
if(FV==V2) {
|
||||
FV=Vnew;
|
||||
IsCoinc = Standard_True;
|
||||
}
|
||||
if(LV==V2) {
|
||||
LV=Vnew;
|
||||
IsCoinc = Standard_True;
|
||||
}
|
||||
if(IsCoinc) {
|
||||
TopoDS_Edge NewE = sbe.CopyReplaceVertices(E,FV,LV);
|
||||
Context()->Replace(E,NewE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
myShape = Context()->Apply(myShape);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Shape
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
TopoDS_Shape ShapeFix_SplitCommonVertex::Shape()
|
||||
{
|
||||
return myShape;
|
||||
}
|
||||
|
70
src/ShapeFix/ShapeFix_SplitTool.cdl
Executable file
70
src/ShapeFix/ShapeFix_SplitTool.cdl
Executable file
@@ -0,0 +1,70 @@
|
||||
-- File: ShapeFix_SplitTool.cdl
|
||||
-- Created: Wed Jul 14 16:04:29 2004
|
||||
-- Author: Sergey KUUL
|
||||
-- <skl@petrox.nnov.matra-dtv.fr>
|
||||
---Copyright: Matra Datavision 2004
|
||||
|
||||
class SplitTool from ShapeFix
|
||||
|
||||
---Purpose: Tool for splitting and cutting edges; includes methods
|
||||
-- used in OverlappingTool and IntersectionTool
|
||||
|
||||
uses
|
||||
|
||||
Face from TopoDS,
|
||||
Edge from TopoDS,
|
||||
Vertex from TopoDS,
|
||||
ReShape from ShapeBuild,
|
||||
SequenceOfShape from TopTools
|
||||
|
||||
is
|
||||
Create returns SplitTool from ShapeFix;
|
||||
---Purpose: Empty constructor
|
||||
|
||||
SplitEdge(me; edge: Edge from TopoDS;
|
||||
param: Real from Standard;
|
||||
vert: Vertex from TopoDS;
|
||||
face: Face from TopoDS;
|
||||
newE1: in out Edge from TopoDS;
|
||||
newE2: in out Edge from TopoDS;
|
||||
tol3d, tol2d : Real from Standard)
|
||||
returns Boolean from Standard;
|
||||
---Purpose: Split edge on two new edges using new vertex "vert"
|
||||
-- and "param" - parameter for splitting
|
||||
-- The "face" is necessary for pcurves and using TransferParameterProj
|
||||
|
||||
SplitEdge (me; edge: Edge from TopoDS;
|
||||
param1: Real from Standard;
|
||||
param2: Real from Standard;
|
||||
vert: Vertex from TopoDS;
|
||||
face: Face from TopoDS;
|
||||
newE1: in out Edge from TopoDS;
|
||||
newE2: in out Edge from TopoDS;
|
||||
tol3d, tol2d : Real from Standard)
|
||||
returns Boolean from Standard;
|
||||
---Purpose: Split edge on two new edges using new vertex "vert"
|
||||
-- and "param1" and "param2" - parameter for splitting and cutting
|
||||
-- The "face" is necessary for pcurves and using TransferParameterProj
|
||||
|
||||
CutEdge(me; edge: Edge from TopoDS; pend: Real from Standard;
|
||||
cut: Real from Standard; face: Face from TopoDS;
|
||||
iscutline: in out Boolean from Standard)
|
||||
returns Boolean from Standard;
|
||||
---Purpose: Cut edge by parameters pend and cut
|
||||
|
||||
SplitEdge(me; edge: Edge from TopoDS; fp: Real from Standard;
|
||||
V1: Vertex from TopoDS; lp: Real from Standard;
|
||||
V2: Vertex from TopoDS; face: Face from TopoDS;
|
||||
SeqE: in out SequenceOfShape from TopTools;
|
||||
aNum: in out Integer from Standard;
|
||||
context: ReShape from ShapeBuild;
|
||||
tol3d, tol2d : Real from Standard)
|
||||
returns Boolean from Standard;
|
||||
---Purpose: Split edge on two new edges using two new vertex V1 and V2
|
||||
-- and two parameters for splitting - fp and lp correspondingly
|
||||
-- The "face" is necessary for pcurves and using TransferParameterProj
|
||||
-- aNum - number of edge in SeqE which corresponding to [fp,lp]
|
||||
|
||||
|
||||
|
||||
end SplitTool;
|
440
src/ShapeFix/ShapeFix_SplitTool.cxx
Executable file
440
src/ShapeFix/ShapeFix_SplitTool.cxx
Executable file
@@ -0,0 +1,440 @@
|
||||
// File: ShapeFix_SplitTool.cxx
|
||||
// Created: 14.07.04 16:10:47
|
||||
// Author: Sergey KUUL
|
||||
|
||||
#include <ShapeFix_SplitTool.ixx>
|
||||
|
||||
#include <ShapeAnalysis_Edge.hxx>
|
||||
#include <ShapeAnalysis_Surface.hxx>
|
||||
#include <ShapeAnalysis_TransferParametersProj.hxx>
|
||||
#include <ShapeFix_Edge.hxx>
|
||||
#include <ShapeBuild_Edge.hxx>
|
||||
#include <ShapeExtend_WireData.hxx>
|
||||
#include <Geom_Curve.hxx>
|
||||
#include <Geom2d_Curve.hxx>
|
||||
#include <Geom2d_TrimmedCurve.hxx>
|
||||
#include <Geom2d_Line.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRepTools.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Wire.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeFix_SplitTool()
|
||||
//purpose : Constructor
|
||||
//=======================================================================
|
||||
|
||||
ShapeFix_SplitTool::ShapeFix_SplitTool()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : SplitEdge
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_SplitTool::SplitEdge(const TopoDS_Edge& edge,
|
||||
const Standard_Real param,
|
||||
const TopoDS_Vertex& vert,
|
||||
const TopoDS_Face& face,
|
||||
TopoDS_Edge& newE1,
|
||||
TopoDS_Edge& newE2,
|
||||
const Standard_Real tol3d,
|
||||
const Standard_Real tol2d) const
|
||||
{
|
||||
Standard_Real a, b;
|
||||
ShapeAnalysis_Edge sae;
|
||||
Handle(Geom2d_Curve) c2d;
|
||||
sae.PCurve(edge,face,c2d,a,b,Standard_True );
|
||||
if( Abs(a-param)<tol2d || Abs(b-param)<tol2d )
|
||||
return Standard_False;
|
||||
// check distanse between edge and new vertex
|
||||
gp_Pnt P1;
|
||||
TopLoc_Location L;
|
||||
if(BRep_Tool::SameParameter(edge)) {
|
||||
Standard_Real f,l;
|
||||
const Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge,L,f,l);
|
||||
if(c3d.IsNull())
|
||||
return Standard_False;
|
||||
P1 = c3d->Value(param);
|
||||
if(!L.IsIdentity()) P1 = P1.Transformed(L.Transformation());
|
||||
}
|
||||
else {
|
||||
Handle(Geom_Surface) surf = BRep_Tool::Surface(face,L);
|
||||
Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface(surf);
|
||||
P1 = sas->Value(c2d->Value(param));
|
||||
if(!L.IsIdentity()) P1 = P1.Transformed(L.Transformation());
|
||||
}
|
||||
gp_Pnt P2 = BRep_Tool::Pnt(vert);
|
||||
if(P1.Distance(P2)>tol3d) {
|
||||
//return Standard_False;
|
||||
BRep_Builder B;
|
||||
B.UpdateVertex(vert,P1.Distance(P2));
|
||||
}
|
||||
|
||||
Handle(ShapeAnalysis_TransferParametersProj) transferParameters =
|
||||
new ShapeAnalysis_TransferParametersProj;
|
||||
transferParameters->SetMaxTolerance(tol3d);
|
||||
transferParameters->Init(edge,face);
|
||||
Standard_Real first, last;
|
||||
if (a < b ) {
|
||||
first = a;
|
||||
last = b;
|
||||
}
|
||||
else {
|
||||
first = b;
|
||||
last = a;
|
||||
}
|
||||
|
||||
ShapeBuild_Edge sbe;
|
||||
Handle(ShapeFix_Edge) sfe = new ShapeFix_Edge;
|
||||
TopAbs_Orientation orient = edge.Orientation();
|
||||
BRep_Builder B;
|
||||
TopoDS_Edge wE = edge;
|
||||
wE.Orientation ( TopAbs_FORWARD );
|
||||
TopoDS_Shape aTmpShape = vert.Oriented(TopAbs_REVERSED); //for porting
|
||||
newE1 = sbe.CopyReplaceVertices ( wE, sae.FirstVertex(wE), TopoDS::Vertex(aTmpShape) );
|
||||
sbe.CopyPCurves ( newE1, wE );
|
||||
transferParameters->TransferRange(newE1,first,param,Standard_True);
|
||||
B.SameRange(newE1,Standard_False);
|
||||
sfe->FixSameParameter(newE1);
|
||||
//B.SameParameter(newE1,Standard_False);
|
||||
aTmpShape = vert.Oriented(TopAbs_FORWARD);
|
||||
newE2 = sbe.CopyReplaceVertices ( wE, TopoDS::Vertex(aTmpShape),sae.LastVertex(wE) );
|
||||
sbe.CopyPCurves ( newE2, wE );
|
||||
transferParameters->TransferRange(newE2,param,last,Standard_True);
|
||||
B.SameRange(newE2,Standard_False);
|
||||
sfe->FixSameParameter(newE2);
|
||||
//B.SameParameter(newE2,Standard_False);
|
||||
|
||||
newE1.Orientation(orient);
|
||||
newE2.Orientation(orient);
|
||||
if (orient==TopAbs_REVERSED) {
|
||||
TopoDS_Edge tmp = newE2; newE2 = newE1; newE1=tmp;
|
||||
}
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : SplitEdge
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_SplitTool::SplitEdge(const TopoDS_Edge& edge,
|
||||
const Standard_Real param1,
|
||||
const Standard_Real param2,
|
||||
const TopoDS_Vertex& vert,
|
||||
const TopoDS_Face& face,
|
||||
TopoDS_Edge& newE1,
|
||||
TopoDS_Edge& newE2,
|
||||
const Standard_Real tol3d,
|
||||
const Standard_Real tol2d) const
|
||||
{
|
||||
Standard_Real param = (param1+param2)/2;
|
||||
if(SplitEdge(edge,param,vert,face,newE1,newE2,tol3d,tol2d)) {
|
||||
// cut new edges by param1 and param2
|
||||
Standard_Boolean IsCutLine;
|
||||
Handle(Geom2d_Curve) Crv1, Crv2;
|
||||
Standard_Real fp1,lp1,fp2,lp2;
|
||||
ShapeAnalysis_Edge sae;
|
||||
if(sae.PCurve ( newE1, face, Crv1, fp1, lp1, Standard_False )) {
|
||||
if(sae.PCurve ( newE2, face, Crv2, fp2, lp2, Standard_False )) {
|
||||
if(lp1==param) {
|
||||
if( (lp1-fp1)*(lp1-param1)>0 ) {
|
||||
CutEdge(newE1, fp1, param1, face, IsCutLine);
|
||||
CutEdge(newE2, lp2, param2, face, IsCutLine);
|
||||
}
|
||||
else {
|
||||
CutEdge(newE1, fp1, param2, face, IsCutLine);
|
||||
CutEdge(newE2, lp2, param1, face, IsCutLine);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if( (fp1-lp1)*(fp1-param1)>0 ) {
|
||||
CutEdge(newE1, lp1, param1, face, IsCutLine);
|
||||
CutEdge(newE2, fp2, param2, face, IsCutLine);
|
||||
}
|
||||
else {
|
||||
CutEdge(newE1, lp1, param2, face, IsCutLine);
|
||||
CutEdge(newE2, fp2, param1, face, IsCutLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : CutEdge
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_SplitTool::CutEdge(const TopoDS_Edge &edge,
|
||||
const Standard_Real pend,
|
||||
const Standard_Real cut,
|
||||
const TopoDS_Face &face,
|
||||
Standard_Boolean &iscutline) const
|
||||
{
|
||||
if( Abs(cut-pend)<10.*Precision::PConfusion() ) return Standard_False;
|
||||
Standard_Real aRange = Abs(cut-pend);
|
||||
Standard_Real a, b;
|
||||
BRep_Tool::Range(edge, a, b);
|
||||
iscutline = Standard_False;
|
||||
if( aRange<10.*Precision::PConfusion() ) return Standard_False;
|
||||
|
||||
// case pcurve is trimm of line
|
||||
if( !BRep_Tool::SameParameter(edge) ) {
|
||||
ShapeAnalysis_Edge sae;
|
||||
Handle(Geom2d_Curve) Crv;
|
||||
Standard_Real fp,lp;
|
||||
if ( sae.PCurve(edge,face,Crv,fp,lp,Standard_False) ) {
|
||||
if(Crv->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) {
|
||||
Handle(Geom2d_TrimmedCurve) tc = Handle(Geom2d_TrimmedCurve)::DownCast(Crv);
|
||||
if(tc->BasisCurve()->IsKind(STANDARD_TYPE(Geom2d_Line))) {
|
||||
BRep_Builder B;
|
||||
B.Range(edge,Min(pend,cut),Max(pend,cut));
|
||||
if( Abs(pend-lp)<Precision::PConfusion() ) { // cut from the begining
|
||||
Standard_Real cut3d = (cut-fp)*(b-a)/(lp-fp);
|
||||
if(cut3d <= Precision::PConfusion())
|
||||
return Standard_False;
|
||||
B.Range(edge, a+cut3d, b, Standard_True);
|
||||
iscutline = Standard_True;
|
||||
}
|
||||
else if( Abs(pend-fp)<Precision::PConfusion() ) { // cut from the end
|
||||
Standard_Real cut3d = (lp-cut)*(b-a)/(lp-fp);
|
||||
if(cut3d <= Precision::PConfusion())
|
||||
return Standard_False;
|
||||
B.Range(edge, a, b-cut3d, Standard_True);
|
||||
iscutline = Standard_True;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
// det-study on 03/12/01 checking the old and new ranges
|
||||
if( Abs(Abs(a-b)-aRange) < Precision::PConfusion() ) return Standard_False;
|
||||
if( aRange<10.*Precision::PConfusion() ) return Standard_False;
|
||||
|
||||
BRep_Builder B;
|
||||
B.Range( edge, Min(pend,cut), Max(pend,cut) );
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : SplitEdge
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_SplitTool::SplitEdge(const TopoDS_Edge& edge,
|
||||
const Standard_Real fp,
|
||||
const TopoDS_Vertex& V1,
|
||||
const Standard_Real lp,
|
||||
const TopoDS_Vertex& V2,
|
||||
const TopoDS_Face& face,
|
||||
TopTools_SequenceOfShape& SeqE,
|
||||
Standard_Integer& aNum,
|
||||
const Handle(ShapeBuild_ReShape)& context,
|
||||
const Standard_Real tol3d,
|
||||
const Standard_Real tol2d) const
|
||||
{
|
||||
if(fabs(lp-fp)<tol2d)
|
||||
return Standard_False;
|
||||
aNum = 0;
|
||||
SeqE.Clear();
|
||||
BRep_Builder B;
|
||||
Standard_Real a, b;
|
||||
ShapeAnalysis_Edge sae;
|
||||
Handle(Geom2d_Curve) c2d;
|
||||
sae.PCurve(edge,face,c2d,a,b,Standard_True);
|
||||
TopoDS_Vertex VF = sae.FirstVertex(edge);
|
||||
TopoDS_Vertex VL = sae.LastVertex(edge);
|
||||
Standard_Real tolVF = BRep_Tool::Tolerance(VF);
|
||||
Standard_Real tolVL = BRep_Tool::Tolerance(VL);
|
||||
Standard_Real tolV1 = BRep_Tool::Tolerance(V1);
|
||||
Standard_Real tolV2 = BRep_Tool::Tolerance(V2);
|
||||
gp_Pnt PVF = BRep_Tool::Pnt(VF);
|
||||
gp_Pnt PVL = BRep_Tool::Pnt(VL);
|
||||
gp_Pnt PV1 = BRep_Tool::Pnt(V1);
|
||||
gp_Pnt PV2 = BRep_Tool::Pnt(V2);
|
||||
|
||||
Standard_Real par1,par2;
|
||||
Standard_Boolean IsReverse = Standard_False;
|
||||
if( (b-a)*(lp-fp)>0 ) {
|
||||
par1 = fp;
|
||||
par2 = lp;
|
||||
}
|
||||
else {
|
||||
par1 = lp;
|
||||
par2 = fp;
|
||||
IsReverse = Standard_True;
|
||||
}
|
||||
|
||||
if( fabs(a-par1)<=tol2d && fabs(b-par2)<=tol2d ) {
|
||||
if(IsReverse) {
|
||||
Standard_Real newtol = tolVF + PVF.Distance(PV2);
|
||||
if(tolV2<newtol) B.UpdateVertex(V2,newtol);
|
||||
if(VF.Orientation()==V2.Orientation()) {
|
||||
context->Replace(VF,V2);
|
||||
VF = V2;
|
||||
}
|
||||
else {
|
||||
context->Replace(VF,V2.Reversed());
|
||||
VF = TopoDS::Vertex(V2.Reversed());
|
||||
}
|
||||
newtol = tolVL + PVL.Distance(PV1);
|
||||
if(tolV1<newtol) B.UpdateVertex(V1,newtol);
|
||||
if(VL.Orientation()==V1.Orientation()) {
|
||||
context->Replace(VL,V1);
|
||||
VL = V1;
|
||||
}
|
||||
else {
|
||||
context->Replace(VL,V1.Reversed());
|
||||
VL = TopoDS::Vertex(V1.Reversed());
|
||||
}
|
||||
}
|
||||
else {
|
||||
Standard_Real newtol = tolVF + PVF.Distance(PV1);
|
||||
if(tolV1<newtol) B.UpdateVertex(V1,newtol);
|
||||
if(VF.Orientation()==V1.Orientation()) {
|
||||
context->Replace(VF,V1);
|
||||
VF = V1;
|
||||
}
|
||||
else {
|
||||
context->Replace(VF,V1.Reversed());
|
||||
VF = TopoDS::Vertex(V1.Reversed());
|
||||
}
|
||||
newtol = tolVL + PVL.Distance(PV2);
|
||||
if(tolV2<newtol) B.UpdateVertex(V2,newtol);
|
||||
if(VL.Orientation()==V2.Orientation()) {
|
||||
context->Replace(VL,V2);
|
||||
VL = V2;
|
||||
}
|
||||
else {
|
||||
context->Replace(VL,V2.Reversed());
|
||||
VL = TopoDS::Vertex(V2.Reversed());
|
||||
}
|
||||
}
|
||||
SeqE.Append(edge);
|
||||
aNum = 1;
|
||||
}
|
||||
|
||||
if( fabs(a-par1)<=tol2d && fabs(b-par2)>tol2d ) {
|
||||
TopoDS_Edge newE1, newE2;
|
||||
if(IsReverse) {
|
||||
if(!SplitEdge(edge,par2,V1,face,newE1,newE2,tol3d,tol2d))
|
||||
return Standard_False;
|
||||
Standard_Real newtol = tolVF + PVF.Distance(PV2);
|
||||
if(tolV2<newtol) B.UpdateVertex(V2,newtol);
|
||||
if(VF.Orientation()==V2.Orientation()) {
|
||||
context->Replace(VF,V2);
|
||||
VF = V2;
|
||||
}
|
||||
else {
|
||||
context->Replace(VF,V2.Reversed());
|
||||
VF = TopoDS::Vertex(V2.Reversed());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(!SplitEdge(edge,par2,V2,face,newE1,newE2,tol3d,tol2d))
|
||||
return Standard_False;
|
||||
Standard_Real newtol = tolVF + PVF.Distance(PV1);
|
||||
if(tolV1<newtol) B.UpdateVertex(V1,newtol);
|
||||
if(VF.Orientation()==V1.Orientation()) {
|
||||
context->Replace(VF,V1);
|
||||
VF = V1;
|
||||
}
|
||||
else {
|
||||
context->Replace(VF,V1.Reversed());
|
||||
VF = TopoDS::Vertex(V1.Reversed());
|
||||
}
|
||||
}
|
||||
SeqE.Append(newE1);
|
||||
SeqE.Append(newE2);
|
||||
aNum = 1;
|
||||
}
|
||||
|
||||
if( fabs(a-par1)>tol2d && fabs(b-par2)<=tol2d ) {
|
||||
TopoDS_Edge newE1, newE2;
|
||||
if(IsReverse) {
|
||||
if(!SplitEdge(edge,par1,V2,face,newE1,newE2,tol3d,tol2d))
|
||||
return Standard_False;
|
||||
Standard_Real newtol = tolVL + PVL.Distance(PV1);
|
||||
if(tolV1<newtol) B.UpdateVertex(V1,newtol);
|
||||
if(VL.Orientation()==V1.Orientation()) {
|
||||
context->Replace(VL,V1);
|
||||
VL = V1;
|
||||
}
|
||||
else {
|
||||
context->Replace(VL,V1.Reversed());
|
||||
VL = TopoDS::Vertex(V1.Reversed());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(!SplitEdge(edge,par1,V1,face,newE1,newE2,tol3d,tol2d))
|
||||
return Standard_False;
|
||||
Standard_Real newtol = tolVL + PVL.Distance(PV2);
|
||||
if(tolV2<newtol) B.UpdateVertex(V2,newtol);
|
||||
if(VL.Orientation()==V2.Orientation()) {
|
||||
context->Replace(VL,V2);
|
||||
VL = V2;
|
||||
}
|
||||
else {
|
||||
context->Replace(VL,V2.Reversed());
|
||||
VL = TopoDS::Vertex(V2.Reversed());
|
||||
}
|
||||
}
|
||||
SeqE.Append(newE1);
|
||||
SeqE.Append(newE2);
|
||||
aNum = 2;
|
||||
}
|
||||
|
||||
if( fabs(a-par1)>tol2d && fabs(b-par2)>tol2d ) {
|
||||
TopoDS_Edge newE1,newE2,newE3,newE4;
|
||||
if(IsReverse) {
|
||||
if(!SplitEdge(edge,par1,V2,face,newE1,newE2,tol3d,tol2d))
|
||||
return Standard_False;
|
||||
if(!SplitEdge(newE2,par2,V1,face,newE3,newE4,tol3d,tol2d))
|
||||
return Standard_False;
|
||||
}
|
||||
else {
|
||||
if(!SplitEdge(edge,par1,V1,face,newE1,newE2,tol3d,tol2d))
|
||||
return Standard_False;
|
||||
if(!SplitEdge(newE2,par2,V2,face,newE3,newE4,tol3d,tol2d))
|
||||
return Standard_False;
|
||||
}
|
||||
SeqE.Append(newE1);
|
||||
SeqE.Append(newE3);
|
||||
SeqE.Append(newE4);
|
||||
aNum = 2;
|
||||
}
|
||||
|
||||
if(aNum==0) return Standard_False;
|
||||
|
||||
Handle(ShapeExtend_WireData) sewd = new ShapeExtend_WireData;
|
||||
for(Standard_Integer i=1; i<=SeqE.Length(); i++) {
|
||||
sewd->Add(SeqE.Value(i));
|
||||
}
|
||||
context->Replace(edge,sewd->Wire());
|
||||
for (TopExp_Explorer exp ( sewd->Wire(), TopAbs_EDGE ); exp.More(); exp.Next() ) {
|
||||
TopoDS_Edge E = TopoDS::Edge ( exp.Current() );
|
||||
BRepTools::Update(E);
|
||||
}
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
|
868
src/ShapeFix/ShapeFix_Wire.cdl
Executable file
868
src/ShapeFix/ShapeFix_Wire.cdl
Executable file
@@ -0,0 +1,868 @@
|
||||
-- File: ShapeFix_Wire.cdl
|
||||
-- Created: Wed Jun 3 12:33:14 1998
|
||||
-- Author: data exchange team
|
||||
-- <det@nnov.matra-dtv.fr>
|
||||
---Copyright: Matra Datavision 1998
|
||||
|
||||
|
||||
class Wire from ShapeFix inherits Root from ShapeFix
|
||||
|
||||
---Purpose: This class provides a set of tools for repairing a wire.
|
||||
--
|
||||
-- These are methods Fix...(), organised in two levels:
|
||||
--
|
||||
-- Level 1: Advanced - each method in this level fixes one separate problem,
|
||||
-- usually dealing with either single edge or connection of the
|
||||
-- two adjacent edges. These methods should be used carefully and
|
||||
-- called in right sequence, because some of them depend on others.
|
||||
--
|
||||
-- Level 2: Public (API) - methods which group several methods of level 1
|
||||
-- and call them in a proper sequence in order to make some
|
||||
-- consistent set of fixes for a whole wire. It is possible to
|
||||
-- control calls to methods of the advanced level from methods of
|
||||
-- the public level by use of flags Fix..Mode() (see below).
|
||||
--
|
||||
-- Fixes can be made in three ways:
|
||||
-- 1. Increasing tolerance of an edge or a vertex
|
||||
-- 2. Changing topology (adding/removing/replacing edge in the wire
|
||||
-- and/or replacing the vertex in the edge)
|
||||
-- 3. Changing geometry (shifting vertex or adjusting ends of edge
|
||||
-- curve to vertices, or recomputing curves of the edge)
|
||||
--
|
||||
-- When fix can be made in more than one way (e.g., either
|
||||
-- by increasing tolerance or shifting a vertex), it is choosen
|
||||
-- according to the flags:
|
||||
-- ModifyTopologyMode - allows modification of the topology.
|
||||
-- This flag can be set when fixing a wire on
|
||||
-- the separate (free) face, and should be
|
||||
-- unset for face which is part of shell.
|
||||
-- ModifyGeometryMode - allows modification of the geometry.
|
||||
--
|
||||
-- The order of descriptions of Fix() methods in this CDL
|
||||
-- approximately corresponds to the optimal order of calls.
|
||||
--
|
||||
-- NOTE: most of fixing methods expect edges in the
|
||||
-- ShapeExtend_WireData to be ordered, so it is necessary to make
|
||||
-- call to FixReorder() before any other fixes
|
||||
--
|
||||
-- ShapeFix_Wire should be initialized prior to any fix by the
|
||||
-- following data:
|
||||
-- a) Wire (ether TopoDS_Wire or ShapeExtend_Wire)
|
||||
-- b) Face or surface
|
||||
-- c) Precision
|
||||
-- This can be done either by calling corresponding methods
|
||||
-- (LoadWire, SetFace or SetSurface, and SetPrecision), or
|
||||
-- by loading already filled ShapeAnalisis_Wire with method Load
|
||||
|
||||
uses
|
||||
|
||||
Surface from Geom,
|
||||
Face from TopoDS,
|
||||
Vertex from TopoDS,
|
||||
Wire from TopoDS,
|
||||
Location from TopLoc,
|
||||
WireData from ShapeExtend,
|
||||
Status from ShapeExtend,
|
||||
Wire from ShapeAnalysis,
|
||||
WireOrder from ShapeAnalysis,
|
||||
Edge from ShapeFix
|
||||
|
||||
is
|
||||
|
||||
Create returns Wire from ShapeFix;
|
||||
---Purpose: Empty Constructor, creates clear object with default flags
|
||||
|
||||
Create (wire: Wire from TopoDS; face: Face from TopoDS; prec: Real)
|
||||
returns Wire from ShapeFix;
|
||||
---Purpose: Create new object with default flags and prepare it for use
|
||||
-- (Loads analyzer with all the data for the wire and face)
|
||||
|
||||
--- Loading and extracting the wire and other working data:
|
||||
|
||||
ClearModes (me: mutable);
|
||||
---Purpose: Sets all modes to default
|
||||
|
||||
ClearStatuses (me: mutable);
|
||||
---Purpose: Clears all statuses
|
||||
|
||||
Init (me: mutable; wire: Wire from TopoDS;
|
||||
face: Face from TopoDS; prec: Real);
|
||||
---Purpose: Load analyzer with all the data for the wire and face
|
||||
-- and drops all fixing statuses
|
||||
|
||||
Init (me: mutable; saw: Wire from ShapeAnalysis);
|
||||
---Purpose: Load analyzer with all the data already prepared
|
||||
-- and drops all fixing statuses
|
||||
-- If analyzer contains face, there is no need to set it
|
||||
-- by SetFace or SetSurface
|
||||
|
||||
Load (me: mutable; wire: Wire from TopoDS);
|
||||
---Purpose: Load data for the wire, and drops all fixing statuses
|
||||
---Note : It is necessary to set face or surface for the wire before fixes
|
||||
|
||||
Load (me: mutable; sbwd: WireData from ShapeExtend);
|
||||
---Purpose: Load data for the wire, and drops all fixing statuses
|
||||
---Note : It is necessary to set face or surface for the wire before fixes
|
||||
|
||||
SetFace (me: mutable; face: Face from TopoDS);
|
||||
---C++: inline
|
||||
---Purpose: Set working face for the wire
|
||||
|
||||
SetSurface (me: mutable; surf: Surface from Geom);
|
||||
---C++: inline
|
||||
---Purpose: Set surface for the wire
|
||||
---Remark : This function creates new face and calls SetFace
|
||||
|
||||
SetSurface (me: mutable; surf: Surface from Geom;
|
||||
loc: Location from TopLoc);
|
||||
---C++: inline
|
||||
---Purpose: Set surface for the wire
|
||||
---Remark : This function creates new face and calls SetFace
|
||||
|
||||
SetPrecision (me: mutable; prec: Real) is redefined;
|
||||
---Purpose: Set working precision (to root and to analyzer)
|
||||
|
||||
IsLoaded (me) returns Boolean;
|
||||
---C++: inline
|
||||
---Purpose: Tells if the wire is loaded
|
||||
---Remark: returns myAnalyzer.IsLoadaed()
|
||||
|
||||
IsReady (me) returns Boolean;
|
||||
---C++: inline
|
||||
---Purpose: Tells if the wire and face are loaded
|
||||
---Remark: returns myAnalyzer.IsReady()
|
||||
|
||||
NbEdges (me) returns Integer;
|
||||
---Purpose: returns number of edges in the working wire
|
||||
---Remark: returns myAnalyzer.NbEdges()
|
||||
|
||||
Wire (me) returns Wire from TopoDS;
|
||||
---C++: inline
|
||||
---Purpose: Makes the resulting Wire (by basic Brep_Builder)
|
||||
---Remark: returns myAnalyzer.Wire()
|
||||
|
||||
WireAPIMake (me) returns Wire from TopoDS;
|
||||
---C++: inline
|
||||
---Purpose: Makes the resulting Wire (by BRepAPI_MakeWire)
|
||||
---Remark: returns myAnalyzer.WireAPIMake()
|
||||
|
||||
Analyzer (me) returns Wire from ShapeAnalysis;
|
||||
---Purpose: returns field Analyzer (working tool)
|
||||
|
||||
WireData (me) returns WireData from ShapeExtend;
|
||||
---C++: inline
|
||||
---C++: return const &
|
||||
---Purpose: returns working wire
|
||||
---Remark: calls Analyzer.WireData()
|
||||
|
||||
Face (me) returns Face from TopoDS;
|
||||
---C++: inline
|
||||
---C++: return const &
|
||||
---Purpose: returns working face (Analyzer.Face())
|
||||
|
||||
--- Parameters:
|
||||
|
||||
ModifyTopologyMode (me: mutable) returns Boolean;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
---Purpose: Returns (modifiable) the flag which defines whether it is
|
||||
-- allowed to modify topology of the wire during fixing
|
||||
-- (adding/removing edges etc.)
|
||||
---Use : This flag can be set to True for wire on separate (free) face.
|
||||
-- It should be set to False if the wire is on face which is a part
|
||||
-- of a shell.
|
||||
---Default: False
|
||||
|
||||
ModifyGeometryMode (me: mutable) returns Boolean;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
---Purpose: Returns (modifiable) the flag which defines whether the Fix..()
|
||||
-- methods are allowed to modify geometry of the edges and vertices
|
||||
---Default: True
|
||||
---Remark : Currently is not used
|
||||
|
||||
ModifyRemoveLoopMode (me: mutable) returns Integer;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
---Purpose: Returns (modifiable) the flag which defines whether the Fix..()
|
||||
-- methods are allowed to modify RemoveLoop of the edges
|
||||
---Default: -1
|
||||
---Remark : Currently is not used
|
||||
|
||||
ClosedWireMode (me: mutable) returns Boolean;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
---Purpose: Returns (modifiable) the flag which defines whether the wire
|
||||
-- is to be closed (by calling methods like FixDegenerated()
|
||||
-- and FixConnected() for last and first edges).
|
||||
---Use : This flag should be set to False if wire is not a face boundary
|
||||
-- but is a (not closed) curve on a face.
|
||||
---Default: True
|
||||
|
||||
PreferencePCurveMode (me: mutable) returns Boolean;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
---Purpose: Returns (modifiable) the flag which defines whether the 2d (True)
|
||||
-- representation of the wire is preferable over 3d one (in the
|
||||
-- case of ambiguity in FixEdgeCurves).
|
||||
---Default: True (means that 2d representation is preferable).
|
||||
---Remark : Currently is not used
|
||||
|
||||
FixGapsByRangesMode (me: mutable) returns Boolean;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
---Purpose: Returns (modifiable) the flag which defines whether tool
|
||||
-- tries to fix gaps first by changing curves ranges (i.e.
|
||||
-- using intersection, extrema, projections) or not.
|
||||
---Default: False (means that tool will only bend curves).
|
||||
---Remark : Currently is not used
|
||||
|
||||
--- Flags:
|
||||
|
||||
--- Level: Public (API)
|
||||
-- These flags are only used in Perform()
|
||||
FixReorderMode (me: mutable) returns Integer;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
FixSmallMode (me: mutable) returns Integer;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
FixConnectedMode (me: mutable) returns Integer;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
FixEdgeCurvesMode (me: mutable) returns Integer;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
FixDegeneratedMode (me: mutable) returns Integer;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
FixSelfIntersectionMode (me: mutable) returns Integer;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
FixLackingMode (me: mutable) returns Integer;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
FixGaps3dMode (me: mutable) returns Integer;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
FixGaps2dMode (me: mutable) returns Integer;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
---Purpose: Returns (modifiable) the flag for corresponding Fix..() method
|
||||
-- which defines whether this method will be called from the
|
||||
-- method APIFix():
|
||||
-- -1 default
|
||||
-- 1 method will be called
|
||||
-- 0 method will not be called
|
||||
|
||||
--- Level: Advanced:
|
||||
-- These flags are only used in FixEdgeCurves() and FixSelfIntersection()
|
||||
-- For FixEdgeCurves():
|
||||
FixReversed2dMode (me: mutable) returns Integer;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
FixRemovePCurveMode (me: mutable) returns Integer;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
FixAddPCurveMode (me: mutable) returns Integer;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
FixRemoveCurve3dMode (me: mutable) returns Integer;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
FixAddCurve3dMode (me: mutable) returns Integer;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
FixSeamMode (me: mutable) returns Integer;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
FixShiftedMode (me: mutable) returns Integer;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
FixSameParameterMode (me: mutable) returns Integer;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
FixVertexToleranceMode (me: mutable) returns Integer;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
-- For FixSelfIntersection():
|
||||
FixNotchedEdgesMode (me: mutable) returns Integer;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
FixSelfIntersectingEdgeMode (me: mutable) returns Integer;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
FixIntersectingEdgesMode (me: mutable) returns Integer;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
FixNonAdjacentIntersectingEdgesMode (me: mutable) returns Integer;
|
||||
---C++: inline
|
||||
---C++: return &
|
||||
---Purpose: Returns (modifiable) the flag for corresponding Fix..() method
|
||||
-- which defines whether this method will be called from the
|
||||
-- corresponding Fix..() method of the public level:
|
||||
-- -1 default
|
||||
-- 1 method will be called
|
||||
-- 0 method will not be called
|
||||
|
||||
--- Fixing methods:
|
||||
|
||||
--- Level: Public (API)
|
||||
|
||||
Perform (me: mutable) returns Boolean;
|
||||
---Purpose: This method performs all the available fixes.
|
||||
-- If some fix is turned on or off explicitly by the Fix..Mode() flag,
|
||||
-- this fix is either called or not depending on that flag.
|
||||
-- Else (i.e. if flag is default) fix is called depending on the
|
||||
-- situation: some fixes are not called or are limited if order of
|
||||
-- edges in the wire is not OK, or depending on modes
|
||||
--
|
||||
-- The order of the fixes and default behaviour of Perform() are:
|
||||
-- FixReorder
|
||||
-- FixSmall (with lockvtx true if ! TopoMode or if wire is not ordered)
|
||||
-- FixConnected (if wire is ordered)
|
||||
-- FixEdgeCurves (without FixShifted if wire is not ordered)
|
||||
-- FixDegenerated (if wire is ordered)
|
||||
-- FixSelfIntersection (if wire is ordered and ClosedMode is True)
|
||||
-- FixLacking (if wire is ordered)
|
||||
--
|
||||
---Returns: False if nothing done, else True
|
||||
-- Use methods Status...() to investigate the results of calls to the
|
||||
-- each fixing method. All statuses are dropped at the start of Perform().
|
||||
|
||||
FixReorder (me: mutable) returns Boolean;
|
||||
---Purpose: Performs an analysis and reorders edges in the wire using
|
||||
-- class WireOrder
|
||||
---Returns: False if nothing to do, True if some edges were reordered
|
||||
---Status : See StatusReorder() for details
|
||||
-- FAIL1 - ShapeAnalysis_WireOrder has detected several loops
|
||||
-- FAIL2 - ShapeAnalysis_WireOrder failed (result is incorrect)
|
||||
-- DONE1 - Reorder done OK
|
||||
-- DONE2 - in addition to DONE1 - some gaps remain
|
||||
-- DONE3 - in addition to DONE1 - some edges were reversed
|
||||
|
||||
FixSmall (me: mutable; lockvtx: Boolean; precsmall: Real = 0.0)
|
||||
returns Integer;
|
||||
---Purpose: Applies FixSmall(num) to all edges in the wire
|
||||
---Returns: True if some edges were removed, else False
|
||||
---Status : See StatusSmall() for details
|
||||
-- OK : Edge is not null-length
|
||||
-- DONE1: Edge is null-length and has the same vertices at begin
|
||||
-- and end; removed
|
||||
-- DONE2: (only if lockvtx is False and ModifyTopologyMode is True)
|
||||
-- Edge is null-length and has different vertices at begin and end;
|
||||
-- edge removed, and CheckConnected called for adjacent edges
|
||||
-- FAIL1: Edge cannot be checked (no 3d curve and no pcurve)
|
||||
-- FAIL2: Edge is null-length and has different vertices at begin
|
||||
-- and end, and lockvtx is True or ModifyTopologyMode is False;
|
||||
-- edge is not removed
|
||||
-- FAIL3: In the case of DONE2, CheckConnected has failed
|
||||
|
||||
FixConnected (me: mutable; prec: Real = -1.0) returns Boolean;
|
||||
---Purpose: Applies FixConnected(num) to all edges in the wire
|
||||
-- Connection between first and last edges is treated only if
|
||||
-- flag ClosedMode is True
|
||||
-- If <prec> is -1 then MaxTolerance() is taken.
|
||||
---Returns: True if some vertices were replaced, False if OK or fail
|
||||
---Status : See StatusConnected() for details
|
||||
-- OK : If they are already the same, nothing done
|
||||
-- DONE1: Absolutely confused (gp::Resolution), set the same
|
||||
-- DONE2: Confused with Analyzer.Precision(), set the same
|
||||
-- DONE3: Confused with <prec> but not Analyzer.Precision(), set the same
|
||||
-- FAIL1: Not confused neither with prec nor Analyzer.Precision()
|
||||
|
||||
FixEdgeCurves (me: mutable) returns Boolean;
|
||||
---Purpose: Groups the fixes dealing with 3d and pcurves of the edges.
|
||||
-- The order of the fixes and the default behaviour are:
|
||||
-- ShapeFix_Edge::FixReversed2d
|
||||
-- ShapeFix_Edge::FixRemovePCurve (only if forced)
|
||||
-- ShapeFix_Edge::FixAddPCurve
|
||||
-- ShapeFix_Edge::FixRemoveCurve3d (only if forced)
|
||||
-- ShapeFix_Edge::FixAddCurve3d
|
||||
-- FixSeam,
|
||||
-- FixShifted,
|
||||
-- ShapeFix_Edge::FixSameParameter
|
||||
---Returns: False if nothing done, else True
|
||||
---Status : See StatusEdgeCurves() for details
|
||||
-- OK - no problem was detected, nothing fixed
|
||||
-- DONE1, FAIL1 - FixReversed2d was fixed and/or failed
|
||||
-- DONE2, FAIL2 - FixRemovePCurve was fixed and/or failed
|
||||
-- DONE3, FAIL3 - FixAddPCurve was fixed and/or failed
|
||||
-- DONE4, FAIL4 - FixRemoveCurve3d was fixed and/or failed
|
||||
-- DONE5, FAIL5 - FixAddCurve3d was fixed and/or failed
|
||||
-- DONE6, FAIL6 - FixSeam was fixed and/or failed
|
||||
-- DONE7, FAIL7 - FixShifted was fixed and/or failed
|
||||
-- DONE8, FAIL8 - FixSameParameter or FixVertexTolerance were fixed and/or failed
|
||||
|
||||
FixDegenerated (me: mutable) returns Boolean;
|
||||
---Purpose: Applies FixDegenerated(num) to all edges in the wire
|
||||
-- Connection between first and last edges is treated only if
|
||||
-- flag ClosedMode is True
|
||||
---Returns: True if at least one degenerated edge was fixed or added
|
||||
---Status : See StatusDegenerated() for details
|
||||
-- OK : Nothing done
|
||||
-- FAIL1: Analysis has failed
|
||||
-- DONE1: New degenerated edge was added
|
||||
-- DONE2: Edge <num> was made degenerated
|
||||
|
||||
FixSelfIntersection ( me: mutable ) returns Boolean;
|
||||
---Purpose: Applies FixSelfIntersectingEdge(num) and
|
||||
-- FixIntersectingEdges(num) to all edges in the wire and
|
||||
-- FixIntersectingEdges(num1, num2) for all pairs num1 and num2
|
||||
-- such that num2 >= num1 + 2
|
||||
-- and removes wrong edges if any
|
||||
---Returns: True if something was fixed, else False
|
||||
---Status : See StatusSelfIntersection() for details
|
||||
-- OK : No intersection found
|
||||
-- FAIL1: analysis failed (edge has no pcurve, or no vertices etc.)
|
||||
-- FAIL2: self-intersection was found, but not fixed because of
|
||||
-- limit of increasing tolerance (MaxTolerance)
|
||||
-- FAIL3: intercestion of non adjacent edges found, but not fixed
|
||||
-- because of limit of increasing tolerance (MaxTolerance)
|
||||
-- DONE1: tolerance of vertex was increased to fix self-intersection
|
||||
-- DONE2: vertex was moved to fix self-intersection
|
||||
-- DONE3: some edges were removed because of intersection
|
||||
-- DONE4: pcurve(s) was(were) modified
|
||||
-- DONE5: non adjacent intersection fixed by increasing tolerance of
|
||||
-- vertex(vertices)
|
||||
-- DONE6: tolerance of edge was increased to hide intersection
|
||||
-- DONE7: range of some edges was decreased to avoid intersection
|
||||
|
||||
FixLacking (me: mutable; force: Boolean = Standard_False) returns Boolean;
|
||||
---Purpose: Applies FixLacking(num) to all edges in the wire
|
||||
-- Connection between first and last edges is treated only if
|
||||
-- flag ClosedMode is True
|
||||
-- If <force> is False (default), test for connectness is done with
|
||||
-- precision of vertex between edges, else it is done with minimal
|
||||
-- value of vertex tolerance and Analyzer.Precision().
|
||||
-- Hence, <force> will lead to inserting lacking edges in replacement
|
||||
-- of vertices which have big tolerances.
|
||||
---Returns: True if lacking edge was fixed, else False.
|
||||
---Status : See StatusLacking() for more details
|
||||
-- OK : No problems detected
|
||||
-- FAIL1: analysis failed (edge has no pcurve, or no vertices etc.)
|
||||
-- FAIL2: lacking edge not fixed because of
|
||||
-- limit of increasing tolerance (MaxTolerance)
|
||||
-- FAIL3: failed to build lacking edge (3d curve)
|
||||
-- DONE1: tolerance was increased to fix lacking edge
|
||||
-- DONE2: lacking edge was inserted
|
||||
|
||||
FixClosed (me: mutable; prec: Real = -1.0) returns Boolean;
|
||||
---Purpose: Fixes a wire to be well closed
|
||||
-- It performs FixConnected, FixDegenerated and FixLacking between
|
||||
-- last and first edges (independingly on flag ClosedMode and modes
|
||||
-- for these fixings)
|
||||
-- If <prec> is -1 then MaxTolerance() is taken.
|
||||
---Returns: False if nothing done, else True
|
||||
---Status : See StatusClosed() for details
|
||||
-- OK - no problem was detected, nothing fixed
|
||||
-- DONE1, FAIL1 - FixConnected was fixed and/or failed
|
||||
-- DONE2, FAIL2 - FixDegenerated was fixed and/or failed
|
||||
-- DONE3, FAIL3 - FixLacking was fixed and/or failed
|
||||
|
||||
FixGaps3d (me: mutable) returns Boolean;
|
||||
---Purpose: Fixes gaps between ends of 3d curves on adjacent edges
|
||||
-- myPrecision is used to detect the gaps.
|
||||
---Returns: False if nothing done, else True
|
||||
---Status : See StatusGaps3d() for details
|
||||
-- OK - no problem was detected, nothing fixed
|
||||
-- DONE1 - Some gaps in 3d were found and fixed
|
||||
-- FAIL1 - There was no 3d curve found on some edges
|
||||
-- FAIL2 - Method failed to fix some gaps
|
||||
|
||||
FixGaps2d (me: mutable) returns Boolean;
|
||||
---Purpose: Fixes gaps between ends of pcurves on adjacent edges
|
||||
-- myPrecision is used to detect the gaps.
|
||||
---Returns: False if nothing done, else True
|
||||
---Status : See StatusGaps2d() for details
|
||||
-- OK - no problem was detected, nothing fixed
|
||||
-- DONE1 - Some gaps in 2d were found and fixed
|
||||
-- FAIL1 - There was no pcurve found on some edges
|
||||
-- FAIL2 - Method failed to fix some gaps
|
||||
|
||||
--- Level: Advanced
|
||||
|
||||
---Status: For analyzing the status of the last performed method use
|
||||
-- LastFixStatus(status)
|
||||
--
|
||||
-- All the Fix.. methods below return False if the problem was not
|
||||
-- fixed, in this case LastFixStatus contains either FAIL or OK.
|
||||
-- If a method returns True the LastFixStatus contains DONE,
|
||||
-- this means that some fix was made
|
||||
-- For detailed meaning of Status see corresponding method.
|
||||
|
||||
FixReorder (me: mutable; wi: in WireOrder from ShapeAnalysis) returns Boolean;
|
||||
---Purpose: Reorder edges in the wire as determined by WireOrder
|
||||
-- that should be filled and computed before
|
||||
---Returns: False if nothing to do, True if some edges were reordered
|
||||
---Status : See LastFixStatus() for details
|
||||
-- OK - edges are ordered well
|
||||
-- FAIL1 - WireOrder has detected several loops
|
||||
-- FAIL2 - WireOrder is incorrect (wrong number of edges)
|
||||
-- FAIL3 - WireOrder is incorrect
|
||||
-- DONE1 - reorder was performed successfully
|
||||
|
||||
FixSmall (me: mutable; num: Integer; lockvtx: Boolean; precsmall: Real)
|
||||
returns Boolean;
|
||||
---Purpose: Fixes Null Length Edge to be removed
|
||||
-- If an Edge has Null Length (regarding preci, or <precsmall>
|
||||
-- - what is smaller), it should be removed
|
||||
-- It can be with no problem if its two vertices are the same
|
||||
-- Else, if lockvtx is False, it is removed and its end vertex
|
||||
-- is put on the preceeding edge
|
||||
-- But if lockvtx is True, this edge must be kept ...
|
||||
---Use : Is to be used in the case if some edges can be too short, and
|
||||
-- should be removed (hence, if topology of the wire can be modified).
|
||||
-- It is recommended to call this method before FixIntersection()
|
||||
--
|
||||
---Returns: True if null edge was removed, False if nothing done
|
||||
---Status : See LastFixStatus() for details
|
||||
-- OK : Edge is not null-length
|
||||
-- DONE1: Edge is null-length and has the same vertices at begin
|
||||
-- and end; removed
|
||||
-- DONE2: (only if lockvtx is False and ModifyTopologyMode is True)
|
||||
-- Edge is null-length and has different vertices at begin and end;
|
||||
-- edge removed, and CheckConnected called for adjacent edges
|
||||
-- FAIL1: Edge cannot be checked (no 3d curve and no pcurve)
|
||||
-- FAIL2: Edge is null-length and has different vertices at begin
|
||||
-- and end, and lockvtx is True or ModifyTopologyMode is False;
|
||||
-- edge is not removed
|
||||
-- FAIL3: In the case of DONE2, CheckConnected has failed
|
||||
|
||||
FixConnected (me: mutable; num: Integer; prec: Real)
|
||||
returns Boolean;
|
||||
---Purpose: Fixes connected edges (preceeding and current)
|
||||
-- Forces Vertices (end of preceeding-begin of current) to be
|
||||
-- the same one
|
||||
-- Tests with starting preci or, if given greater, <prec>
|
||||
-- If <prec> is -1 then MaxTolerance() is taken.
|
||||
--
|
||||
---Use : It is to be used if two consequent edges in the wire have not
|
||||
-- the same common vertex, e.g., if wire was constructed from
|
||||
-- not connected edges or some operations like adding/removing an
|
||||
-- edge were done.
|
||||
-- While it may change vertices, it should not be
|
||||
-- called in cases when vertices may not be changed ...
|
||||
--
|
||||
---Remark : Replacement of vertices in the edges is made by copying these edges
|
||||
--
|
||||
---Returns: False if edges are already connected (vertices are the same) or if
|
||||
-- it is not possible to perform fix (edges have a gap more than <prec>);
|
||||
-- True if disconnected situation was fixed by producing a new Vertex
|
||||
-- at the middle of the former ones.
|
||||
---Status:
|
||||
-- OK : If they are already the same, nothing done
|
||||
-- DONE1: Absolutely confused (gp::Resolution), set the same
|
||||
-- DONE2: Confused with Analyzer.Precision(), set the same
|
||||
-- DONE3: Confused with <prec> but not Analyzer.Precision(), set the same
|
||||
-- FAIL1: Not confused neither with prec nor Analyzer.Precision()
|
||||
|
||||
FixSeam (me: mutable; num: Integer) returns Boolean;
|
||||
---Purpose: Fixes a seam edge
|
||||
-- A Seam edge has two pcurves, one for forward. one for reversed
|
||||
-- The forward pcurve must be set as first
|
||||
--
|
||||
-- NOTE that correct order of pcurves in the seam edge depends on
|
||||
-- its orientation (i.e., on orientation of the wire, method of
|
||||
-- exploration of edges etc.).
|
||||
-- Since wire represented by the ShapeExtend_WireData is always forward
|
||||
-- (orientation is accounted by edges), it will work correct if:
|
||||
-- 1. Wire created from ShapeExtend_WireData with methods
|
||||
-- ShapeExtend_WireData::Wire..() is added into the FORWARD face
|
||||
-- (orientation can be applied later)
|
||||
-- 2. Wire is extracted from the face with orientation not composed
|
||||
-- with orientation of the face
|
||||
--
|
||||
---Use : This operation should be called after reversing the wire if it
|
||||
-- contains seam edges.
|
||||
--
|
||||
---Returns: True if edge is a seam and its curves were fixed (reordered), else False
|
||||
---Status : See StatusSeam() for details
|
||||
-- OK - edge is not a seam or has pcurves OK
|
||||
-- DONE1 - seam pcurves were fixed
|
||||
|
||||
FixShifted (me: mutable) returns Boolean;
|
||||
---Purpose: Fixes edges which have pcurves shifted by whole parameter
|
||||
-- range on the closed surface (the case may occur if pcurve
|
||||
-- of edge was computed by projecting 3d curve, which goes
|
||||
-- along the seam).
|
||||
-- It compares each two consequent edges and tries to connect them
|
||||
-- if distance between ends is near to range of the surface.
|
||||
-- It also can detect and fix the case if all pcurves are connected,
|
||||
-- but lie out of parametric bounds of the surface.
|
||||
-- In addition to FixShifted from ShapeFix_Wire, more
|
||||
-- sophisticated check of degenerate points is performed,
|
||||
-- and special cases like sphere given by two meridians
|
||||
-- are treated.
|
||||
---Use : Is to be used if some pcurves were recomputed.
|
||||
-- It is recommended to use it before FixDegenerated.
|
||||
---Returns: False if nothing done, else True
|
||||
---Status : See StatusShifted() for details
|
||||
-- OK: If pcurves are OK
|
||||
-- FAIL1: some pcurves are missing
|
||||
-- DONE1: some pcurves were shifted in order to ensure connection
|
||||
-- between edges
|
||||
-- DONE2: all pcurves were shifted in order to be in the parametric
|
||||
-- range of a surface
|
||||
|
||||
FixDegenerated (me: mutable; num: Integer) returns Boolean;
|
||||
---Purpose: Fixes Degenerated Edge
|
||||
-- Checks an <num-th> edge or a point between <num>th-1 and <num>th
|
||||
-- edges for a singularity on a supporting surface.
|
||||
-- If singularity is detected, either adds new degenerated edge
|
||||
-- (before <num>th), or makes <num>th edge to be degenerated.
|
||||
---Use : It is to be called for faces which lie on surfaces with
|
||||
-- singularities.
|
||||
-- It should be called after all pcurves are correctly computed.
|
||||
---Returns: False if nothing done, else True
|
||||
---Status : See LastFixStatus() for details
|
||||
-- OK : Nothing done
|
||||
-- FAIL1: Analysis has failed
|
||||
-- DONE1: New degenerated edge was added
|
||||
-- DONE2: Edge <num> was made degenerated
|
||||
-- DONE3: Edge <num> was incorrectly coded as degenerated, removed
|
||||
|
||||
FixSelfIntersectingEdge ( me: mutable; num: Integer )
|
||||
returns Boolean is private;
|
||||
---Purpose: Detect and fix self-intersecting pcurve of edge <num>.
|
||||
-- Fix is made by one of two methods:
|
||||
-- - cut out the self-intersection loop on pcurve (thus
|
||||
-- producing C0 pcurve). This also increases tolerance of edge
|
||||
-- in order to satisfy SameParameter requirement.
|
||||
-- - increase tolerance of the vertex of edge nearest to the
|
||||
-- self-intersection point so that it comprises that point.
|
||||
-- The first method is considered only if ModifyGeometryMode
|
||||
-- is True. In that case, the method which requires less
|
||||
-- increasing of tolerance is selected.
|
||||
---Returns: True if it was done, else False
|
||||
---Status : See LastFixStatus() for details
|
||||
-- OK : Edge is not self-intersecting
|
||||
-- FAIL1: analysis failed (edge has no pcurve, or no vertices etc.)
|
||||
-- FAIL2: self-intersection was found, but not fixed because of
|
||||
-- limit of increasing tolerance (MaxTolerance)
|
||||
-- DONE1: tolerance was increased to fix self-intersection
|
||||
-- DONE4: pcurve was modified (self-intersection loop cutted out)
|
||||
|
||||
FixIntersectingEdges ( me: mutable; num: Integer )
|
||||
returns Boolean is private;
|
||||
---Purpose: Test if two consequent edges are intersecting and fix it
|
||||
-- by increasing of tolerance of vertex between edges,
|
||||
-- shifting this vertex to the point of intersection,
|
||||
-- cutting edges to the intersection point.
|
||||
-- It also can give signal to remove edge if it whole is cut by
|
||||
-- intersection (if flag ModifyTopologyMode is set).
|
||||
--
|
||||
---Returns: False if nothing done, True if something was fixed.
|
||||
---Status : See LastFixStatus() for details
|
||||
-- OK : No intersection found
|
||||
-- FAIL1: analysis failed (edge has no pcurve, or no vertices etc.)
|
||||
-- FAIL2: self-intersection was found, but not fixed because of
|
||||
-- limit of increasing tolerance (MaxTolerance)
|
||||
-- DONE1: tolerance was increased to fix self-intersection
|
||||
-- DONE2: vertex was moved to fix self-intersection
|
||||
-- DONE3: previous or
|
||||
-- DONE4: current edge should be removed because of intersection
|
||||
-- DONE6: tolerance of edge was increased to hide intersection
|
||||
-- DONE7: range of some edges was decreased to avoid intersection
|
||||
|
||||
FixIntersectingEdges (me: mutable; num1 : Integer;
|
||||
num2 : Integer)
|
||||
returns Boolean is private;
|
||||
---Purpose: Tests if two edges <num1> and <num2> are intersecting and
|
||||
-- fix intersection by increasing of tolerance of vertex
|
||||
-- nearest to the point of intersection.
|
||||
--
|
||||
---Returns: False if nothing done, True if something was fixed.
|
||||
---Status : See LastFixStatus() for details
|
||||
-- OK : No intersection found
|
||||
-- FAIL1: analysis failed (edge has no pcurve, or no vertices etc.)
|
||||
-- FAIL2: self-intersection was found, but not fixed because of
|
||||
-- limit of increasing tolerance (MaxTolerance)
|
||||
-- DONE1: tolerance was increased to fix self-intersection
|
||||
|
||||
FixLacking ( me: mutable; num: Integer; force: Boolean = Standard_False )
|
||||
returns Boolean;
|
||||
---Purpose: Fixes Lacking Edge
|
||||
-- Test if two adjucent edges are disconnected in 2d (while
|
||||
-- connected in 3d), and in that case either increase tolerance
|
||||
-- of the vertex or add a new edge (straight in 2d space), in
|
||||
-- order to close wire in 2d.
|
||||
-- Returns True if edge was added or tolerance was increased.
|
||||
---Algorithm:
|
||||
-- 1. Compute the 2d gap between edges and calculate a tolerance
|
||||
-- which should have vertex in order to comprise the gap
|
||||
-- (using GeomAdaptor_Surface); computed value is inctol
|
||||
-- 2. If inctol < tol of vertex, return False (everything is OK)
|
||||
-- 3. If inctol < Precision, just increase tolerance of vertex to inctol
|
||||
-- 4. Else (if both edges are not degenerated) try to add new edge
|
||||
-- with straight pcurve (in order to close the gap):
|
||||
-- a) if flag MayEdit is False
|
||||
-- 1. if inctol < MaxTolerance, increase tolerance of vertex to inctol
|
||||
-- 2. else try to add degenerated edge (check that middle point of
|
||||
-- that pcurve is inside the vertex)
|
||||
-- b) if MayEdit is True
|
||||
-- 1. try to replace big vertex with two new small vertices
|
||||
-- connected by new edge. This is made if there is a 3d space
|
||||
-- between ends of adjacent edges.
|
||||
-- 2. if inctol < MaxTolerance, increase tolerance of vertex to inctol
|
||||
-- 3. else add either degenerated or closed edge (if middle point
|
||||
-- of a pcurve of a new edge is inside the vertex, then
|
||||
-- degenerated edge is added, else new edge is closed).
|
||||
-- 5. If new edge cannot be added, but inctol < MaxTolerance,
|
||||
-- when increase tolerance of vertex to a value of inctol
|
||||
--
|
||||
---Use : This method should be used after all pcurves in the wire are
|
||||
-- correctly computed. It is not recommended to use this method
|
||||
-- after FixDegenerated() and before FixSelfIntersection().
|
||||
--
|
||||
---Returns: False if nothing done, else True.
|
||||
---Status : See LastFixStatus() for more details
|
||||
-- OK : If nothing done
|
||||
-- FAIL1: analysis failed (edge has no pcurve, or no vertices etc.)
|
||||
-- FAIL2: lacking edge not fixed because of
|
||||
-- limit of increasing tolerance (MaxTolerance)
|
||||
-- FAIL3: failed to build lacking edge (3d curve)
|
||||
-- DONE1: tolerance was increased to fix lacking edge
|
||||
-- DONE2: lacking edge was inserted
|
||||
-- DONE3: (in addition to DONE2) inserted edge is degenerated
|
||||
-- DONE4: (in addition to DONE2) inserted edge is closed
|
||||
-- DONE5: pcurves of edges were bent (only if ModifyGeometry is True)
|
||||
|
||||
FixNotchedEdges(me: mutable) returns Boolean;
|
||||
|
||||
FixDummySeam(me: mutable; num: Integer) is private;
|
||||
|
||||
FixGap3d ( me: mutable; num: Integer; convert: Boolean = Standard_False )
|
||||
returns Boolean;
|
||||
---Purpose: Fixes gap between ends of 3d curves on num-1 and num-th edges.
|
||||
-- myPrecision is used to detect the gap.
|
||||
-- If convert is True, converts curves to bsplines to bend.
|
||||
---Algorithm:
|
||||
---Returns: False if nothing done, else True
|
||||
---Status : See StatusGaps3d() for details
|
||||
-- OK - no problem was detected, nothing fixed
|
||||
-- DONE1 - A gap in 3d were found and fixed
|
||||
-- FAIL1 - There was no 3d curve found on some edge
|
||||
-- FAIL2 - Method failed to fix the gap
|
||||
|
||||
FixGap2d ( me: mutable; num: Integer; convert: Boolean = Standard_False )
|
||||
returns Boolean;
|
||||
---Purpose: Fixes gap between ends of pcurves on num-1 and num-th edges.
|
||||
-- myPrecision is used to detect the gap.
|
||||
-- If convert is True, converts pcurves to bsplines to bend.
|
||||
---Algorithm:
|
||||
---Returns: False if nothing done, else True
|
||||
---Status : See StatusGaps2d() for details
|
||||
-- OK - no problem was detected, nothing fixed
|
||||
-- DONE1 - A gap in 2d were found and fixed
|
||||
-- FAIL1 - There was no pcurve found on some edge
|
||||
-- FAIL2 - Method failed to fix the gap
|
||||
|
||||
--- Result of fixes:
|
||||
|
||||
StatusReorder (me; status: Status from ShapeExtend) returns Boolean;
|
||||
---C++: inline
|
||||
StatusSmall (me; status: Status from ShapeExtend) returns Boolean;
|
||||
---C++: inline
|
||||
StatusConnected (me; status: Status from ShapeExtend) returns Boolean;
|
||||
---C++: inline
|
||||
StatusEdgeCurves (me; status: Status from ShapeExtend) returns Boolean;
|
||||
---C++: inline
|
||||
StatusDegenerated (me; status: Status from ShapeExtend) returns Boolean;
|
||||
---C++: inline
|
||||
StatusSelfIntersection (me; status: Status from ShapeExtend) returns Boolean;
|
||||
---C++: inline
|
||||
StatusLacking (me; status: Status from ShapeExtend) returns Boolean;
|
||||
---C++: inline
|
||||
StatusClosed (me; status: Status from ShapeExtend) returns Boolean;
|
||||
---C++: inline
|
||||
StatusGaps3d (me; status: Status from ShapeExtend) returns Boolean;
|
||||
---C++: inline
|
||||
StatusGaps2d (me; status: Status from ShapeExtend) returns Boolean;
|
||||
---C++: inline
|
||||
StatusNotches (me; status: Status from ShapeExtend) returns Boolean;
|
||||
---C++: inline
|
||||
StatusRemovedSegment (me) returns Boolean;
|
||||
---C++: inline
|
||||
---Purpose: Querying the status of perfomed API fixing procedures
|
||||
-- Each Status..() methods gives information about the last call to
|
||||
-- the corresponding Fix..() method of API level:
|
||||
-- OK : no problems detected; nothing done
|
||||
-- DONE: some problem(s) was(were) detected and successfully fixed
|
||||
-- FAIL: some problem(s) cannot be fixed
|
||||
---Level : Public (API)
|
||||
LastFixStatus (me; status: Status from ShapeExtend) returns Boolean;
|
||||
---C++: inline
|
||||
---Purpose: Queries the status of last call to methods Fix... of
|
||||
-- advanced level
|
||||
-- For details see corresponding methods; universal statuses are:
|
||||
-- OK : problem not detected; nothing done
|
||||
-- DONE: problem was detected and successfully fixed
|
||||
-- FAIL: problem cannot be fixed
|
||||
---Level : Advanced
|
||||
|
||||
FixEdgeTool (me) returns Edge from ShapeFix;
|
||||
---Purpose: Returns tool for fixing wires.
|
||||
---C++: inline
|
||||
|
||||
UpdateWire (me: mutable) is protected;
|
||||
---Purpose: Updates WireData if some replacements are made
|
||||
-- This is necessary for wires (unlike other shape types)
|
||||
-- since one edge can present in wire several times
|
||||
|
||||
fields
|
||||
|
||||
myFixEdge : Edge from ShapeFix is protected;
|
||||
myAnalyzer: Wire from ShapeAnalysis is protected; -- working analyzer
|
||||
|
||||
myGeomMode: Boolean is protected; -- may change geometry
|
||||
myTopoMode: Boolean is protected; -- may change topology
|
||||
myClosedMode: Boolean is protected; -- should wire be closed?
|
||||
myPreference2d: Boolean is protected; -- is 2d representation of edge preferred
|
||||
myFixGapsByRanges: Boolean is protected; -- try to fix gaps by changing curves ranges
|
||||
|
||||
myFixReversed2dMode: Integer is protected;
|
||||
myFixRemovePCurveMode: Integer is protected;
|
||||
myFixAddPCurveMode: Integer is protected;
|
||||
myFixRemoveCurve3dMode: Integer is protected;
|
||||
myFixAddCurve3dMode: Integer is protected;
|
||||
myFixSeamMode: Integer is protected;
|
||||
myFixShiftedMode: Integer is protected;
|
||||
myFixSameParameterMode: Integer is protected;
|
||||
myFixVertexToleranceMode: Integer is protected;
|
||||
myFixNotchedEdgesMode: Integer is protected;
|
||||
myFixSelfIntersectingEdgeMode: Integer is protected;
|
||||
myFixIntersectingEdgesMode: Integer is protected;
|
||||
myFixNonAdjacentIntersectingEdgesMode: Integer is protected;
|
||||
|
||||
myRemoveLoopMode: Integer is protected;
|
||||
-- -1 - old variant (default)
|
||||
-- 0 - try remove both 2d loop and 3d loop
|
||||
-- 1 - try insert new vertex
|
||||
|
||||
myFixReorderMode: Integer is protected;
|
||||
myFixSmallMode: Integer is protected;
|
||||
myFixConnectedMode: Integer is protected;
|
||||
myFixEdgeCurvesMode: Integer is protected;
|
||||
myFixDegeneratedMode: Integer is protected;
|
||||
myFixSelfIntersectionMode: Integer is protected;
|
||||
myFixLackingMode: Integer is protected;
|
||||
myFixGaps3dMode: Integer is protected;
|
||||
myFixGaps2dMode: Integer is protected;
|
||||
|
||||
myLastFixStatus: Integer is protected; -- status of last fix of advanced level
|
||||
|
||||
-- statuses corresponding to API methods, queried by Status..(status) methods
|
||||
myStatusReorder: Integer is protected;
|
||||
myStatusSmall: Integer is protected;
|
||||
myStatusConnected: Integer is protected;
|
||||
myStatusEdgeCurves: Integer is protected;
|
||||
myStatusDegenerated: Integer is protected;
|
||||
myStatusClosed: Integer is protected;
|
||||
myStatusSelfIntersection: Integer is protected;
|
||||
myStatusLacking: Integer is protected;
|
||||
myStatusGaps3d: Integer is protected;
|
||||
myStatusGaps2d: Integer is protected;
|
||||
myStatusRemovedSegment: Boolean is protected;
|
||||
myStatusNotches: Integer is protected;
|
||||
end Wire;
|
3249
src/ShapeFix/ShapeFix_Wire.cxx
Executable file
3249
src/ShapeFix/ShapeFix_Wire.cxx
Executable file
File diff suppressed because it is too large
Load Diff
537
src/ShapeFix/ShapeFix_Wire.lxx
Executable file
537
src/ShapeFix/ShapeFix_Wire.lxx
Executable file
@@ -0,0 +1,537 @@
|
||||
// File: ShapeFix_Wire.lxx
|
||||
// Created: Fri Jan 21 10:04:04 2000
|
||||
// Author: data exchange team
|
||||
// <det@nnov>
|
||||
|
||||
// pdn 05.01.98: renaming method ...Little to ...Small
|
||||
|
||||
#include <ShapeExtend.hxx>
|
||||
#include <ShapeExtend_WireData.hxx>
|
||||
#include <ShapeAnalysis_Wire.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : SetFace
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline void ShapeFix_Wire::SetFace(const TopoDS_Face& face)
|
||||
{
|
||||
myAnalyzer->SetFace ( face );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetSurface
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline void ShapeFix_Wire::SetSurface(const Handle(Geom_Surface)& surf)
|
||||
{
|
||||
myAnalyzer->SetSurface ( surf );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetSurface
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline void ShapeFix_Wire::SetSurface(const Handle(Geom_Surface)& surf,const TopLoc_Location& loc)
|
||||
{
|
||||
myAnalyzer->SetSurface ( surf, loc );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsLoaded
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean ShapeFix_Wire::IsLoaded() const
|
||||
{
|
||||
return myAnalyzer->IsLoaded();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsReady
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean ShapeFix_Wire::IsReady() const
|
||||
{
|
||||
return myAnalyzer->IsReady();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Wire
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline TopoDS_Wire ShapeFix_Wire::Wire() const
|
||||
{
|
||||
return myAnalyzer->WireData()->Wire();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : WireAPIMake
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline TopoDS_Wire ShapeFix_Wire::WireAPIMake() const
|
||||
{
|
||||
return myAnalyzer->WireData()->WireAPIMake();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Analyzer
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Handle(ShapeAnalysis_Wire) ShapeFix_Wire::Analyzer() const
|
||||
{
|
||||
return myAnalyzer;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : WireData
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline const Handle(ShapeExtend_WireData)& ShapeFix_Wire::WireData() const
|
||||
{
|
||||
return myAnalyzer->WireData();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Face
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline const TopoDS_Face& ShapeFix_Wire::Face() const
|
||||
{
|
||||
return myAnalyzer->Face();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ModifyTopologyMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean& ShapeFix_Wire::ModifyTopologyMode()
|
||||
{
|
||||
return myTopoMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ModifyGeometryMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean& ShapeFix_Wire::ModifyGeometryMode()
|
||||
{
|
||||
return myGeomMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ModifyRemoveLoopMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Wire::ModifyRemoveLoopMode()
|
||||
{
|
||||
return myRemoveLoopMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ClosedWireMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean& ShapeFix_Wire::ClosedWireMode()
|
||||
{
|
||||
return myClosedMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : PreferencePCurveMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean& ShapeFix_Wire::PreferencePCurveMode()
|
||||
{
|
||||
return myPreference2d;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixGapsByRangesMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean& ShapeFix_Wire::FixGapsByRangesMode()
|
||||
{
|
||||
return myFixGapsByRanges;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Fix..Mode for high-level fixes
|
||||
|
||||
//=======================================================================
|
||||
//function : FixReorderMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Wire::FixReorderMode()
|
||||
{
|
||||
return myFixReorderMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixSmallMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Wire::FixSmallMode()
|
||||
{
|
||||
return myFixSmallMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixConnectedMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Wire::FixConnectedMode()
|
||||
{
|
||||
return myFixConnectedMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixEdgeCurvesMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Wire::FixEdgeCurvesMode()
|
||||
{
|
||||
return myFixEdgeCurvesMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixDegeneratedMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Wire::FixDegeneratedMode()
|
||||
{
|
||||
return myFixDegeneratedMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Fix..Mode for low-level fixes
|
||||
|
||||
//=======================================================================
|
||||
//function : FixReversed2dMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Wire::FixReversed2dMode()
|
||||
{
|
||||
return myFixReversed2dMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixRemovePCurveMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Wire::FixRemovePCurveMode()
|
||||
{
|
||||
return myFixRemovePCurveMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixRemoveCurve3dMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Wire::FixRemoveCurve3dMode()
|
||||
{
|
||||
return myFixRemoveCurve3dMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixAddPCurveMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Wire::FixAddPCurveMode()
|
||||
{
|
||||
return myFixAddPCurveMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixAddCurve3dMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Wire::FixAddCurve3dMode()
|
||||
{
|
||||
return myFixAddCurve3dMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixSeamMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Wire::FixSeamMode()
|
||||
{
|
||||
return myFixSeamMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixShiftedMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Wire::FixShiftedMode()
|
||||
{
|
||||
return myFixShiftedMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixSameParameterMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Wire::FixSameParameterMode()
|
||||
{
|
||||
return myFixSameParameterMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixVertexToleranceMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Wire::FixVertexToleranceMode()
|
||||
{
|
||||
return myFixVertexToleranceMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixLackingMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Wire::FixLackingMode()
|
||||
{
|
||||
return myFixLackingMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixSelfIntersectionMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Wire::FixSelfIntersectionMode()
|
||||
{
|
||||
return myFixSelfIntersectionMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixGaps3dMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Wire::FixGaps3dMode()
|
||||
{
|
||||
return myFixGaps3dMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixGaps2dMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Wire::FixGaps2dMode()
|
||||
{
|
||||
return myFixGaps2dMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixNotchedEdgesMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Wire::FixNotchedEdgesMode()
|
||||
{
|
||||
return myFixNotchedEdgesMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixSelfIntersectingEdgeMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Wire::FixSelfIntersectingEdgeMode()
|
||||
{
|
||||
return myFixSelfIntersectingEdgeMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixIntersectingEdgesMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Wire::FixIntersectingEdgesMode()
|
||||
{
|
||||
return myFixIntersectingEdgesMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixNonAdjacentIntersectingEdgesMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer& ShapeFix_Wire::FixNonAdjacentIntersectingEdgesMode()
|
||||
{
|
||||
return myFixNonAdjacentIntersectingEdgesMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Status.. for high-level methods
|
||||
|
||||
//=======================================================================
|
||||
//function : StatusReorder
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean ShapeFix_Wire::StatusReorder(const ShapeExtend_Status status) const
|
||||
{
|
||||
return ShapeExtend::DecodeStatus ( myStatusReorder, status );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : StatusSmall
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean ShapeFix_Wire::StatusSmall(const ShapeExtend_Status status) const
|
||||
{
|
||||
return ShapeExtend::DecodeStatus ( myStatusSmall, status );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : StatusConnected
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean ShapeFix_Wire::StatusConnected(const ShapeExtend_Status status) const
|
||||
{
|
||||
return ShapeExtend::DecodeStatus ( myStatusConnected, status );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : StatusEdgeCurves
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean ShapeFix_Wire::StatusEdgeCurves(const ShapeExtend_Status status) const
|
||||
{
|
||||
return ShapeExtend::DecodeStatus ( myStatusEdgeCurves, status );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : StatusDegenerated
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean ShapeFix_Wire::StatusDegenerated(const ShapeExtend_Status status) const
|
||||
{
|
||||
return ShapeExtend::DecodeStatus ( myStatusDegenerated, status );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : StatusLacking
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean ShapeFix_Wire::StatusLacking(const ShapeExtend_Status status) const
|
||||
{
|
||||
return ShapeExtend::DecodeStatus ( myStatusLacking, status );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : StatusSelfIntersection
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean ShapeFix_Wire::StatusSelfIntersection(const ShapeExtend_Status status) const
|
||||
{
|
||||
return ShapeExtend::DecodeStatus ( myStatusSelfIntersection, status );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : StatusGaps3d
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean ShapeFix_Wire::StatusGaps3d(const ShapeExtend_Status status) const
|
||||
{
|
||||
return ShapeExtend::DecodeStatus ( myStatusGaps3d, status );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : StatusGaps2d
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean ShapeFix_Wire::StatusGaps2d(const ShapeExtend_Status status) const
|
||||
{
|
||||
return ShapeExtend::DecodeStatus ( myStatusGaps2d, status );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : StatusClosed
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean ShapeFix_Wire::StatusClosed(const ShapeExtend_Status status) const
|
||||
{
|
||||
return ShapeExtend::DecodeStatus ( myStatusClosed, status );
|
||||
}
|
||||
//=======================================================================
|
||||
//function : StatusNotches
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean ShapeFix_Wire::StatusNotches(const ShapeExtend_Status status) const
|
||||
{
|
||||
return ShapeExtend::DecodeStatus ( myStatusNotches, status );
|
||||
}
|
||||
//=======================================================================
|
||||
//function : LastFixStatus - Status for low-level methods (common)
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean ShapeFix_Wire::LastFixStatus(const ShapeExtend_Status status) const
|
||||
{
|
||||
return ShapeExtend::DecodeStatus ( myLastFixStatus, status );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixEdgeTool
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Handle(ShapeFix_Edge) ShapeFix_Wire::FixEdgeTool() const
|
||||
{
|
||||
return myFixEdge;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : StatusRemovedSegment
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean ShapeFix_Wire::StatusRemovedSegment() const
|
||||
{
|
||||
return myStatusRemovedSegment;
|
||||
}
|
138
src/ShapeFix/ShapeFix_WireSegment.cdl
Executable file
138
src/ShapeFix/ShapeFix_WireSegment.cdl
Executable file
@@ -0,0 +1,138 @@
|
||||
-- File: ShapeFix_WireSegment.cdl
|
||||
-- Created: Tue Apr 27 10:42:17 1999
|
||||
-- Author: Andrey BETENEV
|
||||
-- <abv@nnov.matra-dtv.fr>
|
||||
---Copyright: Matra Datavision 1999
|
||||
|
||||
|
||||
class WireSegment from ShapeFix
|
||||
|
||||
---Purpose: This class is auxiliary class used in ComposeShell.
|
||||
-- It is intended for representing segment of the wire
|
||||
-- (or whole wire). The segment itself is represented by
|
||||
-- ShapeExtend_WireData. In addition, some associated data
|
||||
-- necessary for computations are stored:
|
||||
--
|
||||
-- * Orientation flag - determines current use of the segment
|
||||
-- and used for parity checking:
|
||||
--
|
||||
-- TopAbs_FORWARD and TopAbs_REVERSED - says that segment was
|
||||
-- traversed once in the corresponding direction, and hence
|
||||
-- it should be traversed once more in opposite direction;
|
||||
--
|
||||
-- TopAbs_EXTERNAL - the segment was not yet traversed in any
|
||||
-- direction (i.e. not yet used as boundary)
|
||||
--
|
||||
-- TopAbs_INTERNAL - the segment was traversed in both
|
||||
-- directions and hence is out of further work.
|
||||
--
|
||||
-- Segments of initial bounding wires are created with
|
||||
-- orientation REVERSED (for outer wire) or FORWARD (for inner
|
||||
-- wires), and segments of splitting seams - with orientation
|
||||
-- EXTERNAL.
|
||||
|
||||
uses
|
||||
Orientation from TopAbs,
|
||||
Edge from TopoDS,
|
||||
Wire from TopoDS,
|
||||
Vertex from TopoDS,
|
||||
WireData from ShapeExtend,
|
||||
HSequenceOfInteger from TColStd
|
||||
|
||||
is
|
||||
Create returns WireSegment;
|
||||
---Purpose: Creates empty segment.
|
||||
|
||||
Create (wire: WireData from ShapeExtend;
|
||||
ori: Orientation from TopAbs = TopAbs_EXTERNAL)
|
||||
returns WireSegment;
|
||||
---Purpose: Creates segment and initializes it with wire and orientation.
|
||||
|
||||
Create (wire: Wire from TopoDS;
|
||||
ori: Orientation from TopAbs = TopAbs_EXTERNAL)
|
||||
returns WireSegment;
|
||||
---Purpose: Creates segment and initializes it with wire and orientation.
|
||||
|
||||
Clear (me: in out);
|
||||
---Purpose: Clears all fields.
|
||||
|
||||
Load (me: in out; wire: WireData from ShapeExtend);
|
||||
---Purpose: Loads wire.
|
||||
|
||||
WireData (me) returns WireData from ShapeExtend;
|
||||
---Purpose: Returns wire.
|
||||
---C++: return const &
|
||||
|
||||
Orientation (me: in out; ori: Orientation from TopAbs);
|
||||
---Purpose: Sets orientation flag.
|
||||
|
||||
Orientation (me) returns Orientation from TopAbs;
|
||||
---Purpose: Returns orientation flag.
|
||||
|
||||
FirstVertex (me) returns Vertex from TopoDS;
|
||||
---Purpose: Returns first vertex of the first edge in the wire
|
||||
-- (no dependance on Orientation()).
|
||||
|
||||
LastVertex (me) returns Vertex from TopoDS;
|
||||
---Purpose: Returns last vertex of the last edge in the wire
|
||||
-- (no dependance on Orientation()).
|
||||
|
||||
IsClosed (me) returns Boolean;
|
||||
---Purpose: Returns True if FirstVertex() == LastVertex()
|
||||
|
||||
---Scope: work with edges and synchronous maintaining patch indices
|
||||
|
||||
NbEdges (me) returns Integer;
|
||||
---Purpose: Returns Number of edges in the wire
|
||||
|
||||
Edge (me; i: Integer) returns Edge from TopoDS;
|
||||
---Purpose: Returns edge by given index in the wire
|
||||
|
||||
SetEdge (me: in out; i: Integer; edge: Edge from TopoDS);
|
||||
---Purpose: Replaces edge at index i by new one.
|
||||
|
||||
AddEdge (me: in out; i: Integer; edge: Edge from TopoDS);
|
||||
---Purpose: Insert a new edge with index i and implicitly defined
|
||||
-- patch indices (indefinite patch).
|
||||
-- If i==0, edge is inserted at end of wire.
|
||||
|
||||
AddEdge (me: in out; i: Integer; edge: Edge from TopoDS;
|
||||
iumin, iumax, ivmin, ivmax: Integer);
|
||||
---Purpose: Insert a new edge with index i and explicitly defined
|
||||
-- patch indices. If i==0, edge is inserted at end of wire.
|
||||
|
||||
SetPatchIndex (me: in out; i: Integer; iumin, iumax, ivmin, ivmax: Integer);
|
||||
---Purpose: Set patch indices for edge i.
|
||||
|
||||
DefineIUMin (me: in out; i: Integer; iumin: Integer);
|
||||
DefineIUMax (me: in out; i: Integer; iumax: Integer);
|
||||
DefineIVMin (me: in out; i: Integer; ivmin: Integer);
|
||||
DefineIVMax (me: in out; i: Integer; ivmax: Integer);
|
||||
---Purpose: Modify minimal or maximal patch index for edge i.
|
||||
-- The corresponding patch index for that edge is modified so
|
||||
-- as to satisfy eq. iumin <= myIUMin(i) <= myIUMax(i) <= iumax
|
||||
|
||||
GetPatchIndex (me; i: Integer; iumin, iumax, ivmin, ivmax: out Integer);
|
||||
---Purpose: Returns patch indices for edge i.
|
||||
|
||||
CheckPatchIndex (me; i: Integer) returns Boolean;
|
||||
---Purpose: Checks patch indices for edge i to satisfy equations
|
||||
-- IUMin(i) <= IUMax(i) <= IUMin(i)+1
|
||||
|
||||
-- for non-manifold faces if face contains INTERNAL vertices
|
||||
SetVertex(me: in out; theVertex: Vertex from TopoDS);
|
||||
--SetVertex(me: in out; theVertex: Vertex from TopoDS;iumin, iumax, ivmin, ivmax: Integer );
|
||||
GetVertex(me) returns Vertex from TopoDS;
|
||||
IsVertex(me) returns Boolean;
|
||||
|
||||
fields
|
||||
|
||||
myWire : WireData from ShapeExtend;
|
||||
myVertex : Vertex from TopoDS;
|
||||
myOrient: Orientation from TopAbs;
|
||||
myIUMin : HSequenceOfInteger from TColStd; -- indices
|
||||
myIUMax : HSequenceOfInteger from TColStd; -- for
|
||||
myIVMin : HSequenceOfInteger from TColStd; -- patch
|
||||
myIVMax : HSequenceOfInteger from TColStd; --
|
||||
|
||||
end WireSegment;
|
365
src/ShapeFix/ShapeFix_WireSegment.cxx
Executable file
365
src/ShapeFix/ShapeFix_WireSegment.cxx
Executable file
@@ -0,0 +1,365 @@
|
||||
// File: ShapeFix_WireSegment.cxx
|
||||
// Created: Tue Apr 27 17:30:20 1999
|
||||
// Author: Pavel DURANDIN
|
||||
// <pdn@nnov.matra-dtv.fr>
|
||||
|
||||
|
||||
#include <ShapeFix_WireSegment.ixx>
|
||||
#include <ShapeAnalysis_Edge.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeFix_WireSegment
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
ShapeFix_WireSegment::ShapeFix_WireSegment()
|
||||
{
|
||||
Clear();
|
||||
myOrient = TopAbs_FORWARD;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeFix_WireSegment
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
ShapeFix_WireSegment::ShapeFix_WireSegment(const Handle(ShapeExtend_WireData)& wire,
|
||||
const TopAbs_Orientation ori)
|
||||
{
|
||||
Load ( wire );
|
||||
myOrient = ori;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Clear
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_WireSegment::Clear()
|
||||
{
|
||||
myWire = new ShapeExtend_WireData;
|
||||
myWire->ManifoldMode() = Standard_False;
|
||||
myIUMin = new TColStd_HSequenceOfInteger;
|
||||
myIUMax = new TColStd_HSequenceOfInteger;
|
||||
myIVMin = new TColStd_HSequenceOfInteger;
|
||||
myIVMax = new TColStd_HSequenceOfInteger;
|
||||
myVertex = TopoDS_Vertex();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Load
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_WireSegment::Load (const Handle(ShapeExtend_WireData)& wire)
|
||||
{
|
||||
// myWire = wire;
|
||||
Clear();
|
||||
myWire->ManifoldMode() = wire->ManifoldMode();
|
||||
for ( Standard_Integer i=1; i <= wire->NbEdges(); i++ )
|
||||
AddEdge ( i, wire->Edge(i) );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : WireData
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
const Handle(ShapeExtend_WireData)& ShapeFix_WireSegment::WireData() const
|
||||
{
|
||||
return myWire;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Orientation
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_WireSegment::Orientation(const TopAbs_Orientation ori)
|
||||
{
|
||||
myOrient = ori;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Orientation
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
TopAbs_Orientation ShapeFix_WireSegment::Orientation() const
|
||||
{
|
||||
return myOrient;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FirstVertex
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
TopoDS_Vertex ShapeFix_WireSegment::FirstVertex() const
|
||||
{
|
||||
ShapeAnalysis_Edge sae;
|
||||
return sae.FirstVertex (myWire->Edge(1));
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : LastVertex
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
TopoDS_Vertex ShapeFix_WireSegment::LastVertex() const
|
||||
{
|
||||
ShapeAnalysis_Edge sae;
|
||||
return sae.LastVertex (myWire->Edge(myWire->NbEdges()));
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsClosed
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_WireSegment::IsClosed() const
|
||||
{
|
||||
TopoDS_Vertex v;
|
||||
v = FirstVertex();
|
||||
return v.IsSame(LastVertex());
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// WORK with EDGES and PATCH INDICES
|
||||
//=======================================================================
|
||||
|
||||
#define MININD -32000
|
||||
#define MAXIND 32000
|
||||
|
||||
//=======================================================================
|
||||
//function : NbEdges
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer ShapeFix_WireSegment::NbEdges() const
|
||||
{
|
||||
return myWire->NbEdges();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Edge
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
TopoDS_Edge ShapeFix_WireSegment::Edge (const Standard_Integer i) const
|
||||
{
|
||||
|
||||
return myWire->Edge(i);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetEdge
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_WireSegment::SetEdge (const Standard_Integer i,
|
||||
const TopoDS_Edge &edge)
|
||||
{
|
||||
myWire->Set ( edge, i );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : AddEdge
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_WireSegment::AddEdge (const Standard_Integer i,
|
||||
const TopoDS_Edge &edge)
|
||||
{
|
||||
AddEdge ( i, edge, MININD, MAXIND, MININD, MAXIND );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : AddEdge
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_WireSegment::AddEdge (const Standard_Integer i,
|
||||
const TopoDS_Edge &edge,
|
||||
const Standard_Integer iumin,
|
||||
const Standard_Integer iumax,
|
||||
const Standard_Integer ivmin,
|
||||
const Standard_Integer ivmax)
|
||||
{
|
||||
myWire->Add ( edge, i );
|
||||
if ( i ==0 ) {
|
||||
myIUMin->Append ( iumin );
|
||||
myIUMax->Append ( iumax );
|
||||
myIVMin->Append ( ivmin );
|
||||
myIVMax->Append ( ivmax );
|
||||
}
|
||||
else {
|
||||
myIUMin->InsertBefore ( i, iumin );
|
||||
myIUMax->InsertBefore ( i, iumax );
|
||||
myIVMin->InsertBefore ( i, ivmin );
|
||||
myIVMax->InsertBefore ( i, ivmax );
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetPatchIndex
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_WireSegment::SetPatchIndex (const Standard_Integer i,
|
||||
const Standard_Integer iumin,
|
||||
const Standard_Integer iumax,
|
||||
const Standard_Integer ivmin,
|
||||
const Standard_Integer ivmax)
|
||||
{
|
||||
myIUMin->SetValue ( i, iumin );
|
||||
myIUMax->SetValue ( i, iumax );
|
||||
myIVMin->SetValue ( i, ivmin );
|
||||
myIVMax->SetValue ( i, ivmax );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : DefineIUMin
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_WireSegment::DefineIUMin (const Standard_Integer i,
|
||||
const Standard_Integer iumin)
|
||||
{
|
||||
if ( myIUMin->Value(i) < iumin ) myIUMin->SetValue ( i, iumin );
|
||||
#ifdef DEB
|
||||
if ( myIUMin->Value(i) > myIUMax->Value(i) )
|
||||
cout << "Warning: ShapeFix_WireSegment::DefineIUMin: indexation error" << endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : DefineIUMax
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_WireSegment::DefineIUMax (const Standard_Integer i,
|
||||
const Standard_Integer iumax)
|
||||
{
|
||||
if ( myIUMax->Value(i) > iumax ) myIUMax->SetValue ( i, iumax );
|
||||
#ifdef DEB
|
||||
Standard_Integer iun = myIUMin->Value(i), iux = myIUMax->Value(i);
|
||||
if ( iun > iux )
|
||||
cout << "Warning: ShapeFix_WireSegment::DefineIUMax: indexation error" << endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : DefineIVMin
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_WireSegment::DefineIVMin (const Standard_Integer i,
|
||||
const Standard_Integer ivmin)
|
||||
{
|
||||
if ( myIVMin->Value(i) < ivmin ) myIVMin->SetValue ( i, ivmin );
|
||||
#ifdef DEB
|
||||
Standard_Integer ivn = myIVMin->Value(i), ivx = myIVMax->Value(i);
|
||||
if ( ivn > ivx )
|
||||
cout << "Warning: ShapeFix_WireSegment::DefineIVMin: indexation error" << endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : DefineIVMax
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_WireSegment::DefineIVMax (const Standard_Integer i,
|
||||
const Standard_Integer ivmax)
|
||||
{
|
||||
if ( myIVMax->Value(i) > ivmax ) myIVMax->SetValue ( i, ivmax );
|
||||
#ifdef DEB
|
||||
Standard_Integer ivn = myIVMin->Value(i), ivx = myIVMax->Value(i);
|
||||
if ( ivn > ivx )
|
||||
cout << "Warning: ShapeFix_WireSegment::DefineIVMax: indexation error" << endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : GetPatchIndex
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_WireSegment::GetPatchIndex (const Standard_Integer i,
|
||||
Standard_Integer &iumin,
|
||||
Standard_Integer &iumax,
|
||||
Standard_Integer &ivmin,
|
||||
Standard_Integer &ivmax) const
|
||||
{
|
||||
iumin = myIUMin->Value(i);
|
||||
iumax = myIUMax->Value(i);
|
||||
ivmin = myIVMin->Value(i);
|
||||
ivmax = myIVMax->Value(i);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : CheckPatchIndex
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_WireSegment::CheckPatchIndex (const Standard_Integer i) const
|
||||
{
|
||||
Standard_Integer dU = myIUMax->Value(i) - myIUMin->Value(i);
|
||||
Standard_Integer dV = myIVMax->Value(i) - myIVMin->Value(i);
|
||||
Standard_Boolean ok = ( dU ==0 || dU ==1 ) && ( dV ==0 || dV ==1 );
|
||||
#ifdef DEB
|
||||
if ( ! ok )
|
||||
cout << "Warning: ShapeFix_WireSegment::CheckPatchIndex: incomplete indexation" << endl;
|
||||
#endif
|
||||
return ok;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetVertex
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_WireSegment::SetVertex(const TopoDS_Vertex& theVertex)
|
||||
{
|
||||
myVertex = theVertex;
|
||||
//SetVertex(theVertex, MININD, MAXIND, MININD, MAXIND);
|
||||
}
|
||||
|
||||
/*//=======================================================================
|
||||
//function : SetVertex
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_WireSegment::SetVertex(const TopoDS_Vertex& theVertex,
|
||||
Standard_Integer iumin,
|
||||
Standard_Integer iumax,
|
||||
Standard_Integer ivmin,
|
||||
Standard_Integer ivmax)
|
||||
myVertex = theVertex;
|
||||
myIUMin->Append ( iumin );
|
||||
myIUMax->Append ( iumax );
|
||||
myIVMin->Append ( ivmin );
|
||||
myIVMax->Append ( ivmax );
|
||||
}
|
||||
*/
|
||||
//=======================================================================
|
||||
//function : GetVertex
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
TopoDS_Vertex ShapeFix_WireSegment::GetVertex() const
|
||||
{
|
||||
return myVertex;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsVertex
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeFix_WireSegment::IsVertex() const
|
||||
{
|
||||
return !myVertex.IsNull();
|
||||
}
|
64
src/ShapeFix/ShapeFix_WireVertex.cdl
Executable file
64
src/ShapeFix/ShapeFix_WireVertex.cdl
Executable file
@@ -0,0 +1,64 @@
|
||||
-- File: ShapeFix_WireVertex.cdl
|
||||
-- Created: Wed Jun 3 12:33:04 1998
|
||||
-- Author: data exchange team
|
||||
-- <det@nnov.matra-dtv.fr>
|
||||
---Copyright: Matra Datavision 1998
|
||||
|
||||
|
||||
class WireVertex from ShapeFix
|
||||
|
||||
---Purpose: Fixes vertices in the wire on the basis of pre-analysis
|
||||
-- made by ShapeAnalysis_WireVertex (given as argument).
|
||||
-- The Wire has formerly been loaded in a ShapeExtend_WireData.
|
||||
|
||||
uses
|
||||
Wire from TopoDS,
|
||||
WireData from ShapeExtend,
|
||||
WireVertex from ShapeAnalysis
|
||||
|
||||
is
|
||||
|
||||
Create returns WireVertex from ShapeFix;
|
||||
|
||||
Init (me: in out; wire: Wire from TopoDS; preci: Real);
|
||||
---Purpose: Loads the wire, ininializes internal analyzer
|
||||
-- (ShapeAnalysis_WireVertex) with the given precision,
|
||||
-- and performs analysis
|
||||
|
||||
Init (me: in out; sbwd: WireData from ShapeExtend; preci: Real);
|
||||
---Purpose: Loads the wire, ininializes internal analyzer
|
||||
-- (ShapeAnalysis_WireVertex) with the given precision,
|
||||
-- and performs analysis
|
||||
|
||||
Init (me: in out; sawv: WireVertex from ShapeAnalysis);
|
||||
---Purpose: Loads all the data on wire, already analysed by
|
||||
-- ShapeAnalysis_WireVertex
|
||||
|
||||
Analyzer (me) returns WireVertex from ShapeAnalysis;
|
||||
---C++: return const &
|
||||
---Purpose: returns internal analyzer
|
||||
|
||||
WireData (me) returns WireData from ShapeExtend;
|
||||
---C++: return const &
|
||||
---Purpose: returns data on wire (fixed)
|
||||
---Remark : calls Analyzer().WireData()
|
||||
|
||||
Wire (me) returns Wire from TopoDS;
|
||||
---Purpose: returns resulting wire (fixed)
|
||||
---Remark : calls Analyzer().WireData()->Wire()
|
||||
|
||||
FixSame (me: in out) returns Integer;
|
||||
---Purpose: Fixes "Same" or "Close" status (same vertex may be set,
|
||||
-- without changing parameters)
|
||||
-- Returns the count of fixed vertices, 0 if none
|
||||
|
||||
Fix (me: in out) returns Integer;
|
||||
---Purpose: Fixes all statuses except "Disjoined", i.e. the cases in which a
|
||||
-- common value has been set, with or without changing parameters
|
||||
-- Returns the count of fixed vertices, 0 if none
|
||||
|
||||
fields
|
||||
|
||||
myAnalyzer: WireVertex from ShapeAnalysis;
|
||||
|
||||
end WireVertex;
|
275
src/ShapeFix/ShapeFix_WireVertex.cxx
Executable file
275
src/ShapeFix/ShapeFix_WireVertex.cxx
Executable file
@@ -0,0 +1,275 @@
|
||||
//szv#4 S4163
|
||||
#include <ShapeFix_WireVertex.ixx>
|
||||
|
||||
#include <TopExp.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopTools_HArray1OfShape.hxx>
|
||||
#include <TColStd_HArray1OfReal.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
|
||||
#include <ShapeAnalysis_Edge.hxx>
|
||||
|
||||
#include <gp_Pnt.hxx> //ied_modif_for_compil_Nov-19-1998
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeFix_WireVertex
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
ShapeFix_WireVertex::ShapeFix_WireVertex()
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Init
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_WireVertex::Init (const TopoDS_Wire& wire,
|
||||
const Standard_Real preci)
|
||||
{
|
||||
Handle(ShapeExtend_WireData) sbwd = new ShapeExtend_WireData ( wire );
|
||||
Init ( sbwd, preci );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Init
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_WireVertex::Init (const Handle(ShapeExtend_WireData)& sbwd,
|
||||
const Standard_Real preci)
|
||||
{
|
||||
myAnalyzer.Load ( sbwd );
|
||||
myAnalyzer.SetPrecision ( preci );
|
||||
myAnalyzer.Analyze();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Load
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeFix_WireVertex::Init (const ShapeAnalysis_WireVertex& sawv)
|
||||
{
|
||||
myAnalyzer = sawv;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Analyzer
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
const ShapeAnalysis_WireVertex& ShapeFix_WireVertex::Analyzer() const
|
||||
{
|
||||
return myAnalyzer;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : WireData
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
const Handle(ShapeExtend_WireData)& ShapeFix_WireVertex::WireData() const
|
||||
{
|
||||
return myAnalyzer.WireData();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Wire
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
TopoDS_Wire ShapeFix_WireVertex::Wire() const
|
||||
{
|
||||
return myAnalyzer.WireData()->Wire();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixSame
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer ShapeFix_WireVertex::FixSame()
|
||||
{
|
||||
// FixSame : prend les status "SameCoord" et "Close" et les force a "Same"
|
||||
// reprendre l edge et forcer le vertex. Evt changer sa tolerance. Et voila
|
||||
if ( ! myAnalyzer.IsDone() ) return 0;
|
||||
|
||||
Standard_Integer nbfix = 0;
|
||||
BRep_Builder B;
|
||||
|
||||
Handle(ShapeExtend_WireData) sbwd = myAnalyzer.WireData();
|
||||
Standard_Integer i, nb = sbwd->NbEdges();
|
||||
|
||||
for (i = 1; i <= nb; i ++) {
|
||||
Standard_Integer j = (i == nb ? 1 : i+1);
|
||||
Standard_Integer stat = myAnalyzer.Status(i);
|
||||
if (stat != 1 && stat != 2) continue;
|
||||
// Ici on prend un vertex et on le generalise aux deux edges
|
||||
TopoDS_Edge E1 = sbwd->Edge (i);
|
||||
TopoDS_Edge E2 = sbwd->Edge (j);
|
||||
|
||||
ShapeAnalysis_Edge sae;
|
||||
TopoDS_Vertex V1 = sae.LastVertex ( E1 );
|
||||
TopoDS_Vertex V2 = sae.FirstVertex ( E2 );
|
||||
if (V1 == V2) {
|
||||
myAnalyzer.SetSameVertex(i);
|
||||
continue;
|
||||
} // deja fait ...
|
||||
if (stat == 2) {
|
||||
// OK mais en reprenant les tolerances
|
||||
Handle(Geom_Curve) crv;
|
||||
Standard_Real cf,cl;
|
||||
sae.Curve3d ( sbwd->Edge(i), crv, cf, cl );
|
||||
B.UpdateVertex (V1,cl,E1,myAnalyzer.Precision());
|
||||
sae.Curve3d ( sbwd->Edge(j), crv, cf, cl );
|
||||
B.UpdateVertex (V1,cf,E2,myAnalyzer.Precision());
|
||||
}
|
||||
// Et remettre ce vtx en commun
|
||||
V1.Orientation (E2.Orientation());
|
||||
B.Add (E2,V1);
|
||||
V1.Orientation (E1.Orientation()); V1.Reverse();
|
||||
B.Add (E1,V1);
|
||||
myAnalyzer.SetSameVertex(i); // conclusion
|
||||
nbfix ++;
|
||||
}
|
||||
return nbfix;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Fix
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer ShapeFix_WireVertex::Fix()
|
||||
{
|
||||
// Ici le grand jeu : on repasse partout
|
||||
// stat = 0 (OK) ou <0 (KO) : on passe
|
||||
// stat = 1 ou 2 : on reprend le vtx d origine
|
||||
// sinon on en refait un ...
|
||||
|
||||
// MAIS ATTENTION : on fait du neuf ... forcement. Donc nouvelles edges
|
||||
// auxquelles on remet les Vertex (assez facile)
|
||||
// Donc deux passes : 1 refaire les VTX et 2 les remettre dans les edges
|
||||
if ( ! myAnalyzer.IsDone() ) return 0;
|
||||
|
||||
Handle(ShapeExtend_WireData) sbwd = myAnalyzer.WireData();
|
||||
|
||||
Standard_Integer i, nb = sbwd->NbEdges();
|
||||
Standard_Integer nbfix = 0;
|
||||
for (i = 1; i <= nb; i ++) {
|
||||
// On note les valeurs
|
||||
//szv#4:S4163:12Mar99 optimized
|
||||
if (myAnalyzer.Status(i) > 0) nbfix ++;
|
||||
}
|
||||
if (nbfix == 0) return 0;
|
||||
|
||||
BRep_Builder B;
|
||||
|
||||
Handle(TopTools_HArray1OfShape) VI = new TopTools_HArray1OfShape (1,nb);
|
||||
Handle(TopTools_HArray1OfShape) VJ = new TopTools_HArray1OfShape (1,nb);
|
||||
Handle(TopTools_HArray1OfShape) EF = new TopTools_HArray1OfShape (1,nb);
|
||||
Handle(TColStd_HArray1OfReal) UI = new TColStd_HArray1OfReal (1,nb);
|
||||
Handle(TColStd_HArray1OfReal) UJ = new TColStd_HArray1OfReal (1,nb);
|
||||
|
||||
for (i = 1; i <= nb; i ++) {
|
||||
// On note les valeurs
|
||||
Standard_Integer j = (i == nb ? 1 : i+1);
|
||||
Standard_Integer stat = myAnalyzer.Status (i);
|
||||
|
||||
ShapeAnalysis_Edge sae;
|
||||
TopoDS_Vertex V1 = sae.LastVertex ( sbwd->Edge(i) );
|
||||
TopoDS_Vertex V2 = sae.FirstVertex ( sbwd->Edge(j) );
|
||||
VI->SetValue (i,V1);
|
||||
VJ->SetValue (j,V2);
|
||||
|
||||
TopoDS_Edge E = sbwd->Edge(i);
|
||||
// E.EmptyCopy(); trop d ennuis
|
||||
EF->SetValue (i,E);
|
||||
|
||||
// if (stat <= 0) continue;
|
||||
// TopoDS_Edge E1 = STW.Edge (i);
|
||||
// TopoDS_Edge E2 = STW.Edge (j);
|
||||
Standard_Real upre = myAnalyzer.UPrevious(i);
|
||||
Standard_Real ufol = myAnalyzer.UFollowing(j);
|
||||
|
||||
Handle(Geom_Curve) crv;
|
||||
Standard_Real cf,cl;
|
||||
//szv#4:S4163:12Mar99 optimized
|
||||
if (stat < 4) {
|
||||
sae.Curve3d ( sbwd->Edge(i), crv, cf, cl );
|
||||
upre = cl;
|
||||
}
|
||||
if (stat < 3 || stat == 4) {
|
||||
sae.Curve3d ( sbwd->Edge(j), crv, cf, cl );
|
||||
ufol = cf;
|
||||
}
|
||||
|
||||
UI->SetValue (i,upre);
|
||||
UJ->SetValue (j,ufol);
|
||||
// nbfix ++;
|
||||
}
|
||||
|
||||
if (nbfix == 0) return nbfix;
|
||||
|
||||
// EmptyCopy pas bon : KK sur les Range (dommage, le reste est bon)
|
||||
// Donc on garde l original mais on change les vertex
|
||||
// En effet, avant de "ajouter" des vertex, il faut enlever ceux d avant
|
||||
// Sinon on garde en double !
|
||||
|
||||
for (i = 1; i <= nb; i ++) {
|
||||
TopoDS_Edge E1 = TopoDS::Edge (EF->Value (i));
|
||||
TopoDS_Vertex VA,VB;
|
||||
E1.Orientation (TopAbs_FORWARD);
|
||||
TopExp::Vertices (E1,VA,VB);
|
||||
E1.Free(Standard_True);
|
||||
B.Remove (E1,VA);
|
||||
B.Remove (E1,VB);
|
||||
}
|
||||
|
||||
Standard_Real Prec = myAnalyzer.Precision();
|
||||
for (i = 1; i <= nb; i ++) {
|
||||
// On y va pour de bon
|
||||
// Changer les coords ?
|
||||
Standard_Integer j = (i == nb ? 1 : i+1);
|
||||
Standard_Integer stat = myAnalyzer.Status (i);
|
||||
// if (stat <= 0) continue;
|
||||
|
||||
TopoDS_Vertex V1 = TopoDS::Vertex (VI->Value(i));
|
||||
TopoDS_Vertex V2 = TopoDS::Vertex (VJ->Value(j));
|
||||
TopoDS_Edge E1 = TopoDS::Edge (EF->Value (i));
|
||||
TopoDS_Edge E2 = TopoDS::Edge (EF->Value (j));
|
||||
Standard_Real upre = UI->Value(i);
|
||||
Standard_Real ufol = UJ->Value(j);
|
||||
|
||||
if (stat > 2)
|
||||
B.UpdateVertex (V1, gp_Pnt(myAnalyzer.Position(i)), Prec);
|
||||
|
||||
// ce qui suit : seulement si vertex a reprendre
|
||||
if (stat > 0) {
|
||||
B.UpdateVertex (V1,upre,E1,Prec);
|
||||
B.UpdateVertex (V1,ufol,E2,Prec);
|
||||
V1.Orientation (TopAbs_FORWARD);
|
||||
// V1.Orientation (E2.Orientation());
|
||||
}
|
||||
|
||||
// Comme on a deshabille les edges, il faut tout remettre
|
||||
E2.Free (Standard_True); // sur place
|
||||
B.Add (E2,V1);
|
||||
V1.Orientation (TopAbs_REVERSED);
|
||||
// V1.Orientation (E1.Orientation()); V1.Reverse();
|
||||
E1.Free (Standard_True); // sur place
|
||||
B.Add (E1,V1);
|
||||
|
||||
myAnalyzer.SetSameVertex (i); // conclusion
|
||||
// nbfix ++;
|
||||
}
|
||||
|
||||
// pour finir, MAJ du STW
|
||||
for (i = 1; i <= nb; i ++) sbwd->Set (TopoDS::Edge(EF->Value(i)),i);
|
||||
|
||||
return nbfix;
|
||||
}
|
1612
src/ShapeFix/ShapeFix_Wire_1.cxx
Executable file
1612
src/ShapeFix/ShapeFix_Wire_1.cxx
Executable file
File diff suppressed because it is too large
Load Diff
119
src/ShapeFix/ShapeFix_Wireframe.cdl
Executable file
119
src/ShapeFix/ShapeFix_Wireframe.cdl
Executable file
@@ -0,0 +1,119 @@
|
||||
-- File: ShapeFix_Wireframe.cdl
|
||||
-- Created: Tue Aug 24 11:27:03 1999
|
||||
-- Author: Sergei ZERTCHANINOV
|
||||
-- <szv@nnov>
|
||||
---Copyright: Matra Datavision 1999
|
||||
|
||||
|
||||
class Wireframe from ShapeFix inherits Root from ShapeFix
|
||||
|
||||
---Purpose : Provides methods for fixing wireframe of shape
|
||||
|
||||
uses
|
||||
|
||||
Shape from TopoDS,
|
||||
Status from ShapeExtend,
|
||||
Shape from GeomAbs,
|
||||
HArray1OfReal from TColStd,
|
||||
MapOfShape from TopTools,
|
||||
DataMapOfShapeListOfShape from TopTools
|
||||
|
||||
is
|
||||
|
||||
Create returns Wireframe from ShapeFix;
|
||||
|
||||
Create (shape: Shape from TopoDS) returns Wireframe from ShapeFix;
|
||||
|
||||
ClearStatuses (me: mutable) is virtual;
|
||||
---Purpose: Clears all statuses
|
||||
|
||||
Load (me : mutable; shape: Shape from TopoDS);
|
||||
---Purpose: Loads a shape, resets statuses
|
||||
|
||||
FixWireGaps (me : mutable) returns Boolean from Standard;
|
||||
---Purpose : Fixes gaps between ends of curves of adjacent edges
|
||||
-- (both 3d and pcurves) in wires
|
||||
-- If precision is 0.0, uses Precision::Confusion().
|
||||
---Status : See StatusWireGaps() for details
|
||||
-- OK - No gaps were found
|
||||
-- DONE1 - Some gaps in 3D were fixed
|
||||
-- DONE2 - Some gaps in 2D were fixed
|
||||
-- FAIL1 - Failed to fix some gaps in 3D
|
||||
-- FAIL2 - Failed to fix some gaps in 2D
|
||||
---Returns : False if nothing done, else True
|
||||
|
||||
FixSmallEdges (me : mutable) returns Boolean from Standard;
|
||||
---Purpose : Fixes small edges in shape by merging adjacent edges
|
||||
-- If precision is 0.0, uses Precision::Confusion().
|
||||
---Status : See StatusSmallEdges() for details
|
||||
-- OK - No small edges were found
|
||||
-- DONE1 - Some small edges were fixed
|
||||
-- FAIL1 - Failed to fix some small edges
|
||||
---Returns : False if nothing done, else True
|
||||
|
||||
CheckSmallEdges (me: mutable; theSmallEdges: out MapOfShape from TopTools;
|
||||
theEdgeToFaces: out DataMapOfShapeListOfShape from TopTools;
|
||||
theFaceWithSmall: out DataMapOfShapeListOfShape from TopTools;
|
||||
theMultyEdges: out MapOfShape from TopTools)
|
||||
returns Boolean from Standard;
|
||||
---Purpose: Auxiliary tool for FixSmallEdges which checks for small edges and fills the maps.
|
||||
-- Returns True if at least one small edge has been found.
|
||||
|
||||
MergeSmallEdges (me: mutable; theSmallEdges: in out MapOfShape from TopTools;
|
||||
theEdgeToFaces: in out DataMapOfShapeListOfShape from TopTools;
|
||||
theFaceWithSmall: in out DataMapOfShapeListOfShape from TopTools;
|
||||
theMultyEdges: out MapOfShape from TopTools;
|
||||
theModeDrop: Boolean = Standard_False;
|
||||
theLimitAngle: Real = -1)
|
||||
returns Boolean from Standard;
|
||||
---Purpose: Auxiliary tool for FixSmallEdges which merges small edges.
|
||||
-- If theModeDrop is equal to Standard_True then small edges,
|
||||
-- which cannot be connected with adjacent edges are dropped.
|
||||
-- Otherwise they are kept.
|
||||
-- theLimitAngle specifies maximum allowed tangency
|
||||
-- discontinuity between adjacent edges.
|
||||
-- If theLimitAngle is equal to -1, this angle is not taken into account.
|
||||
|
||||
StatusWireGaps (me; status: Status from ShapeExtend) returns Boolean;
|
||||
---C++: inline
|
||||
---Purpose : Decodes the status of the last FixWireGaps.
|
||||
-- OK - No gaps were found
|
||||
-- DONE1 - Some gaps in 3D were fixed
|
||||
-- DONE2 - Some gaps in 2D were fixed
|
||||
-- FAIL1 - Failed to fix some gaps in 3D
|
||||
-- FAIL2 - Failed to fix some gaps in 2D
|
||||
|
||||
StatusSmallEdges (me; status: Status from ShapeExtend) returns Boolean;
|
||||
---C++: inline
|
||||
---Purpose : Decodes the status of the last FixSmallEdges.
|
||||
-- OK - No small edges were found
|
||||
-- DONE1 - Some small edges were fixed
|
||||
-- FAIL1 - Failed to fix some small edges
|
||||
|
||||
Shape (me : mutable) returns Shape from TopoDS;
|
||||
---C++: inline
|
||||
|
||||
ModeDropSmallEdges(me : mutable) returns Boolean;
|
||||
---C++: return &
|
||||
---C++: inline
|
||||
---Purpose: Returns mode managing removing small edges.
|
||||
|
||||
SetLimitAngle(me:mutable; theLimitAngle : Real);
|
||||
---C++: inline
|
||||
---Purpose:Set limit angle for merging edges.
|
||||
|
||||
LimitAngle(me) returns Real;
|
||||
---C++: inline
|
||||
---Purpose:Get limit angle for merging edges.
|
||||
|
||||
|
||||
|
||||
fields
|
||||
|
||||
myShape : Shape from TopoDS is protected;
|
||||
myModeDrop : Boolean;
|
||||
myLimitAngle : Real;
|
||||
myStatusWireGaps : Integer from Standard;
|
||||
myStatusSmallEdges : Integer from Standard;
|
||||
|
||||
end Wireframe;
|
1524
src/ShapeFix/ShapeFix_Wireframe.cxx
Executable file
1524
src/ShapeFix/ShapeFix_Wireframe.cxx
Executable file
File diff suppressed because it is too large
Load Diff
62
src/ShapeFix/ShapeFix_Wireframe.lxx
Executable file
62
src/ShapeFix/ShapeFix_Wireframe.lxx
Executable file
@@ -0,0 +1,62 @@
|
||||
#include <ShapeExtend.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : StatusWireGaps
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean ShapeFix_Wireframe::StatusWireGaps
|
||||
(const ShapeExtend_Status status) const
|
||||
{
|
||||
return ShapeExtend::DecodeStatus( myStatusWireGaps, status );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : StatusSmallEdges
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean ShapeFix_Wireframe::StatusSmallEdges
|
||||
(const ShapeExtend_Status status) const
|
||||
{
|
||||
return ShapeExtend::DecodeStatus( myStatusSmallEdges, status );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Shape
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline TopoDS_Shape ShapeFix_Wireframe::Shape()
|
||||
{
|
||||
return myShape;
|
||||
}
|
||||
//=======================================================================
|
||||
//function : ModeDropSmallEdges
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean& ShapeFix_Wireframe::ModeDropSmallEdges()
|
||||
{
|
||||
return myModeDrop;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : SetLimitAngle
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline void ShapeFix_Wireframe::SetLimitAngle(const Standard_Real theLimitAngle)
|
||||
{
|
||||
myLimitAngle = theLimitAngle;
|
||||
}
|
||||
//=======================================================================
|
||||
//function : LimitAngle
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Real ShapeFix_Wireframe::LimitAngle() const
|
||||
{
|
||||
return myLimitAngle;
|
||||
}
|
Reference in New Issue
Block a user