1
0
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:
bugmaster
2011-03-16 07:30:28 +00:00
committed by bugmaster
parent 4903637061
commit 7fd59977df
16375 changed files with 3882564 additions and 0 deletions

1
src/ShapeFix/FILES Executable file
View File

@@ -0,0 +1 @@
ShapeFix_Wire_1.cxx

145
src/ShapeFix/ShapeFix.cdl Executable file
View 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
View 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;
}

View 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;

File diff suppressed because it is too large Load Diff

193
src/ShapeFix/ShapeFix_Edge.cdl Executable file
View 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
View 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);
}

View 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;

View 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();
}

View 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;

View 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
View 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

File diff suppressed because it is too large Load Diff

131
src/ShapeFix/ShapeFix_Face.lxx Executable file
View 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;
}

View 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;

View 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();
}

View 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;

View 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;
}

View 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;

View 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;
}

View 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;
}

View 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;

File diff suppressed because it is too large Load Diff

View 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
View 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
View 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
View 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
View 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
View 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
View 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;
}

View 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;

View 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
View 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

File diff suppressed because it is too large Load Diff

34
src/ShapeFix/ShapeFix_Shell.lxx Executable file
View 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
View 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
View 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
View 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;
}

View 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;

View 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;
}

View 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;

View 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
View 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

File diff suppressed because it is too large Load Diff

537
src/ShapeFix/ShapeFix_Wire.lxx Executable file
View 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;
}

View 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;

View 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();
}

View 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;

View 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

File diff suppressed because it is too large Load Diff

View 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;

File diff suppressed because it is too large Load Diff

View 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;
}