0022746: Progress indicator in ShapeHealing
authorKGV and DBV <>
Fri, 18 Nov 2011 14:51:14 +0000 (14:51 +0000)
committerbugmaster <bugmaster@opencascade.com>
Mon, 5 Mar 2012 15:31:13 +0000 (19:31 +0400)
23 files changed:
src/IGESControl/IGESControl_ActorWrite.cxx
src/IGESControl/IGESControl_Writer.cxx
src/IGESToBRep/IGESToBRep_Actor.cxx
src/IGESToBRep/IGESToBRep_Reader.cxx
src/STEPControl/STEPControl_ActorRead.cxx
src/STEPControl/STEPControl_ActorWrite.cxx
src/SWDRAW/SWDRAW.cxx
src/SWDRAW/SWDRAW_ShapeFix.cxx
src/ShapeFix/ShapeFix.cdl
src/ShapeFix/ShapeFix.cxx
src/ShapeFix/ShapeFix_Shape.cdl
src/ShapeFix/ShapeFix_Shape.cxx
src/ShapeFix/ShapeFix_Shell.cdl
src/ShapeFix/ShapeFix_Shell.cxx
src/ShapeFix/ShapeFix_Solid.cdl
src/ShapeFix/ShapeFix_Solid.cxx
src/ShapeProcess/ShapeProcess.cxx
src/ShapeProcess/ShapeProcess_Context.cdl
src/ShapeProcess/ShapeProcess_Context.cxx
src/ShapeProcess/ShapeProcess_OperLibrary.cxx
src/XSAlgo/XSAlgo.cdl
src/XSAlgo/XSAlgo_AlgoContainer.cdl
src/XSAlgo/XSAlgo_AlgoContainer.cxx

index d294edd..aebd056 100755 (executable)
@@ -53,7 +53,8 @@ Handle(Transfer_Binder)  IGESControl_ActorWrite::Transfer
     Standard_Real maxTol = Interface_Static::RVal("read.maxprecision.val");
     shape = XSAlgo::AlgoContainer()->ProcessShape( shape, Tol, maxTol, 
                                                    "write.iges.resource.name", 
-                                                   "write.iges.sequence", info );
+                                                   "write.iges.sequence", info,
+                                                   FP->GetProgress() );
 //  modified by NIZHNY-EAP Tue Aug 29 11:17:01 2000 ___END___
 
     BRepToIGES_BREntity   BR0; BR0.SetModel(modl);  BR0.SetTransferProcess(FP);
index 6e97d2e..408800c 100755 (executable)
@@ -101,7 +101,8 @@ Standard_Boolean IGESControl_Writer::AddShape (const TopoDS_Shape& theShape)
   Standard_Real maxTol = Interface_Static::RVal("read.maxprecision.val");
   TopoDS_Shape Shape = XSAlgo::AlgoContainer()->ProcessShape( theShape, Tol, maxTol, 
                                                               "write.iges.resource.name", 
-                                                              "write.iges.sequence", info );
+                                                              "write.iges.sequence", info,
+                                                              progress );
   //  modified by NIZHNY-EAP Tue Aug 29 11:17:01 2000 ___END___
   Handle(IGESData_IGESEntity) ent; 
   BRepToIGES_BREntity   B0;  B0.SetTransferProcess(theTP); B0.SetModel(themod);
index 5246bff..a50c6d1 100755 (executable)
@@ -1,27 +1,28 @@
-#include <Standard_ErrorHandler.hxx>
 #include <IGESToBRep_Actor.ixx>
-#include <Standard_Failure.hxx>
-
 #include <IGESToBRep.hxx>
 #include <IGESData_IGESEntity.hxx>
 #include <IGESData_IGESModel.hxx>
 #include <IGESData_GlobalSection.hxx>
-
 #include <IGESToBRep_CurveAndSurface.hxx>
 
+#include <BRepLib.hxx>
+
+#include <Standard_Failure.hxx>
+#include <Standard_ErrorHandler.hxx>
+#include <ShapeExtend_Explorer.hxx>
+#include <ShapeFix_ShapeTolerance.hxx>
+
 #include <Interface_Macros.hxx>
 #include <Interface_Static.hxx>
 
-#include <TopoDS_Shape.hxx>
+#include <Message_ProgressSentry.hxx>
 
+#include <TopoDS_Shape.hxx>
 #include <TransferBRep.hxx>
 #include <TransferBRep_ShapeBinder.hxx>
 
 #include <XSAlgo.hxx>
 #include <XSAlgo_AlgoContainer.hxx>
-#include <ShapeFix_ShapeTolerance.hxx>
-#include <BRepLib.hxx>
-#include <ShapeExtend_Explorer.hxx>
 
 //=======================================================================
 //function : IGESToBRep_Actor
@@ -144,6 +145,10 @@ Handle(Transfer_Binder) IGESToBRep_Actor::Transfer
       (typnum == 402 && (fornum == 1 || fornum == 7|| 
                          fornum == 14 || fornum == 15)) || 
       (typnum == 408) || (typnum == 308)) {
+
+    // Start progress scope (no need to check if progress exists -- it is safe)
+    Message_ProgressSentry aPSentry(TP->GetProgress(), "Transfer stage", 0, 2, 1);
+
     XSAlgo::AlgoContainer()->PrepareForTransfer();
     IGESToBRep_CurveAndSurface CAS;
     CAS.SetModel(mymodel);
@@ -175,16 +180,19 @@ Handle(Transfer_Binder) IGESToBRep_Actor::Transfer
        shape.Nullify();
       }
     }
+
+    // Switch to fix stage.
+    aPSentry.Next();
     
     // fixing shape
-//    shape =  XSAlgo::AlgoContainer()->PerformFixShape( shape, TP, theeps, CAS.GetMaxTol() );
     Handle(Standard_Transient) info;
     shape = XSAlgo::AlgoContainer()->ProcessShape( shape, theeps, CAS.GetMaxTol(), 
                                                    "read.iges.resource.name", 
-                                                   "read.iges.sequence", info );
+                                                   "read.iges.sequence", info,
+                                                   TP->GetProgress() );
     XSAlgo::AlgoContainer()->MergeTransferInfo(TP, info, nbTPitems);
   }
-// if (!shape.IsNull()) TransferBRep::SameParameter (shape,Standard_False,eps);
+
   ShapeExtend_Explorer SBE;
   if (SBE.ShapeType(shape,Standard_True) != TopAbs_SHAPE) {
     if (!shape.IsNull()) {
index 78c0f5f..4e86814 100755 (executable)
@@ -545,7 +545,8 @@ Standard_Boolean  IGESToBRep_Reader::Transfer(const Standard_Integer num)
     Handle(Standard_Transient) info;
     shape = XSAlgo::AlgoContainer()->ProcessShape( shape, eps*CAS.GetUnitFactor(), CAS.GetMaxTol(),
                                                    "read.iges.resource.name", 
-                                                   "read.iges.sequence", info );
+                                                   "read.iges.sequence", info,
+                                                   theProc->GetProgress() );
     XSAlgo::AlgoContainer()->MergeTransferInfo(theProc, info, nbTPitems);
 
     ShapeExtend_Explorer SBE;
index 3d02b54..34eb972 100755 (executable)
@@ -810,9 +810,10 @@ Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::TransferEntity(const Han
     Handle(Standard_Transient) info;
     // IMPORTANT: any fixing on non-manifold topology must be done after the shape is transferred from STEP
     TopoDS_Shape fixedResult = 
-      XSAlgo::AlgoContainer()->ProcessShape(comp, myPrecision, myMaxTol,
-                                           "read.step.resource.name", 
-                                           "read.step.sequence", info);
+      XSAlgo::AlgoContainer()->ProcessShape( comp, myPrecision, myMaxTol,
+                                             "read.step.resource.name", 
+                                             "read.step.sequence", info,
+                                             TP->GetProgress() );
     XSAlgo::AlgoContainer()->MergeTransferInfo(TP, info, nbTPitems);
 
     BRep_Builder brepBuilder;
@@ -1187,6 +1188,10 @@ Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::TransferEntity(const Han
   }
   myShapeBuilder.SetPrecision(myPrecision);
   myShapeBuilder.SetMaxTol(myMaxTol);
+
+  // Start progress scope (no need to check if progress exists -- it is safe)
+  Message_ProgressSentry aPSentry(TP->GetProgress(), "Transfer stage", 0, 2, 1);
+
   try {
     OCC_CATCH_SIGNALS
   if (start->IsKind(STANDARD_TYPE(StepShape_FacetedBrep))) {
@@ -1227,6 +1232,8 @@ Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::TransferEntity(const Han
     TP->Bind(start, shbinder);
     return shbinder;
   }
+
+  aPSentry.Next();
   
   if (found && myShapeBuilder.IsDone()) {
     mappedShape = myShapeBuilder.Value();
@@ -1234,9 +1241,10 @@ Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::TransferEntity(const Han
     if (isManifold) {
       Handle(Standard_Transient) info;
       mappedShape = 
-        XSAlgo::AlgoContainer()->ProcessShape(mappedShape, myPrecision, myMaxTol,
-                                             "read.step.resource.name", 
-                                             "read.step.sequence", info);
+        XSAlgo::AlgoContainer()->ProcessShape( mappedShape, myPrecision, myMaxTol,
+                                               "read.step.resource.name", 
+                                               "read.step.sequence", info,
+                                               TP->GetProgress() );
       XSAlgo::AlgoContainer()->MergeTransferInfo(TP, info, nbTPitems);
     }
   }
@@ -1365,8 +1373,9 @@ Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::TransferEntity(const Han
     
     Handle(Standard_Transient) info;
     TopoDS_Shape shape = XSAlgo::AlgoContainer()->ProcessShape( S, myPrecision, myMaxTol,
-                                                               "read.step.resource.name", 
-                                                               "read.step.sequence", info );
+                                                                "read.step.resource.name", 
+                                                                "read.step.sequence", info,
+                                                                TP->GetProgress() );
     //      TopoDS_Shape shape = XSAlgo::AlgoContainer()->PerformFixShape( S, TP, myPrecision, myMaxTol );
     if ( shape != S ) 
       sb->SetResult ( shape );
index cd63114..fba328a 100755 (executable)
@@ -863,7 +863,8 @@ Handle(Transfer_Binder) STEPControl_ActorWrite::TransferShape (const Handle(Tran
     if (isManifold)
       aShape = XSAlgo::AlgoContainer()->ProcessShape(xShape, Tol, maxTol, 
                                                     "write.step.resource.name", 
-                                                    "write.step.sequence", info);
+                                                    "write.step.sequence", info,
+                                                    FP->GetProgress() );
     else
       aShape = xShape;
     
index dfd1a49..87981f5 100755 (executable)
@@ -32,6 +32,8 @@
 #include <XSAlgo.hxx>
 #include <XSAlgo_AlgoContainer.hxx>
 
+#include <Draw_ProgressIndicator.hxx>
+
 static int dejadraw = 0;
 
 //=======================================================================
@@ -168,8 +170,9 @@ static Standard_Integer NSPApply (Draw_Interpretor& di, Standard_Integer argc, c
 
   XSAlgo::AlgoContainer()->PrepareForTransfer();
   Handle(Standard_Transient) info;  // reserved for special uses
+  Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (di, 1);
   newshape = XSAlgo::AlgoContainer()->ProcessShape
-    ( shape, tol, maxtol, argv[3] , argv[4] , info);
+    ( shape, tol, maxtol, argv[3] , argv[4] , info, aProgress);
 //    WHAT IS MISSING HERE IS MERGING with starting transfer map
 
   if (newshape.IsNull()) {
index 1175e1e..13a4493 100755 (executable)
@@ -44,6 +44,8 @@
 #include <TopTools_DataMapOfShapeListOfShape.hxx>
 #include <TopAbs_State.hxx>
 
+#include <Draw_ProgressIndicator.hxx>
+
 #ifdef AIX
 #include <strings.h>
 #endif
@@ -437,10 +439,11 @@ static Standard_Integer fixshape (Draw_Interpretor& di, Standard_Integer argc, c
     di << "For enhanced message output, use switch '+?'" << "\n"; 
     return 1;
   }
-  
-  sfs->Perform();
+
+  Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (di, 1);
+  sfs->Perform (aProgress);
   DBRep::Set (res,sfs->Shape());
-  
+
   if ( mess ) {
     Standard_Integer num = 0;
     const ShapeExtend_DataMapOfShapeListOfMsg &map = msg->MapShape();
index a23e096..79da826 100755 (executable)
@@ -4,15 +4,14 @@
 --             <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
+  ---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
@@ -47,31 +46,31 @@ is
        ---Purpose: Fixing different problems on edge
        
     class Wire;
-        ---Purpose: Fixing different problems with wires
+      ---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
+      ---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
+      ---Purpose: Provides methods to fix wireframe of shape
     
     class FreeBounds;
-       ---Purpose: Fixing free bounds of the shape (connecting open wires)
+      ---Purpose: Fixing free bounds of the shape (connecting open wires)
 
     class FaceConnect;
-        ---Purpose: Rebuilds connectivity between faces in shell
+      ---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
+      ---Purpose: Creating solid from shell and orienting it to have finite volume
        
     class ShapeTolerance;
        ---Purpose: Modifying shape tolerances
@@ -87,21 +86,18 @@ is
 
     class SplitCommonVertex;
        ---Purpose: Splits vertex which is common for two wires
-       --          (for writing into STEP)
+      --          (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
+      --          and intersecting wires
        
     class SplitTool;
        ---Purpose: Tool for splitting and cutting edges; incudes methods
-       --          used in OverlappingTool and IntersectionTool
+      --          used in OverlappingTool and IntersectionTool
        
     class SequenceOfWireSegment instantiates Sequence from TCollection
        (WireSegment from ShapeFix);
@@ -110,9 +106,10 @@ is
        (Shape from TopoDS, Box2d from Bnd, ShapeMapHasher from TopTools);
 
 
-    SameParameter (shape  : Shape from TopoDS;
-                  enforce: Boolean;
-                  preci  : Real = 0.0)
+    SameParameter (shape       : Shape from TopoDS;
+                   enforce     : Boolean;
+                   preci       : Real = 0.0;
+                   theProgress : ProgressIndicator from Message = 0)
     returns Boolean;
        ---Purpose : Runs SameParameter from BRepLib with these adaptations :
        --           <enforce> forces computations, else they are made only on
@@ -121,25 +118,27 @@ is
        --           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
+       --           been processed. The passed progress indicator allows user
+       --           to consult the current progress stage and abort algorithm
+       --           if needed.
 
     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
+      --           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()
+      ---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.;       
+      ---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;       
+      ---Purpose: Calculate size of least edge;       
         
 
 end ShapeFix;
index 606a0af..75a6ca4 100755 (executable)
@@ -59,6 +59,7 @@
 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
 #include <TopExp.hxx>
 
+#include <Message_ProgressSentry.hxx>
 
 //=======================================================================
 //function : SameParameter
 
 Standard_Boolean ShapeFix::SameParameter(const TopoDS_Shape& shape,
                                          const Standard_Boolean enforce,
-                                         const Standard_Real preci)
+                                         const Standard_Real preci,
+                                         const Handle(Message_ProgressIndicator)& theProgress)
 {
+  // Calculate number of edges
+  Standard_Integer aNbEdges = 0;
+  for ( TopExp_Explorer anEdgeExp(shape, TopAbs_EDGE); anEdgeExp.More(); anEdgeExp.Next() )
+    ++aNbEdges;
+
+  // Calculate number of faces
+  Standard_Integer aNbFaces = 0;
+  for ( TopExp_Explorer anEdgeExp(shape, TopAbs_FACE); anEdgeExp.More(); anEdgeExp.Next() )
+    ++aNbFaces;
+
   BRep_Builder B;
   //Standard_Integer nbexcp = 0; 
   Standard_Integer nbfail = 0,  numedge = 0; 
@@ -78,88 +90,118 @@ Standard_Boolean ShapeFix::SameParameter(const TopoDS_Shape& shape,
   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
-  }
+  // Start progress scope (no need to check if progress exists -- it is safe)
+  Message_ProgressSentry aPSentry(theProgress, "Fixing same parameter problem", 0, 2, 1);
 
-  //: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;
+  {
+    // Start progress scope (no need to check if progress exists -- it is safe)
+    Message_ProgressSentry aPSentry(theProgress, "Fixing edge", 0, aNbEdges, 1);
+
+    while ( ex.More() )
+    {
+      TopoDS_Edge E;
+      while ( ex.More() && aPSentry.More() )
+      {
+        numedge ++;
+        int ierr = 0;
+        TopLoc_Location loc;
+        E = TopoDS::Edge (ex.Current());
+        ex.Next();
+       
+        if (!iatol)
+          tol = BRep_Tool::Tolerance (E);
+        if (enforce)
+        {
+          B.SameRange     (E,Standard_False);
+          B.SameParameter (E,Standard_False);
+        }
+
+        sfe->FixSameParameter (E); // 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);
+        }
+
+        // Complete step in current progress scope
+        aPSentry.Next();     
+      } // -- end while
+
+      // Halt algorithm in case of user's abort
+      if ( !aPSentry.More() )
+        return Standard_False;
     }
-      
-//      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;
+
+  }
+  // Switch to "Update tolerances" step
+  aPSentry.Next();
+
+  {
+    // Start progress scope (no need to check if progress exists -- it is safe)
+    Message_ProgressSentry aPSentry(theProgress, "Update tolerances", 0, aNbFaces, 1);
+
+    //: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() && aPSentry.More(); exp.Next(), aPSentry.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;
       }
-      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 );
-       }
+
+      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 = 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);
+       
+        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 );
+          }
+        }
       }
+
+      // Halt algorithm in case of user's abort
+      if ( !aPSentry.More() )
+        return Standard_False;
     }
   }
 
@@ -167,7 +209,6 @@ Standard_Boolean ShapeFix::SameParameter(const TopoDS_Shape& shape,
 #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
   }
index cff67af..d43d4e0 100755 (executable)
@@ -19,8 +19,9 @@ uses
     Edge                from ShapeFix,
     Status              from ShapeExtend,
     MapOfShape from TopTools,
-    BasicMsgRegistrator from ShapeExtend
-    
+    BasicMsgRegistrator from ShapeExtend,
+    ProgressIndicator   from Message
+
 is
 
     Create returns Shape from ShapeFix;
@@ -33,10 +34,17 @@ is
     Init (me: mutable; shape: Shape from TopoDS);
        ---Purpose: Initislises by shape.
 
-    Perform (me: mutable) returns Boolean;
+    Perform (me          : mutable;
+             theProgress : ProgressIndicator from Message = 0) returns Boolean;
        ---Purpose: Iterates on sub- shape and performs fixes
 
-    SameParameter (me: mutable; shape: Shape from TopoDS; force: Boolean) is protected;
+    SameParameter (me          : mutable; 
+                   shape       : Shape from TopoDS; 
+                   enforce     : Boolean;
+                   theProgress : ProgressIndicator from Message = 0) is protected;
+      ---Purpose: Fixes same parameterization problem on the passed shape
+      --          by updating tolerances of the corresponding topological
+      --          entitites.
 
     Shape (me) returns Shape from TopoDS;
        ---Purpose: Returns resulting shape
index b2f97d3..2bb7b95 100755 (executable)
@@ -26,6 +26,8 @@
 #include <ShapeFix_Shell.hxx>
 #include <ShapeFix_Solid.hxx>
 
+#include <Message_ProgressSentry.hxx>
+
 //=======================================================================
 //function : ShapeFix_Shape
 //purpose  : 
@@ -81,11 +83,11 @@ void ShapeFix_Shape::Init(const TopoDS_Shape& shape)
 //purpose  : 
 //=======================================================================
 
-Standard_Boolean ShapeFix_Shape::Perform() 
+Standard_Boolean ShapeFix_Shape::Perform(const Handle(Message_ProgressIndicator)& theProgress
 {
   Standard_Integer savFixSmallAreaWireMode = 0;
 
-  Handle(ShapeFix_Face) fft = Handle(ShapeFix_Face)::DownCast ( FixFaceTool() );
+  Handle(ShapeFix_Face) fft = Handle(ShapeFix_Face)::DownCast( FixFaceTool() );
   if ( !fft.IsNull() ) {
     savFixSmallAreaWireMode = fft->FixSmallAreaWireMode();
     if ( savFixSmallAreaWireMode == -1 &&
@@ -117,41 +119,60 @@ Standard_Boolean ShapeFix_Shape::Perform()
     ShapeFix::FixVertexPosition(S,Precision(),Context());
 
   st = S.ShapeType();
+
+  // Open progress indication scope for the following fix stages:
+  // - Fix on Solid or Shell;
+  // - Fix same parameterization;
+  Message_ProgressSentry aPSentry(theProgress, "Fixing stage", 0, 2, 1);
+
   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;
+
+    Standard_Integer aShapesNb = 0;
+    for ( TopoDS_Iterator anIter(S); anIter.More(); anIter.Next() )
+      ++aShapesNb;
+
+    // Open progress indication scope for sub-shape fixing
+    Message_ProgressSentry aPSentry(theProgress, "Fixing sub-shape", 0, aShapesNb, 1);
+    for ( TopoDS_Iterator anIter(S); anIter.More() && aPSentry.More(); anIter.Next(), aPSentry.Next() )
+    {
+      myShape = anIter.Value();
+      if ( Perform(theProgress) )
+        status = Standard_True;
     }
+    if ( !aPSentry.More() )
+      return Standard_False; // aborted execution
+
     myFixSameParameterMode = savFixSameParameterMode;
     myShape = shape;
-//    myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE5 );
     break;
   }
   case TopAbs_SOLID: {  
-    if ( ! NeedFix ( myFixSolidMode ) ) break;
+    if ( !NeedFix(myFixSolidMode) )
+      break;
     myFixSolid->Init(TopoDS::Solid(S)); 
     myFixSolid->SetContext(Context());
-    if(myFixSolid->Perform()) {
-//      Context()->Replace(S,myFixSolid->Solid());
+
+    if ( myFixSolid->Perform(theProgress) )
       status = Standard_True;
-    }
+
     myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
     break;
   }
   case TopAbs_SHELL:  {
-    if ( ! NeedFix ( myFixShellMode ) ) break;
+    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());
+    sfsh->Init( TopoDS::Shell(S) ); 
+    sfsh->SetContext( Context() );
+
+    if ( sfsh->Perform(theProgress) )
       status = Standard_True;
-    }
+
     myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
     break;
   }
@@ -162,8 +183,8 @@ Standard_Boolean ShapeFix_Shape::Perform()
     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;
@@ -178,7 +199,6 @@ Standard_Boolean ShapeFix_Shape::Perform()
     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());
@@ -201,10 +221,16 @@ Standard_Boolean ShapeFix_Shape::Perform()
   case TopAbs_SHAPE :    
   default           : break;
   }
+
+  // Switch to the second progress indication scope if it exists
+  aPSentry.Next();
   
-  myResult  = Context()->Apply(S);  
-  if ( NeedFix ( myFixSameParameterMode ) ) 
-    SameParameter (myResult,Standard_False);
+  myResult = Context()->Apply(S);  
+
+  if ( NeedFix(myFixSameParameterMode) )
+  {
+    SameParameter(myResult, Standard_False, theProgress);
+  }
 
   if ( !fft.IsNull() )
     fft->FixSmallAreaWireMode() = savFixSmallAreaWireMode;
@@ -217,9 +243,11 @@ Standard_Boolean ShapeFix_Shape::Perform()
 //purpose  : 
 //=======================================================================
 
-void ShapeFix_Shape::SameParameter(const TopoDS_Shape& sh, const Standard_Boolean enforce)
+void ShapeFix_Shape::SameParameter(const TopoDS_Shape& sh,
+                                   const Standard_Boolean enforce,
+                                   const Handle(Message_ProgressIndicator)& theProgress)
 {
-  ShapeFix::SameParameter(sh, enforce);
+  ShapeFix::SameParameter(sh, enforce, 0.0, theProgress);
 }
 
 //=======================================================================
index dbb5afc..35eda9d 100755 (executable)
@@ -16,7 +16,9 @@ uses
     Shape               from TopoDS,
     Status              from ShapeExtend,
     BasicMsgRegistrator from ShapeExtend,
-    Face                from ShapeFix
+    Face                from ShapeFix,
+    ProgressIndicator   from Message
+    
 is
 
     Create returns Shell from ShapeFix;
@@ -29,33 +31,36 @@ is
     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)
+    Perform (me: mutable;
+             theProgress : ProgressIndicator from Message = 0) returns Boolean;
+        ---Purpose: Iterates on subshapes and performs fixes
+        --          (for each face calls ShapeFix_Face::Perform and
+        --          then calls FixFaceOrientation). The passed progress
+        --          indicator allows user to consult the current progress
+        --          stage and abort algorithm if needed.
 
     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
+      ---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).
@@ -74,10 +79,10 @@ is
 
     FixFaceTool (me:mutable) returns Face from ShapeFix;
        ---Purpose: Returns tool for fixing faces.
-       ---C++:inline
+      ---C++:inline
 
     SetMsgRegistrator (me: mutable; msgreg: BasicMsgRegistrator from ShapeExtend) is redefined;
-       ---Purpose: Sets message registrator
+      ---Purpose: Sets message registrator
 
     SetPrecision (me: mutable; preci: Real) is redefined;
        ---Purpose: Sets basic precision value (also to FixWireTool)
@@ -90,15 +95,15 @@ is
 
     FixFaceMode (me: mutable) returns Integer;
        ---C++: return &
-       ---C++: inline
-        ---Purpose: Returns (modifiable) the mode for applying fixes of 
-        --          ShapeFix_Face, by default True.
+      ---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.
+      ---C++: inline
+      ---Purpose: Returns (modifiable) the mode for applying 
+      --          FixFaceOrientation, by default True.
     
 fields
 
@@ -108,5 +113,6 @@ fields
     myFixFace            : Face from ShapeFix is protected;
     myFixFaceMode        : Integer is protected;   
     myFixOrientationMode : Integer is protected; 
-    myNbShells : Integer is protected; 
+    myNbShells           : Integer is protected; 
+
 end Shell;
index 72ada38..f49a2dc 100755 (executable)
@@ -33,6 +33,7 @@
 #include <ShapeExtend.hxx>
 #include <ShapeBuild_ReShape.hxx> 
 #include <Message_Msg.hxx>
+#include <Message_ProgressSentry.hxx>
 #include <TopTools_DataMapOfShapeInteger.hxx>
 #include <TopTools_DataMapOfShapeInteger.hxx>
 #include <TopTools_DataMapOfShapeInteger.hxx>
@@ -93,26 +94,40 @@ void ShapeFix_Shell::Init(const TopoDS_Shell& shell)
 //purpose  : 
 //=======================================================================
 
-Standard_Boolean ShapeFix_Shell::Perform() 
+Standard_Boolean ShapeFix_Shell::Perform(const Handle(Message_ProgressIndicator)& theProgress
 {
   Standard_Boolean status = Standard_False;
-  if(Context().IsNull())
-    SetContext ( new ShapeBuild_ReShape );
+  if ( Context().IsNull() )
+    SetContext(new ShapeBuild_ReShape);
   myFixFace->SetContext(Context());
-  if ( NeedFix ( myFixFaceMode ) ) {
-    TopoDS_Shape S = Context()->Apply ( myShell );
-    for( TopoDS_Iterator iter(S); iter.More(); iter.Next()) { 
+
+  if ( NeedFix(myFixFaceMode) )
+  {
+    TopoDS_Shape S = Context()->Apply(myShell);
+
+    // Get the number of faces for progress indication
+    Standard_Integer aNbFaces = 0;
+    for ( TopExp_Explorer aFaceExp(S, TopAbs_FACE); aFaceExp.More(); aFaceExp.Next() )
+      ++aNbFaces;
+
+    // Start progress scope (no need to check if progress exists -- it is safe)
+    Message_ProgressSentry aPSentry(theProgress, "Fixing face", 0, aNbFaces, 1);
+
+    for( TopoDS_Iterator iter(S); iter.More() && aPSentry.More(); iter.Next(), aPSentry.Next() )
+    { 
       TopoDS_Shape sh = iter.Value();
       TopoDS_Face tmpFace = TopoDS::Face(sh);
       myFixFace->Init(tmpFace);
-//      myFixFace->SetPrecision(Precision());
-      if(myFixFace->Perform()) {
-//     if(!Context().IsNull())
-//       Context()->Replace(tmpFace,myFixFace->Face());
-       status = Standard_True;
-       myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
+      if ( myFixFace->Perform() )
+      {
+        status = Standard_True;
+        myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
       }
     }
+
+    // Halt algorithm in case of user's abort
+    if ( !aPSentry.More() )
+      return Standard_False;
   }
   TopoDS_Shape newsh = Context()->Apply(myShell);
   if ( NeedFix ( myFixOrientationMode) )
index f7ee172..269afa4 100755 (executable)
@@ -17,7 +17,8 @@ uses
     Shape               from TopoDS,
     Shell               from ShapeFix,
     Status              from ShapeExtend,
-    BasicMsgRegistrator from ShapeExtend
+    BasicMsgRegistrator from ShapeExtend,
+    ProgressIndicator   from Message
 
 is
     Create returns Solid from ShapeFix;
@@ -29,9 +30,12 @@ is
     Init(me: mutable; solid : Solid from TopoDS) is virtual;
        ---Purpose: Initializes by solid .
     
-    Perform(me: mutable) returns Boolean is virtual;
+    Perform(me: mutable;
+            theProgress : ProgressIndicator from Message = 0) returns Boolean is virtual;
        ---Purpose: Iterates on shells and performs fixes
-       --          (calls ShapeFix_Shell for each subshell)
+      --          (calls ShapeFix_Shell for each subshell). The passed
+      --          progress indicator allows user to consult the current
+      --          progress stage and abort algorithm if needed.
        
     SolidFromShell (me: mutable; shell: Shell from TopoDS)
     returns Solid from TopoDS;
@@ -45,10 +49,10 @@ is
      
     FixShellTool (me) returns Shell from ShapeFix;
        ---Purpose: Returns tool for fixing shells.
-       ---C++:inline
+      ---C++:inline
          
     SetMsgRegistrator (me: mutable; msgreg: BasicMsgRegistrator from ShapeExtend) is redefined;
-       ---Purpose: Sets message registrator
+      ---Purpose: Sets message registrator
        
     SetPrecision (me: mutable; preci: Real) is redefined;
        ---Purpose: Sets basic precision value (also to FixShellTool)
@@ -61,17 +65,17 @@ is
        
     FixShellMode (me: mutable) returns Integer;
        ---C++: return &
-       ---C++: inline
-        ---Purpose: Returns (modifiable) the mode for applying fixes of 
-        --          ShapeFix_Shell, by default True.
+      ---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.
+      ---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.
index 3a269a7..ad5ee8b 100755 (executable)
 #include <TopTools_IndexedMapOfShape.hxx>
 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
 #include <Message_Msg.hxx>
+#include <Message_ProgressSentry.hxx>
 #include <TopoDS_Vertex.hxx>
 #include <TopTools_IndexedMapOfShape.hxx>
 
 #include <TopTools_DataMapOfShapeInteger.hxx>
 #include <Geom_Curve.hxx>
 #include <ShapeAnalysis_FreeBounds.hxx>
-
   
 //======================================================
 //function : ShapeFix_Solid
@@ -341,36 +341,55 @@ static Standard_Boolean CreateSolids(const TopoDS_Shape aShape,TopTools_IndexedM
 //purpose  : 
 //=======================================================================
 
-Standard_Boolean ShapeFix_Solid::Perform() 
+Standard_Boolean ShapeFix_Solid::Perform(const Handle(Message_ProgressIndicator)& theProgress
 {
 
   Standard_Boolean status = Standard_False;
-  if(Context().IsNull())
+  if ( Context().IsNull() )
     SetContext ( new ShapeBuild_ReShape );
   myFixShell->SetContext(Context());
-  Standard_Integer NbShells =0;
+
+  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());
+
+  // Calculate number of underlying shells
+  Standard_Integer aNbShells = 0;
+  for ( TopExp_Explorer aExpSh(S, TopAbs_SHELL); aExpSh.More(); aExpSh.Next() )
+    aNbShells++;
+
+  // Start progress scope (no need to check if progress exists -- it is safe)
+  Message_ProgressSentry aPSentry(theProgress, "Fixing solid stage", 0, 2, 1);
+
+  if ( NeedFix(myFixShellMode) )
+  {
+    // Start progress scope (no need to check if progress exists -- it is safe)
+    Message_ProgressSentry aPSentry(theProgress, "Fixing shell", 0, aNbShells, 1);
+
+    // Fix shell by shell using ShapeFix_Shell tool
+    for ( TopExp_Explorer aExpSh(S, TopAbs_SHELL); aExpSh.More() && aPSentry.More(); aExpSh.Next(), aPSentry.Next() )
+    { 
+      TopoDS_Shape sh = aExpSh.Current();
+
+      myFixShell->Init( TopoDS::Shell(sh) );
+      if ( myFixShell->Perform(theProgress) )
+      {
         status = Standard_True;
         myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
       }
       NbShells+= myFixShell->NbShells();
     }
+
+    // Halt algorithm in case of user's abort
+    if ( !aPSentry.More() )
+      return Standard_False;
   }
-  else {
-    for(TopExp_Explorer aExpSh(myShape,TopAbs_SHELL); aExpSh.More(); aExpSh.Next())
-      NbShells++;
+  else 
+  {
+    NbShells = aNbShells;
   }
-  //if(!status) return status;
+
+  // Switch to the second stage
+  aPSentry.Next();
     
   if(NbShells ==1) {
     TopoDS_Shape tmpShape = Context()->Apply(myShape);
@@ -441,7 +460,11 @@ Standard_Boolean ShapeFix_Solid::Perform()
         BRep_Builder aB;
         TopoDS_Compound aComp;
         aB.MakeCompound(aComp);
-        for(Standard_Integer i =1; i <= aMapSolids.Extent(); i++) {
+        Message_ProgressSentry aPSentry(theProgress, "Creating solid",
+                                        0, aMapSolids.Extent(), 1);
+        for(Standard_Integer i =1; (i <= aMapSolids.Extent()) && (aPSentry.More()); 
+            i++, aPSentry.Next()) 
+        {
           TopoDS_Shape aResSh =aMapSolids.FindKey(i);
           if(aResShape.ShapeType() == TopAbs_SHELL && myCreateOpenSolidMode) {
             aResSh.Closed(Standard_False);
@@ -456,6 +479,8 @@ Standard_Boolean ShapeFix_Solid::Perform()
           aB.Add(aComp,aResSh);
           
         }
+        if ( !aPSentry.More() )
+          return Standard_False; // aborted execution
         Context()->Replace(aResShape,aComp);
       }
     }
index 59180fc..bcda645 100755 (executable)
@@ -118,7 +118,8 @@ Standard_Boolean ShapeProcess::Perform (const Handle(ShapeProcess_Context)& cont
     context->SetScope ( oper.ToCString() );
     try {
       OCC_CATCH_SIGNALS
-      op->Perform ( context );
+      if ( !op->Perform(context) )
+        return Standard_False;
     }
     catch (Standard_Failure) {
       Message_Msg SMSG2 ("Sequence.MSG2"); //Operator %s failed with exception %s
index 7632179..7d677ce 100755 (executable)
@@ -16,10 +16,11 @@ class Context from ShapeProcess inherits TShared from MMgt
 
 uses
 
-    Manager from Resource,
-    AsciiString from TCollection,
+    Manager                 from Resource,
+    AsciiString             from TCollection,
     HSequenceOfHAsciiString from TColStd,
-    Messenger from Message
+    Messenger               from Message,
+    ProgressIndicator       from Message
 
 is
 
@@ -75,6 +76,12 @@ is
 
     Messenger (me) returns Messenger from Message;
     ---Purpose : Returns Messenger used for outputting messages.
+    
+    SetProgress (me: mutable; theProgress: ProgressIndicator from Message);
+    ---Purpose : Sets Progress Indicator.
+
+    Progress (me) returns ProgressIndicator from Message;
+    ---Purpose : Returns Progress Indicator.
 
     SetTraceLevel (me: mutable; tracelev: Integer);
     ---Purpose : Sets trace level used for outputting messages
@@ -89,9 +96,10 @@ is
 
 fields
 
-    myRC:      Manager from Resource;
-    myScope:   HSequenceOfHAsciiString from TColStd;
+    myRC:        Manager from Resource;
+    myScope:     HSequenceOfHAsciiString from TColStd;
     myMessenger: Messenger from Message;
-    myTraceLev : Integer;
+    myProgress:  ProgressIndicator from Message;
+    myTraceLev:  Integer;
 
 end Context;
index 3783113..e075cce 100755 (executable)
@@ -353,6 +353,26 @@ Handle(Message_Messenger) ShapeProcess_Context::Messenger () const
   return myMessenger;
 }
 
+//=======================================================================
+//function : SetProgress
+//purpose  : 
+//=======================================================================
+
+void ShapeProcess_Context::SetProgress (const Handle(Message_ProgressIndicator)& progress)
+{
+  myProgress = progress;
+}
+
+//=======================================================================
+//function : Progress
+//purpose  : 
+//=======================================================================
+
+Handle(Message_ProgressIndicator) ShapeProcess_Context::Progress() const
+{
+  return myProgress;
+}
+
 //=======================================================================
 //function : SetTraceLevel
 //purpose  : 
index fa33b40..f2b0d11 100755 (executable)
@@ -13,6 +13,8 @@
 #include <BRepLib.hxx>
 
 #include <Message_MsgFile.hxx>
+#include <Message_ProgressIndicator.hxx>
+
 #include <ShapeExtend_MsgRegistrator.hxx>
 #include <ShapeProcess.hxx>
 #include <ShapeProcess_UOperator.hxx>
@@ -109,7 +111,7 @@ static Standard_Boolean directfaces (const Handle(ShapeProcess_Context)& context
   TopoDS_Shape res = ShapeProcess_OperLibrary::ApplyModifier ( ctx->Result(), ctx, DM, map );
   ctx->RecordModification ( map );
   ctx->SetResult ( res );
-  return 0;
+  return Standard_True;
 }
 
 
@@ -623,7 +625,11 @@ static Standard_Boolean fixshape (const Handle(ShapeProcess_Context)& context)
   sfw->FixNonAdjacentIntersectingEdgesMode() = ctx->IntegerVal ( "FixNonAdjacentIntersectingEdgesMode", -1 );
   
   sfs->Init(ctx->Result());
-  sfs->Perform();
+  sfs->Perform(ctx->Progress());
+
+  if ( !ctx->Progress().IsNull() && ctx->Progress()->UserBreak() )
+    return Standard_False;
+
   TopoDS_Shape result = sfs->Shape();
   if ( result != ctx->Result() ) {
     ctx->RecordModification ( sfs->Context(), msg );
index be6d947..b45bb0a 100755 (executable)
@@ -18,15 +18,16 @@ uses
     ShapeExtend,
     ShapeAnalysis,
     ShapeFix,
-    Transfer
+    Transfer,
+    Message
     
 is
 
     enumeration Caller is
        ---Purpose: Identifies the caller of the algorithm
-       DEFAULT,
-       IGES,
-       STEP
+      DEFAULT,
+      IGES,
+      STEP
     end Caller;
 
     class ToolContainer;
index 20861cd..3ef0796 100755 (executable)
@@ -11,18 +11,19 @@ class AlgoContainer from XSAlgo inherits TShared from MMgt
 
 uses
 
-    Curve         from Geom2d,
-    Surface       from Geom,
-    Edge          from TopoDS,
-    Face          from TopoDS,
-    Shape         from TopoDS,
-    Caller        from XSAlgo,
-    ToolContainer from XSAlgo,
-    WireData      from ShapeExtend,
-    Wire          from ShapeAnalysis,
-    Wire          from ShapeFix,
-    TransientProcess from Transfer,
-    FinderProcess from Transfer
+    Curve             from Geom2d,
+    Surface           from Geom,
+    Edge              from TopoDS,
+    Face              from TopoDS,
+    Shape             from TopoDS,
+    Caller            from XSAlgo,
+    ToolContainer     from XSAlgo,
+    WireData          from ShapeExtend,
+    Wire              from ShapeAnalysis,
+    Wire              from ShapeFix,
+    TransientProcess  from Transfer,
+    FinderProcess     from Transfer,
+    ProgressIndicator from Message
     
 is
 
@@ -40,65 +41,59 @@ is
 
     PrepareForTransfer (me) is virtual;
        ---Purpose: Performs actions necessary for preparing environment
-       --          for transfer. Empty in Open version.
+       --          for transfer. Empty in Open version.
        
---    PerformFixShape (me; shape       : Shape from TopoDS;
---                      TP          : TransientProcess from Transfer;
---                      Prec, MaxTol: Real)
---    returns Shape from TopoDS is virtual;
-       ---Purpose: Applies fixes to the shape resulting from transfer,
-       --          and updates map of entity-shape in TP in accordance with 
-       --          substitutions made during fixes (if any)
-
-    ProcessShape (me; shape: Shape from TopoDS; 
-                     Prec, MaxTol: Real;
-                      rscfile: CString;
-                     seq: CString;
-                     info: out Transient)
+    ProcessShape (me; shape:
+                  Shape from TopoDS; 
+                  Prec, MaxTol: Real;
+                  rscfile: CString;
+                  seq: CString;
+                  info: out Transient;
+                  progress: ProgressIndicator from Message = 0)
     returns Shape from TopoDS is virtual;
        ---Purpose: Does shape processing with specified tolerances
        --          and returns resulting shape and associated information 
-        --          in the form of Transient.
-       --          This information should be later transmitted to 
-       --          MergeTransferInfo in order to be recorded in the
-       --          translation map
-       --
-       ---Default behaviour:
-       --          Applies sequence with name identified by parameter named 
-        --          <seq> (see Interface_Static), defined in resource file
-        --          identified by parameter with name <rscfile>, to shape,
-       --          and keeps info of substitutions made during the process.
-       --          The Prec and MaxTol define run-time parameters 
-       --          Runtime.Tolerance and Runtime.MaxTolerance which can be 
-        --          referred from the resource file
-        --          ("param : &Runtime.Tolerance")
-       --          In the info returns ShapeProcess_ShapeContext with recorded
-       --          modifications. If info has already this type on input, uses it.
-       --
-       --          If resource file is not found, or sequence is not defined 
-        --          there, performs default fixes:
-       --        - if <seq> is write.iges.sequence or write.step.sequence, does DirectFaces
-       --        - if <seq> is read.iges.sequence or read.step.sequence, performs FixShape
+      --          in the form of Transient.
+      --          This information should be later transmitted to 
+      --          MergeTransferInfo in order to be recorded in the
+      --          translation map
+      --
+      ---Default behaviour:
+      --          Applies sequence with name identified by parameter named 
+      --          <seq> (see Interface_Static), defined in resource file
+      --          identified by parameter with name <rscfile>, to shape,
+      --          and keeps info of substitutions made during the process.
+      --          The Prec and MaxTol define run-time parameters 
+      --          Runtime.Tolerance and Runtime.MaxTolerance which can be 
+      --          referred from the resource file
+      --          ("param : &Runtime.Tolerance")
+      --          In the info returns ShapeProcess_ShapeContext with recorded
+      --          modifications. If info has already this type on input, uses it.
+      --
+      --          If resource file is not found, or sequence is not defined 
+      --          there, performs default fixes:
+      --        - if <seq> is write.iges.sequence or write.step.sequence, does DirectFaces
+      --        - if <seq> is read.iges.sequence or read.step.sequence, performs FixShape
 
     CheckPCurve (me; edge  : Edge from TopoDS;
-                    face  : Face from TopoDS;
-                    preci : Real;
-                    isSeam: Boolean)
+                 face  : Face from TopoDS;
+                 preci : Real;
+                 isSeam: Boolean)
     returns Boolean is virtual;
        ---Purpose: Checks quality of pcurve of the edge on the given face, 
-        --          and corrects it if necessary.
-       ---Remark : In Open CASCADE does nothing.
+      --          and corrects it if necessary.
+      ---Remark : In Open CASCADE does nothing.
 
     MergeTransferInfo (me; TP : TransientProcess from Transfer;
-                          info: Transient;
-                          startTPitem: Integer = 1) is virtual;
+                       info: Transient;
+                       startTPitem: Integer = 1) is virtual;
     MergeTransferInfo (me; FP : FinderProcess from Transfer;
-                          info: Transient) is virtual;
-       ---Purpose: Updates translation map (TP or FP) with information
-       --          resulting from ShapeProcessing
-       --          Parameter startTPitem can be used for optimisation, to
-       --          restrict modifications to entities stored in TP starting
-       --          from item startTPitem
+                       info: Transient) is virtual;
+       ---Purpose: Updates translation map (TP or FP) with information
+       --          resulting from ShapeProcessing
+       --          Parameter startTPitem can be used for optimisation, to
+       --          restrict modifications to entities stored in TP starting
+       --          from item startTPitem
 
 fields
 
index 4eba3a7..9c5c716 100755 (executable)
@@ -80,16 +80,21 @@ TopoDS_Shape XSAlgo_AlgoContainer::ProcessShape (const TopoDS_Shape& shape,
                                                  const Standard_Real maxTol,
                                                  const Standard_CString prscfile,
                                                  const Standard_CString pseq,
-                                                 Handle(Standard_Transient)& info) const
+                                                 Handle(Standard_Transient)& info,
+                                                 const Handle(Message_ProgressIndicator)& progress) const
 {
   if ( shape.IsNull() ) return shape;
   
-  Handle(ShapeProcess_ShapeContext) context = Handle(ShapeProcess_ShapeContext)::DownCast ( info );
-  if ( context.IsNull() ) {
-    Standard_CString rscfile = Interface_Static::CVal ( prscfile );
-    if ( ! rscfile ) rscfile = prscfile;
-    context = new ShapeProcess_ShapeContext (shape, rscfile);
-    context->SetDetalisation ( TopAbs_EDGE );
+  Handle(ShapeProcess_ShapeContext) context = Handle(ShapeProcess_ShapeContext)::DownCast(info);
+  if ( context.IsNull() )
+  {
+    Standard_CString rscfile = Interface_Static::CVal(prscfile);
+    if (!rscfile)
+      rscfile = prscfile;
+    context = new ShapeProcess_ShapeContext(shape, rscfile);
+    context->SetDetalisation(TopAbs_EDGE);
+    if ( !progress.IsNull() )
+      context->SetProgress(progress);
   }
   info = context;
   
@@ -123,7 +128,7 @@ TopoDS_Shape XSAlgo_AlgoContainer::ProcessShape (const TopoDS_Shape& shape,
        sfs->SetMaxTolerance ( maxTol );
        sfs->FixFaceTool()->FixWireTool()->FixSameParameterMode() = Standard_False;
        sfs->FixSolidTool()->CreateOpenSolidMode() = Standard_False;
-       sfs->Perform();
+       sfs->Perform(progress);
 
        TopoDS_Shape S = sfs->Shape();
        if ( ! S.IsNull() && S != shape ) {
@@ -151,8 +156,10 @@ TopoDS_Shape XSAlgo_AlgoContainer::ProcessShape (const TopoDS_Shape& shape,
   // Define runtime tolerances and do Shape Processing 
   rsc->SetResource ( "Runtime.Tolerance", Prec );
   rsc->SetResource ( "Runtime.MaxTolerance", maxTol );
-  ShapeProcess::Perform ( context, seq );
-  
+
+  if ( !ShapeProcess::Perform(context, seq) )
+    return TopoDS_Shape(); // Null shape
+
   return context->Result();
 }