0028786: Refactoring of the Warning/Error reporting system of Boolean Operations...
authoremv <emv@opencascade.com>
Mon, 29 May 2017 08:08:08 +0000 (11:08 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 6 Jul 2017 09:41:56 +0000 (12:41 +0300)
0. Basic tools for defining classes representing alerts (errors, warnings etc.) and collecting them during execution of algorithms are added in Message package.

1. Refactoring of the Error/Warning reporting system of the algorithms in Boolean Component.
   To dump the description of the Error/Warning status of the algorithm the DumpErrors/DumpWarnings method should be called.
   Also, the methods GerErrorMsg(int Error) and GetWarningMsg(int Warning) have been implemented to get the description for the given Error/Warning.
   All Error/Warning statuses are now listed in the enumeration ErrorStatusEnum/WarningStatusEnum of the algorithm.
   It is also possible to get the shapes for which the warning has been set by using the method GetWarningShapes().

2. The new class BOPAlgo_Options has been created to unify the options of the BOPAlgo_* and BRepAlgoAPI* algorithms.

3. The new checks across the algorithms have been added to detect and report errors and warnings.

4. Test cases
  boolean bopcut_complex B9 E1 E5 E8
  boolean bopfuse_complex B4 B5 C9 D1 D4 D5 D6 D7
have been rewritten to use Cells Builder algorithm instead of Boolean Operations algorithm, because latter always returns error "Unsupported Boolean operation" for these cases.

5. New chapter has been added in the user guide for Boolean Operations - Error / Warning reporting system.

6. Added comment to NCollection_List::Remove(Iterator&)

109 files changed:
adm/RESOURCES
dox/user_guides/boolean_operations/boolean_operations.md
src/BOPAlgo/BOPAlgo.msg [new file with mode: 0644]
src/BOPAlgo/BOPAlgo_Alerts.hxx [new file with mode: 0644]
src/BOPAlgo/BOPAlgo_Algo.cxx
src/BOPAlgo/BOPAlgo_Algo.hxx
src/BOPAlgo/BOPAlgo_ArgumentAnalyzer.cxx
src/BOPAlgo/BOPAlgo_BOP.cxx
src/BOPAlgo/BOPAlgo_BOP.hxx
src/BOPAlgo/BOPAlgo_BOPAlgo_msg.pxx [new file with mode: 0644]
src/BOPAlgo/BOPAlgo_Builder.cxx
src/BOPAlgo/BOPAlgo_Builder.hxx
src/BOPAlgo/BOPAlgo_BuilderFace.cxx
src/BOPAlgo/BOPAlgo_BuilderFace.hxx
src/BOPAlgo/BOPAlgo_BuilderShape.hxx
src/BOPAlgo/BOPAlgo_BuilderSolid.cxx
src/BOPAlgo/BOPAlgo_BuilderSolid.hxx
src/BOPAlgo/BOPAlgo_Builder_1.cxx
src/BOPAlgo/BOPAlgo_Builder_2.cxx
src/BOPAlgo/BOPAlgo_Builder_3.cxx
src/BOPAlgo/BOPAlgo_CellsBuilder.cxx
src/BOPAlgo/BOPAlgo_CellsBuilder.hxx
src/BOPAlgo/BOPAlgo_CheckerSI.cxx
src/BOPAlgo/BOPAlgo_CheckerSI.hxx
src/BOPAlgo/BOPAlgo_CheckerSI_1.cxx
src/BOPAlgo/BOPAlgo_MakerVolume.cxx
src/BOPAlgo/BOPAlgo_MakerVolume.hxx
src/BOPAlgo/BOPAlgo_Options.cxx [new file with mode: 0644]
src/BOPAlgo/BOPAlgo_Options.hxx [new file with mode: 0644]
src/BOPAlgo/BOPAlgo_PaveFiller.cxx
src/BOPAlgo/BOPAlgo_PaveFiller.hxx
src/BOPAlgo/BOPAlgo_PaveFiller_1.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_11.cxx [new file with mode: 0644]
src/BOPAlgo/BOPAlgo_PaveFiller_2.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_4.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_7.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_8.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_9.cxx
src/BOPAlgo/BOPAlgo_Section.cxx
src/BOPAlgo/BOPAlgo_Section.hxx
src/BOPAlgo/BOPAlgo_ShellSplitter.cxx
src/BOPAlgo/BOPAlgo_ShellSplitter.hxx
src/BOPAlgo/BOPAlgo_Splitter.cxx
src/BOPAlgo/BOPAlgo_Splitter.hxx
src/BOPAlgo/BOPAlgo_Tools.cxx
src/BOPAlgo/BOPAlgo_WireSplitter.cxx
src/BOPAlgo/BOPAlgo_WireSplitter.hxx
src/BOPAlgo/FILES
src/BOPTest/BOPTest.cxx
src/BOPTest/BOPTest.hxx
src/BOPTest/BOPTest_APICommands.cxx
src/BOPTest/BOPTest_BOPCommands.cxx
src/BOPTest/BOPTest_CellsCommands.cxx
src/BOPTest/BOPTest_CheckCommands.cxx
src/BOPTest/BOPTest_DebugCommands.cxx
src/BOPTest/BOPTest_Objects.cxx
src/BOPTest/BOPTest_Objects.hxx
src/BOPTest/BOPTest_OptionCommands.cxx
src/BOPTest/BOPTest_PartitionCommands.cxx
src/BRepAlgoAPI/BRepAlgoAPI_Algo.cxx
src/BRepAlgoAPI/BRepAlgoAPI_Algo.hxx
src/BRepAlgoAPI/BRepAlgoAPI_BooleanOperation.cxx
src/BRepAlgoAPI/BRepAlgoAPI_BooleanOperation.hxx
src/BRepAlgoAPI/BRepAlgoAPI_BuilderAlgo.cxx
src/BRepAlgoAPI/BRepAlgoAPI_BuilderAlgo.hxx
src/BRepAlgoAPI/BRepAlgoAPI_Splitter.cxx
src/BRepAlgoAPI/BRepAlgoAPI_Splitter.hxx
src/BRepFeat/BRepFeat_Builder.cxx
src/BRepFeat/BRepFeat_MakeCylindricalHole.cxx
src/BRepFill/BRepFill_TrimShellCorner.cxx
src/BRepOffset/BRepOffset_MakeOffset.cxx
src/BRepOffset/BRepOffset_MakeOffset_1.cxx
src/BRepOffsetAPI/BRepOffsetAPI_DraftAngle.cxx
src/BRepTest/BRepTest_FeatureCommands.cxx
src/BRepTest/BRepTest_FilletCommands.cxx
src/Message/FILES
src/Message/Message_Alert.cxx [new file with mode: 0644]
src/Message/Message_Alert.hxx [new file with mode: 0644]
src/Message/Message_Algorithm.cxx
src/Message/Message_ListOfAlert.hxx [new file with mode: 0644]
src/Message/Message_Report.cxx [new file with mode: 0644]
src/Message/Message_Report.hxx [new file with mode: 0644]
src/NCollection/NCollection_List.hxx
src/QABugs/QABugs_19.cxx
src/TopoDS/FILES
src/TopoDS/TopoDS_AlertWithShape.cxx [new file with mode: 0644]
src/TopoDS/TopoDS_AlertWithShape.hxx [new file with mode: 0644]
tests/boolean/bopcut_complex/B9
tests/boolean/bopcut_complex/E1
tests/boolean/bopcut_complex/E5
tests/boolean/bopcut_complex/E8
tests/boolean/bopfuse_complex/B4
tests/boolean/bopfuse_complex/B5
tests/boolean/bopfuse_complex/C9
tests/boolean/bopfuse_complex/D1
tests/boolean/bopfuse_complex/D4
tests/boolean/bopfuse_complex/D5
tests/boolean/bopfuse_complex/D6
tests/boolean/bopfuse_complex/D7
tests/bugs/modalg_4/bug726_3
tests/bugs/modalg_6/bug27448_2
tests/bugs/modalg_7/bug28786_1 [new file with mode: 0644]
tests/bugs/modalg_7/bug28786_2 [new file with mode: 0644]
tests/bugs/modalg_7/bug28786_3 [new file with mode: 0644]
tests/bugs/modalg_7/bug28786_4 [new file with mode: 0644]
tests/bugs/modalg_7/bug28786_5 [new file with mode: 0644]

index 3d6c59e..4ee7b15 100644 (file)
@@ -7,4 +7,5 @@ XSMessage
 XSTEPResource
 XmlOcafResource
 UnitsAPI/Units.dat
-TObj/TObj.msg
\ No newline at end of file
+TObj/TObj.msg
+BOPAlgo/BOPAlgo.msg
index b224df2..55da9a7 100644 (file)
@@ -2708,6 +2708,58 @@ To enable the safe processing mode for the operation in DRAW, it is necessary to
 bnondestructive 1
 ~~~~
 
+@section occt_algorithms_ers Errors and warnings reporting system
+
+The chapter describes the Error/Warning reporting system of the algorithms in the Boolean Component.
+
+The errors and warnings are collected in the instance of the class *Message_Report* maintained as a field by common base class of Boolean operation algorithms *BOPAlgo_Options*.
+
+The error is reported in for problems which cannot be treated and cause the algorithm to fail. 
+In this case the result of the operation will be incorrect or incomplete or there will be no result at all. 
+
+The warnings are reported for the problems which can be potentially handled or ignored and thus do not cause the algorithms to stop their work (but probably affect the result). 
+
+All possible errors and warnings that can be set by the algorithm are listed in its header file.
+The complete list of errors and warnings that can be generated by Boolean operations is defined in *BOPAlgo_Alerts.hxx*.
+
+Use method *HasErrors()* to check for presence of error; method *HasError()* can be used to check for particular error.
+Methods *DumpErrors()* outputs textual description of collected errors into the stream.
+Similar methods *HasWarnings()*, *HasWarning()*, and *DumpWarnings()* are provided for warnings.
+
+Note that messages corresponding to errors and warnings are defined in resource file *BOPAlgo.msg*.
+These messages can be localized; for that put translated version to separate file and load it in the application by call to *Message_MsgFile::Load()* .
+
+Here is the example of how to use this system:
+~~~~~
+BOPAlgo_PaveFiller aPF;
+aPF.SetArguments(...);
+aPF.Perform();
+if (aPF.HasErrors()) {
+  aPF.DumpErrors(std::cerr);
+  //
+  if (aPF.HasError(STANDARD_TYPE(BOPAlgo_AlertNullInputShapes)) {
+    // some actions
+  }
+  if (aPF.HasWarning(STANDARD_TYPE(BOPAlgo_AlertTooSmallEdge)) {
+    // some actions
+  }
+  ...
+}
+~~~~~
+
+DRAW commands executing Boolean operations output errors and warnings generated by these operations in textual form.
+Additional option allows saving shapes for which warnings have been generated, as DRAW variables. 
+To activate this option, run command *bdrawwarnshapes* with argument 1 (or with 0 to deactivate):
+~~~~
+bdrawwarnshapes 1
+~~~~
+
+After setting this option and running an algorithm the result will look as follows:
+~~~~
+Warning: The interfering vertices of the same argument: ws_1_1 ws_1_2
+Warning: The positioning of the shapes leads to creation of small edges without valid range: ws_2_1
+~~~~
+
 
 @section occt_algorithms_11b Usage 
 
diff --git a/src/BOPAlgo/BOPAlgo.msg b/src/BOPAlgo/BOPAlgo.msg
new file mode 100644 (file)
index 0000000..67350fc
--- /dev/null
@@ -0,0 +1,69 @@
+!!!!!!!!!! ----- Messages file for BOPAlgo package --------- !!!!!!!!!
+!  Keyword is name of corresponding alert (error or warning) class
+
+! Special key used to check that messages are loaded; see BOPAlgo_Options.cxx
+.BOPAlgo_LOAD_CHECKER
+N/A
+
+.BOPAlgo_AlertBOPIsNotSet
+Error: The type of Boolean Operation is not set
+
+.BOPAlgo_AlertBOPNotAllowed
+Error: Boolean operation of the given type is not allowed on the given inputs
+
+.BOPAlgo_AlertSolidBuilderFailed
+Error: Building Fused solid has failed
+
+.BOPAlgo_AlertTooFewArguments
+Error: There are no enough arguments to perform the operation
+
+.BOPAlgo_AlertMultipleArguments
+Error: More than one argument is provided
+
+.BOPAlgo_AlertNoFiller
+Error: The Pave Filler (the intersection tool) has not been created
+
+.BOPAlgo_AlertIntersectionFailed
+Error: The intersection of the arguments has failed
+
+.BOPAlgo_AlertBuilderFailed
+Error: Building of the result shape has failed
+
+.BOPAlgo_AlertNullFace
+Error: The face given to be split is a null shape
+
+.BOPAlgo_AlertNullInputShapes
+Error: No or null input shapes
+
+.BOPAlgo_AlertPostTreatFF
+Error: Cannot connect face intersection curves
+
+.BOPAlgo_AlertEmptyShape
+Warning: Some of the arguments are empty shapes
+
+.BOPAlgo_AlertSelfInterferingShape
+Warning: Some of the arguments are self-interfering shapes
+
+.BOPAlgo_AlertTooSmallEdge
+Warning: Some edges are too small and have no valid range
+
+.BOPAlgo_AlertNotSplittableEdge
+Warning: Some edges are very small and have such a small valid range, that they cannot be split
+
+.BOPAlgo_AlertBadPositioning
+Warning: The positioning of the shapes leads to creation of the small edges without valid range
+
+.BOPAlgo_AlertShellSplitterFailed
+Warning: Unable to build loops from the given faces
+
+.BOPAlgo_AlertRemovalOfIBForMDimShapes
+Warning: Removal of internal boundaries among the multi-dimensional shapes is not supported yet
+
+.BOPAlgo_AlertRemovalOfIBForSolidsFailed
+Warning: Removal of internal boundaries among Solids has failed
+
+.BOPAlgo_AlertRemovalOfIBForFacesFailed
+Warning: Removal of internal boundaries among Faces has failed
+
+.BOPAlgo_AlertRemovalOfIBForEdgesFailed
+Warning: Removal of internal boundaries among Edges has failed
diff --git a/src/BOPAlgo/BOPAlgo_Alerts.hxx b/src/BOPAlgo/BOPAlgo_Alerts.hxx
new file mode 100644 (file)
index 0000000..02cec15
--- /dev/null
@@ -0,0 +1,81 @@
+// Created on: 2017-06-26
+// Created by: Andrey Betenev
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BOPAlgo_Alerts_HeaderFile
+#define _BOPAlgo_Alerts_HeaderFile
+
+#include <TopoDS_AlertWithShape.hxx>
+
+//! Boolean operation of given type is not allowed on the given inputs
+DEFINE_SIMPLE_ALERT(BOPAlgo_AlertBOPNotAllowed)
+
+//! The type of Boolean Operation is not set
+DEFINE_SIMPLE_ALERT(BOPAlgo_AlertBOPNotSet)
+
+//! Building of the result shape has failed
+DEFINE_SIMPLE_ALERT(BOPAlgo_AlertBuilderFailed)
+
+//! The intersection of the arguments has failed
+DEFINE_SIMPLE_ALERT(BOPAlgo_AlertIntersectionFailed)
+
+//! The type of Boolean Operation is not set
+DEFINE_SIMPLE_ALERT(BOPAlgo_AlertMultipleArguments)
+
+//! The Pave Filler (the intersection tool) has not been created
+DEFINE_SIMPLE_ALERT(BOPAlgo_AlertNoFiller)
+
+//! Null input shapes
+DEFINE_SIMPLE_ALERT(BOPAlgo_AlertNullInputShapes)
+
+//! Cannot connect face intersection curves
+DEFINE_SIMPLE_ALERT(BOPAlgo_AlertPostTreatFF)
+
+//! The BuilderSolid algorithm has failed
+DEFINE_SIMPLE_ALERT(BOPAlgo_AlertSolidBuilderFailed)
+
+//! There are no enough arguments to perform the operation
+DEFINE_SIMPLE_ALERT(BOPAlgo_AlertTooFewArguments)
+
+//! The positioning of the shapes leads to creation of the small edges without valid range
+DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertBadPositioning)
+
+//! Some of the arguments are empty shapes
+DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertEmptyShape)
+
+//! Some edges are very small and have such a small valid range, that they cannot be split
+DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertNotSplittableEdge)
+
+//! Removal of internal boundaries among Edges has failed
+DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertRemovalOfIBForEdgesFailed)
+
+//! Removal of internal boundaries among Faces has failed
+DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertRemovalOfIBForFacesFailed)
+
+//! Removal of internal boundaries among the multi-dimensional shapes is not supported yet
+DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertRemovalOfIBForMDimShapes)
+
+//! Removal of internal boundaries among Solids has failed
+DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertRemovalOfIBForSolidsFailed)
+
+//! Some of the arguments are self-interfering shapes
+DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertSelfInterferingShape)
+
+//! The positioning of the shapes leads to creation of the small edges without valid range
+DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertShellSplitterFailed)
+
+//! Some edges are too small and have no valid range
+DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertTooSmallEdge)
+
+#endif // _BOPAlgo_Alerts_HeaderFile
index efb4a9b..1fd54ec 100644 (file)
 
 
 #include <BOPAlgo_Algo.hxx>
-#include <Message_ProgressIndicator.hxx>
-#include <NCollection_BaseAllocator.hxx>
-#include <Precision.hxx>
-#include <Standard_NotImplemented.hxx>
-#include <Standard_ProgramError.hxx>
-
-namespace
-{
-  Standard_Boolean myGlobalRunParallel = Standard_False;
-}
-
-//=======================================================================
-// function: 
-// purpose: 
-//=======================================================================
-void BOPAlgo_Algo::SetParallelMode(Standard_Boolean theNewMode)
-{
-  myGlobalRunParallel = theNewMode;
-}
-
-//=======================================================================
-// function: 
-// purpose: 
-//=======================================================================
-Standard_Boolean BOPAlgo_Algo::GetParallelMode()
-{
-  return myGlobalRunParallel;
-}
-
 
 //=======================================================================
 // function: 
@@ -53,11 +24,7 @@ Standard_Boolean BOPAlgo_Algo::GetParallelMode()
 //=======================================================================
 BOPAlgo_Algo::BOPAlgo_Algo()
 :
-  myAllocator(NCollection_BaseAllocator::CommonBaseAllocator()),
-  myErrorStatus(1),
-  myWarningStatus(0),
-  myRunParallel(myGlobalRunParallel),
-  myFuzzyValue(Precision::Confusion())
+  BOPAlgo_Options(NCollection_BaseAllocator::CommonBaseAllocator())
 {}
 //=======================================================================
 // function: 
@@ -66,11 +33,7 @@ BOPAlgo_Algo::BOPAlgo_Algo()
 BOPAlgo_Algo::BOPAlgo_Algo
   (const Handle(NCollection_BaseAllocator)& theAllocator)
 :
-  myAllocator(theAllocator),
-  myErrorStatus(1),
-  myWarningStatus(0),
-  myRunParallel(myGlobalRunParallel),
-  myFuzzyValue(Precision::Confusion())
+  BOPAlgo_Options(theAllocator)
 {}
 
 //=======================================================================
@@ -80,21 +43,14 @@ BOPAlgo_Algo::BOPAlgo_Algo
 BOPAlgo_Algo::~BOPAlgo_Algo()
 {
 }
-//=======================================================================
-//function : Allocator
-//purpose  : 
-//=======================================================================
-const Handle(NCollection_BaseAllocator)& BOPAlgo_Algo::Allocator()const
-{
-  return myAllocator;
-}
+
 //=======================================================================
 // function: CheckData
 // purpose: 
 //=======================================================================
 void BOPAlgo_Algo::CheckData()
 {
-  myErrorStatus=0;
+  GetReport()->Clear(Message_Fail);
 }
 //=======================================================================
 // function: CheckResult
@@ -102,80 +58,5 @@ void BOPAlgo_Algo::CheckData()
 //=======================================================================
 void BOPAlgo_Algo::CheckResult()
 {
-  myErrorStatus=0;
+  GetReport()->Clear(Message_Fail);
 }
-//=======================================================================
-// function: ErrorStatus
-// purpose: 
-//=======================================================================
-Standard_Integer BOPAlgo_Algo::ErrorStatus()const
-{
-  return myErrorStatus;
-}
-//=======================================================================
-// function: WarningStatus
-// purpose: 
-//=======================================================================
-Standard_Integer BOPAlgo_Algo::WarningStatus()const
-{
-  return myWarningStatus;
-}
-//=======================================================================
-//function : SetRunParallel
-//purpose  : 
-//=======================================================================
-void BOPAlgo_Algo::SetRunParallel(const Standard_Boolean theFlag)
-{
-  myRunParallel=theFlag;
-}
-//=======================================================================
-//function : RunParallel
-//purpose  : 
-//=======================================================================
-Standard_Boolean BOPAlgo_Algo::RunParallel()const
-{
-  return myRunParallel;
-}
-//=======================================================================
-//function : SetFuzzyValue
-//purpose  : 
-//=======================================================================
-void BOPAlgo_Algo::SetFuzzyValue(const Standard_Real theFuzz)
-{
-  myFuzzyValue = Max(theFuzz, Precision::Confusion());
-}
-//=======================================================================
-//function : FuzzyValue
-//purpose  : 
-//=======================================================================
-Standard_Real BOPAlgo_Algo::FuzzyValue() const
-{
-  return myFuzzyValue;
-}
-//=======================================================================
-//function : SetProgressIndicator
-//purpose  : 
-//=======================================================================
-void BOPAlgo_Algo::SetProgressIndicator
-  (const Handle(Message_ProgressIndicator)& theObj)
-{
-  if (!theObj.IsNull()) {
-    myProgressIndicator=theObj;
-  }
-}
-//=======================================================================
-//function : UserBreak
-//purpose  : 
-//=======================================================================
-void BOPAlgo_Algo::UserBreak() const
-{
-  if (myProgressIndicator.IsNull()) {
-    return;
-  }
-  if (myProgressIndicator->UserBreak()) {
-    throw Standard_NotImplemented ("BOPAlgo_Algo::UserBreak(), method is not implemented");
-  }
-} 
-//  myErrorStatus
-//
-// 1 - object is just initialized
index 9141e2f..5a39fd0 100644 (file)
 #include <Standard_DefineAlloc.hxx>
 #include <Standard_Handle.hxx>
 
-#include <BOPCol_BaseAllocator.hxx>
-#include <Standard_Integer.hxx>
-#include <Standard_Boolean.hxx>
-class Message_ProgressIndicator;
+#include <BOPAlgo_Options.hxx>
 
+#include <BOPCol_DataMapOfIntegerListOfShape.hxx>
 
-//! provides the root interface for algorithms
-class BOPAlgo_Algo 
+//! The class provides the root interface for the algorithms in Boolean Component.<br>
+class BOPAlgo_Algo : public BOPAlgo_Options
 {
 public:
 
   DEFINE_STANDARD_ALLOC
 
-  
-  Standard_EXPORT static Standard_Boolean GetParallelMode();
-  
-  Standard_EXPORT static void SetParallelMode (const Standard_Boolean theNewMode);
-  
   Standard_EXPORT virtual void Perform() = 0;
-  
-  Standard_EXPORT Standard_Integer ErrorStatus() const;
-  
-  Standard_EXPORT Standard_Integer WarningStatus() const;
-  
-  Standard_EXPORT const BOPCol_BaseAllocator& Allocator() const;
-  
-  //! Set the flag of parallel processing
-  //! if <theFlag> is true  the parallel processing is switched on
-  //! if <theFlag> is false the parallel processing is switched off
-  Standard_EXPORT void SetRunParallel (const Standard_Boolean theFlag);
-  
-  //! Returns the flag of parallel processing
-  Standard_EXPORT Standard_Boolean RunParallel() const;
-
-  //! Sets the additional tolerance
-  Standard_EXPORT void SetFuzzyValue (const Standard_Real theFuzz);
-  
-  //! Returns the additional tolerance
-  Standard_EXPORT Standard_Real FuzzyValue() const;
-  
-  //! Set the Progress Indicator object.
-  Standard_EXPORT void SetProgressIndicator (const Handle(Message_ProgressIndicator)& theObj);
-
-
-
 
 protected:
 
-  
+  //! Default constructor
   Standard_EXPORT BOPAlgo_Algo();
-Standard_EXPORT virtual ~BOPAlgo_Algo();
-  
-  Standard_EXPORT BOPAlgo_Algo(const BOPCol_BaseAllocator& theAllocator);
-  
-  Standard_EXPORT virtual void CheckData();
-  
-  Standard_EXPORT virtual void CheckResult();
-  
-  //! Breaks the execution if the break signal
-  //! is indicated by myProgressIndicator.
-  Standard_EXPORT void UserBreak() const;
-
-
-  BOPCol_BaseAllocator myAllocator;
-  Standard_Integer myErrorStatus;
-  Standard_Integer myWarningStatus;
-  Standard_Boolean myRunParallel;
-  Standard_Real myFuzzyValue;
-  Handle(Message_ProgressIndicator) myProgressIndicator;
-
-
-private:
-
+  Standard_EXPORT virtual ~BOPAlgo_Algo();
 
+  Standard_EXPORT BOPAlgo_Algo(const BOPCol_BaseAllocator& theAllocator);
 
+  //! Checks input data
+  Standard_EXPORT virtual void CheckData();
 
+  //! Checks the obtained result
+  Standard_EXPORT virtual void CheckResult();
 
 };
 
-
-
-
-
-
-
 #endif // _BOPAlgo_Algo_HeaderFile
index ed181df..d9df6f8 100644 (file)
@@ -351,7 +351,7 @@ void BOPAlgo_ArgumentAnalyzer::TestSelfInterferences()
       continue;
     }
     //
-    Standard_Integer iErr, n1, n2;
+    Standard_Integer n1, n2;
     BOPDS_MapIteratorOfMapOfPair aItMPK;
     BOPCol_ListOfShape anArgs;
     BOPAlgo_CheckerSI aChecker;
@@ -364,7 +364,7 @@ void BOPAlgo_ArgumentAnalyzer::TestSelfInterferences()
     aChecker.SetProgressIndicator(myProgressIndicator);
     //
     aChecker.Perform();
-    iErr=aChecker.ErrorStatus();
+    Standard_Boolean hasError = aChecker.HasErrors();
     //
     const BOPDS_DS& aDS=*(aChecker.PDS());
     const BOPDS_MapOfPair& aMPK=aDS.Interferences();
@@ -397,7 +397,7 @@ void BOPAlgo_ArgumentAnalyzer::TestSelfInterferences()
       myResult.Append(aResult);
     }
     //
-    if (iErr) {
+    if (hasError) {
       BOPAlgo_CheckResult aResult;
       if(ii == 0) {
         aResult.SetShape1(myShape1);
index 55a43db..7004b3a 100644 (file)
@@ -16,6 +16,7 @@
 #include <BOPAlgo_BOP.hxx>
 #include <BOPAlgo_BuilderSolid.hxx>
 #include <BOPAlgo_PaveFiller.hxx>
+#include <BOPAlgo_Alerts.hxx>
 #include <BOPCol_DataMapOfShapeShape.hxx>
 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
 #include <BOPCol_IndexedMapOfShape.hxx>
@@ -159,41 +160,34 @@ void BOPAlgo_BOP::SetTools(const BOPCol_ListOfShape& theShapes)
 void BOPAlgo_BOP::CheckData()
 {
   Standard_Integer i, j, iDim, aNbArgs, aNbTools;
-  Standard_Boolean bFlag, bFuse;
+  Standard_Boolean bFuse;
   BOPCol_ListIteratorOfListOfShape aItLS;
   //
-  myErrorStatus=0;
-  //
   if (!(myOperation==BOPAlgo_COMMON ||
         myOperation==BOPAlgo_FUSE || 
         myOperation==BOPAlgo_CUT|| 
         myOperation==BOPAlgo_CUT21)) {
     // non-licit operation
-    myErrorStatus=14;
+    AddError (new BOPAlgo_AlertBOPNotSet);
     return;
   }
   //
   aNbArgs=myArguments.Extent();
   if (!aNbArgs) {
     // invalid number of Arguments
-    myErrorStatus=100; 
+    AddError (new BOPAlgo_AlertTooFewArguments);
     return;
   }
   //
   aNbTools=myTools.Extent();
   if (!aNbTools) { 
     // invalid number of Tools
-    myErrorStatus=100;
-    return;
-  }
-  //
-  if (!myPaveFiller) {
-    myErrorStatus=101; 
+    AddError (new BOPAlgo_AlertTooFewArguments);
     return;
   }
   //
-  myErrorStatus=myPaveFiller->ErrorStatus();
-  if (myErrorStatus) {
+  CheckFiller();
+  if (HasErrors()) {
     return;
   }
   //
@@ -208,24 +202,28 @@ void BOPAlgo_BOP::CheckData()
   // 4. COMMON: The arguments and tools could have any dimensions.
   //
   Standard_Integer iDimMin[2], iDimMax[2];
+  Standard_Boolean bHasValid[2] = {Standard_False, Standard_False};
   //
   for (i=0; i<2; ++i) {
     const BOPCol_ListOfShape& aLS=(!i)? myArguments : myTools;
     aItLS.Initialize(aLS);
     for (j=0; aItLS.More(); aItLS.Next(), ++j) {
       const TopoDS_Shape& aS=aItLS.Value();
-      bFlag=BOPTools_AlgoTools3D::IsEmptyShape(aS);
-      if(bFlag) {
-        myWarningStatus=2;
+      Standard_Boolean bIsEmpty = BOPTools_AlgoTools3D::IsEmptyShape(aS);
+      if (bIsEmpty) {
+        AddWarning(new BOPAlgo_AlertEmptyShape (aS));
+        continue;
       }
       //
-      iDim=BOPTools_AlgoTools::Dimension(aS);
-      if (iDim<0) {
-        // non-homogenious argument
-        myErrorStatus=13; 
+      iDim = BOPTools_AlgoTools::Dimension(aS);
+      if (iDim < 0) {
+        // non-homogeneous argument
+        AddError (new BOPAlgo_AlertBOPNotAllowed);
         return;
       }
       //
+      bHasValid[i] = Standard_True;
+      //
       if (!j) {
         iDimMin[i] = iDim;
         iDimMax[i] = iDim;
@@ -240,77 +238,101 @@ void BOPAlgo_BOP::CheckData()
       }
       //
       if (bFuse && (iDimMin[i] != iDimMax[i])) {
-        // non-homogenious argument
-        myErrorStatus=13;
+        // non-homogeneous argument
+        AddError (new BOPAlgo_AlertBOPNotAllowed);
         return;
       }
     }
   }
   //
-  if (((myOperation == BOPAlgo_FUSE)  && (iDimMax[0] != iDimMax[1])) ||
-      ((myOperation == BOPAlgo_CUT)   && (iDimMax[0] >  iDimMin[1])) ||
-      ((myOperation == BOPAlgo_CUT21) && (iDimMin[0] <  iDimMax[1])) ) {
-    // non-licit operation for the arguments
-    myErrorStatus=14;
-    return;
+  if (bHasValid[0] && bHasValid[1]) {
+    if (((myOperation == BOPAlgo_FUSE)  && (iDimMax[0] != iDimMax[1])) ||
+        ((myOperation == BOPAlgo_CUT)   && (iDimMax[0] >  iDimMin[1])) ||
+        ((myOperation == BOPAlgo_CUT21) && (iDimMin[0] <  iDimMax[1])) )
+    {
+      // non-licit operation for the arguments
+      AddError (new BOPAlgo_AlertBOPNotAllowed);
+      return;
+    }
+    myDims[0] = iDimMin[0];
+    myDims[1] = iDimMin[1];
   }
-  //
-  myDims[0] = iDimMin[0];
-  myDims[1] = iDimMin[1];
 }
 //=======================================================================
-//function : Prepare
+//function : TreatEmtpyShape
 //purpose  : 
 //=======================================================================
-void BOPAlgo_BOP::Prepare()
+Standard_Boolean BOPAlgo_BOP::TreatEmptyShape()
 {
+  if (! GetReport()->HasAlert (STANDARD_TYPE(BOPAlgo_AlertEmptyShape)))
+  {
+    return Standard_False;
+  }
   //
-  BOPAlgo_Builder::Prepare();
+  // Find non-empty objects
+  BOPCol_ListOfShape aLValidObjs;
+  BOPCol_ListIteratorOfListOfShape aItLS(myArguments);
+  for (; aItLS.More(); aItLS.Next()) {
+    if (!BOPTools_AlgoTools3D::IsEmptyShape(aItLS.Value())) {
+      aLValidObjs.Append(aItLS.Value());
+    }
+  }
   //
-  if(myWarningStatus == 2) {
-    Standard_Integer i;
-    BRep_Builder aBB;
-    BOPCol_ListIteratorOfListOfShape aItLS;
-    //
-    switch(myOperation) {
-      case BOPAlgo_FUSE: {
-        for (i=0; i<2; ++i) {
-          const BOPCol_ListOfShape& aLS=(!i)? myArguments : myTools;
-          aItLS.Initialize(aLS);
-          for (; aItLS.More(); aItLS.Next()) {
-            const TopoDS_Shape& aS=aItLS.Value();
-            aBB.Add(myShape, aS);
-          }
-        }
-      }
-        break;
-      //  
-      case BOPAlgo_CUT: {
-        aItLS.Initialize(myArguments);
-        for (; aItLS.More(); aItLS.Next()) {
-          const TopoDS_Shape& aS=aItLS.Value();
-          if(!BOPTools_AlgoTools3D::IsEmptyShape(aS)) {
-            aBB.Add(myShape, aS);
-          } 
-        }
-      }
-        break;
-      
-      case BOPAlgo_CUT21: {
-        aItLS.Initialize(myTools);
-        for (; aItLS.More(); aItLS.Next()) {
-          const TopoDS_Shape& aS=aItLS.Value();
-          if(!BOPTools_AlgoTools3D::IsEmptyShape(aS)) {
-            aBB.Add(myShape, aS);
-          } 
-        }
-      }
-        break;
-        //
-      default:
-        break;
-      }
+  // Find non-empty tools
+  BOPCol_ListOfShape aLValidTools;
+  aItLS.Initialize(myTools);
+  for (; aItLS.More() ; aItLS.Next()) {
+    if (!BOPTools_AlgoTools3D::IsEmptyShape(aItLS.Value())) {
+      aLValidTools.Append(aItLS.Value());
+    }
+  }
+  //
+  Standard_Boolean bHasValidObj  = (aLValidObjs .Extent() > 0);
+  Standard_Boolean bHasValidTool = (aLValidTools.Extent() > 0);
+  //
+  if (bHasValidObj && bHasValidTool) {
+    // We need to continue the operation to obtain the result
+    return Standard_False;
+  }
+  //
+  if (!bHasValidObj && !bHasValidTool) {
+    // All shapes are empty shapes, the result will always be empty shape
+    return Standard_True;
   }
+  //
+  // One of the groups of arguments consists of empty shapes only,
+  // so we can build the result of operation right away just by
+  // choosing the list of shapes to add to result, depending on
+  // the type of the operation
+  BOPCol_ListOfShape *pLResult = NULL;
+  //
+  switch (myOperation) {
+    case BOPAlgo_FUSE:
+      // Add not empty shapes into result
+      pLResult = bHasValidObj ? &aLValidObjs : &aLValidTools;
+      break;
+    case BOPAlgo_CUT:
+      // Add objects into result
+      pLResult = &aLValidObjs;
+      break;
+    case BOPAlgo_CUT21:
+      // Add tools into result
+      pLResult = &aLValidTools;
+      break;
+    case BOPAlgo_COMMON:
+      // Common will be empty
+      break;
+    default:
+      break;
+  }
+  //
+  if (pLResult) {
+    aItLS.Initialize(*pLResult);
+    for (; aItLS.More(); aItLS.Next()) {
+      BRep_Builder().Add(myShape, aItLS.Value());
+    }
+  }
+  return Standard_True;
 }
 //=======================================================================
 //function : BuildResult
@@ -323,8 +345,6 @@ void BOPAlgo_BOP::BuildResult(const TopAbs_ShapeEnum theType)
   BOPCol_MapOfShape aM;
   BOPCol_ListIteratorOfListOfShape aIt, aItIm;
   //
-  myErrorStatus=0;
-  //
   const BOPCol_ListOfShape& aLA=myDS->Arguments();
   aIt.Initialize(aLA);
   for (; aIt.More(); aIt.Next()) {
@@ -359,7 +379,7 @@ void BOPAlgo_BOP::Perform()
   BOPAlgo_PaveFiller* pPF;
   BOPCol_ListIteratorOfListOfShape aItLS;
   //
-  myErrorStatus=0;
+  GetReport()->Clear();
   //
   if (myEntryPoint==1) {
     if (myPaveFiller) {
@@ -403,9 +423,6 @@ void BOPAlgo_BOP::Perform()
 //=======================================================================
 void BOPAlgo_BOP::PerformInternal1(const BOPAlgo_PaveFiller& theFiller)
 {
-  myErrorStatus=0;
-  myWarningStatus=0;
-  //
   myPaveFiller=(BOPAlgo_PaveFiller*)&theFiller;
   myDS=myPaveFiller->PDS();
   myContext=myPaveFiller->Context();
@@ -414,110 +431,115 @@ void BOPAlgo_BOP::PerformInternal1(const BOPAlgo_PaveFiller& theFiller)
   //
   // 1. CheckData
   CheckData();
-  if (myErrorStatus && !myWarningStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   // 2. Prepare
   Prepare();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
-  if(myWarningStatus == 2) {
-    return;
+  if (GetReport()->HasAlert (STANDARD_TYPE(BOPAlgo_AlertEmptyShape)))
+  {
+    Standard_Boolean bDone = TreatEmptyShape();
+    if (bDone) {
+      return;
+    }
   }
+  //
   // 3. Fill Images
   // 3.1 Vertices
   FillImagesVertices();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   BuildResult(TopAbs_VERTEX);
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   // 3.2 Edges
   FillImagesEdges();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   BuildResult(TopAbs_EDGE);
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   // 3.3 Wires
   FillImagesContainers(TopAbs_WIRE);
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   BuildResult(TopAbs_WIRE);
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   // 3.4 Faces
   FillImagesFaces();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   
   BuildResult(TopAbs_FACE);
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   // 3.5 Shells
   FillImagesContainers(TopAbs_SHELL);
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   BuildResult(TopAbs_SHELL);
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   // 3.6 Solids
   FillImagesSolids();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   BuildResult(TopAbs_SOLID);
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   // 3.7 CompSolids
   FillImagesContainers(TopAbs_COMPSOLID);
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   BuildResult(TopAbs_COMPSOLID);
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   // 3.8 Compounds
   FillImagesCompounds();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   BuildResult(TopAbs_COMPOUND);
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   // 4.BuildShape;
   BuildShape();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   // 
@@ -537,8 +559,6 @@ void BOPAlgo_BOP::BuildRC()
   TopoDS_Compound aC;
   BRep_Builder aBB;
   //
-  myErrorStatus = 0;
-  //
   aBB.MakeCompound(aC);
   //
   // A. Fuse
@@ -571,6 +591,9 @@ void BOPAlgo_BOP::BuildRC()
     for (; aItLS.More(); aItLS.Next()) {
       const TopoDS_Shape& aS = aItLS.Value();
       iDim = BOPTools_AlgoTools::Dimension(aS);
+      if (iDim < 0) {
+        continue;
+      }
       aType = TypeToExplore(iDim);
       BOPTools::MapShapes(aS, aType, aMS);
     }
@@ -900,8 +923,6 @@ void BOPAlgo_BOP::BuildSolid()
   TopExp_Explorer aExp;
   BRep_Builder aBB;
   //
-  myErrorStatus=0;
-  //
   // Get solids from input arguments
   BOPCol_MapOfShape aMSA;
   // Map the arguments to find shared faces
@@ -1033,8 +1054,8 @@ void BOPAlgo_BOP::BuildSolid()
     aSB.SetContext(myContext);
     aSB.SetShapes(aSFS);
     aSB.Perform();
-    if (aSB.ErrorStatus()) {
-      myErrorStatus = 30; // SolidBuilder failed
+    if (aSB.HasErrors()) {
+      AddError (new BOPAlgo_AlertSolidBuilderFailed); // SolidBuilder failed
       return;
     }
     // new solids
index 176bfca..6555c3f 100644 (file)
 class TopoDS_Shape;
 class BOPAlgo_PaveFiller;
 
-
-
+//!
+//! The class represents the Building part of the Boolean Operations
+//! algorithm.<br>
+//! The arguments of the algorithms are divided in two groups - *Objects*
+//! and *Tools*.<br>
+//! The algorithm builds the splits of the given arguments using the intersection
+//! results and combines the result of Boolean Operation of given type:<br>
+//! - *FUSE* - union of two groups of objects;<br>
+//! - *COMMON* - intersection of two groups of objects;<br>
+//! - *CUT* - subtraction of one group from the other.<br>
+//!
+//! The rules for the arguments and type of the operation are the following:<br>
+//! - For Boolean operation *FUSE* all arguments should have equal dimensions;<br>
+//! - For Boolean operation *CUT* the minimal dimension of *Tools* should not be
+//!   less than the maximal dimension of *Objects*;<br>
+//! - For Boolean operation *COMMON* the arguments can have any dimension.<br>
+//!
+//! The class is a General Fuse based algorithm. Thus, all options
+//! of the General Fuse algorithm such as Fuzzy mode, safe processing mode,
+//! parallel processing mode, gluing mode and history support are also
+//! available in this algorithm.<br>
+//!
+//! Additionally to the Warnings of the parent class the algorithm returns
+//! the following warnings:
+//! - *BOPAlgo_AlertEmptyShape* - in case some of the input shapes are empty shapes.
+//!
+//! Additionally to Errors of the parent class the algorithm returns
+//! the following Error statuses:
+//! - *BOPAlgo_AlertBOPIsNotSet* - in case the type of Boolean operation is not set;
+//! - *BOPAlgo_AlertBOPNotAllowed* - in case the operation of given type is not allowed on
+//!                     given inputs;
+//! - *BOPAlgo_AlertSolidBuilderFailed* - in case the BuilderSolid algorithm failed to
+//!                          produce the Fused solid.
+//!
 class BOPAlgo_BOP  : public BOPAlgo_Builder
 {
 public:
@@ -61,17 +93,10 @@ Standard_EXPORT virtual ~BOPAlgo_BOP();
   
   Standard_EXPORT virtual void Perform() Standard_OVERRIDE;
 
-
-
-
 protected:
-
   
   Standard_EXPORT virtual void CheckData() Standard_OVERRIDE;
   
-  //! Provides preparing actions
-  Standard_EXPORT virtual void Prepare() Standard_OVERRIDE;
-  
   //! Performs calculations using prepared Filler
   //! object <thePF>
   Standard_EXPORT virtual void PerformInternal1 (const BOPAlgo_PaveFiller& thePF) Standard_OVERRIDE;
@@ -86,6 +111,11 @@ protected:
   
   Standard_EXPORT Standard_Boolean IsBoundSplits (const TopoDS_Shape& theS, BOPCol_IndexedDataMapOfShapeListOfShape& theMEF);
 
+  //! Treatment of the cases with empty shapes.<br>
+  //! It returns TRUE if there is nothing to do, i.e.
+  //! all shapes in one of the groups are empty shapes.
+  Standard_EXPORT Standard_Boolean TreatEmptyShape();
+
 
   BOPAlgo_Operation myOperation;
   Standard_Integer myDims[2];
@@ -96,16 +126,6 @@ protected:
 
 private:
 
-
-
-
-
 };
 
-
-
-
-
-
-
 #endif // _BOPAlgo_BOP_HeaderFile
diff --git a/src/BOPAlgo/BOPAlgo_BOPAlgo_msg.pxx b/src/BOPAlgo/BOPAlgo_BOPAlgo_msg.pxx
new file mode 100644 (file)
index 0000000..c63a538
--- /dev/null
@@ -0,0 +1,72 @@
+// This file has been automatically generated from resource file src/BOPAlgo/BOPAlgo.msg
+
+static const char BOPAlgo_BOPAlgo_msg[] =
+  "!!!!!!!!!! ----- Messages file for BOPAlgo package --------- !!!!!!!!!\n"
+  "!  Keyword is name of corresponding alert (error or warning) class\n"
+  "\n"
+  "! Special key used to check that messages are loaded; see BOPAlgo_Options.cxx\n"
+  ".BOPAlgo_LOAD_CHECKER\n"
+  "N/A\n"
+  "\n"
+  ".BOPAlgo_AlertBOPIsNotSet\n"
+  "Error: The type of Boolean Operation is not set\n"
+  "\n"
+  ".BOPAlgo_AlertBOPNotAllowed\n"
+  "Error: Boolean operation of the given type is not allowed on the given inputs\n"
+  "\n"
+  ".BOPAlgo_AlertSolidBuilderFailed\n"
+  "Error: Building Fused solid has failed\n"
+  "\n"
+  ".BOPAlgo_AlertTooFewArguments\n"
+  "Error: There are no enough arguments to perform the operation\n"
+  "\n"
+  ".BOPAlgo_AlertMultipleArguments\n"
+  "Error: More than one argument is provided\n"
+  "\n"
+  ".BOPAlgo_AlertNoFiller\n"
+  "Error: The Pave Filler (the intersection tool) has not been created\n"
+  "\n"
+  ".BOPAlgo_AlertIntersectionFailed\n"
+  "Error: The intersection of the arguments has failed\n"
+  "\n"
+  ".BOPAlgo_AlertBuilderFailed\n"
+  "Error: Building of the result shape has failed\n"
+  "\n"
+  ".BOPAlgo_AlertNullFace\n"
+  "Error: The face given to be split is a null shape\n"
+  "\n"
+  ".BOPAlgo_AlertNullInputShapes\n"
+  "Error: No or null input shapes\n"
+  "\n"
+  ".BOPAlgo_AlertPostTreatFF\n"
+  "Error: Cannot connect face intersection curves\n"
+  "\n"
+  ".BOPAlgo_AlertEmptyShape\n"
+  "Warning: Some of the arguments are empty shapes\n"
+  "\n"
+  ".BOPAlgo_AlertSelfInterferingShape\n"
+  "Warning: Some of the arguments are self-interfering shapes\n"
+  "\n"
+  ".BOPAlgo_AlertTooSmallEdge\n"
+  "Warning: Some edges are too small and have no valid range\n"
+  "\n"
+  ".BOPAlgo_AlertNotSplittableEdge\n"
+  "Warning: Some edges are very small and have such a small valid range, that they cannot be split\n"
+  "\n"
+  ".BOPAlgo_AlertBadPositioning\n"
+  "Warning: The positioning of the shapes leads to creation of the small edges without valid range\n"
+  "\n"
+  ".BOPAlgo_AlertShellSplitterFailed\n"
+  "Warning: Unable to build loops from the given faces\n"
+  "\n"
+  ".BOPAlgo_AlertRemovalOfIBForMDimShapes\n"
+  "Warning: Removal of internal boundaries among the multi-dimensional shapes is not supported yet\n"
+  "\n"
+  ".BOPAlgo_AlertRemovalOfIBForSolidsFailed\n"
+  "Warning: Removal of internal boundaries among Solids has failed\n"
+  "\n"
+  ".BOPAlgo_AlertRemovalOfIBForFacesFailed\n"
+  "Warning: Removal of internal boundaries among Faces has failed\n"
+  "\n"
+  ".BOPAlgo_AlertRemovalOfIBForEdgesFailed\n"
+  "Warning: Removal of internal boundaries among Edges has failed\n";
index 533fddc..9b2302f 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <BOPAlgo_Builder.hxx>
 #include <BOPAlgo_PaveFiller.hxx>
+#include <BOPAlgo_Alerts.hxx>
 #include <BOPTools_AlgoTools.hxx>
 #include <BRep_Builder.hxx>
 #include <IntTools_Context.hxx>
@@ -95,6 +96,7 @@ BOPAlgo_Builder::~BOPAlgo_Builder()
 //=======================================================================
 void BOPAlgo_Builder::Clear()
 {
+  BOPAlgo_Algo::Clear();
   myArguments.Clear();
   myMapFence.Clear();
   myImages.Clear();
@@ -223,36 +225,33 @@ BOPAlgo_GlueEnum BOPAlgo_Builder::Glue() const
 //=======================================================================
 void BOPAlgo_Builder::CheckData()
 {
-  Standard_Integer aNb;
-  //
-  myErrorStatus=0;
-  //
-  aNb=myArguments.Extent();
+  Standard_Integer aNb = myArguments.Extent();
   if (aNb<2) {
-    myErrorStatus=100; // too few arguments to process
+    AddError (new BOPAlgo_AlertTooFewArguments); // too few arguments to process
     return;
   }
   //
-  //  myPaveFiller
+  CheckFiller();
+}
+//=======================================================================
+// function: CheckFiller
+// purpose: 
+//=======================================================================
+void BOPAlgo_Builder::CheckFiller()
+{
   if (!myPaveFiller) {
-    myErrorStatus=101; 
-    return;
-  }
-  //
-  myErrorStatus=myPaveFiller->ErrorStatus();
-  if (myErrorStatus) {
-    myErrorStatus=102; // PaveFiller is failed
+    AddError (new BOPAlgo_AlertNoFiller);
     return;
   }
+  GetReport()->Merge (myPaveFiller->GetReport());
 }
+
 //=======================================================================
 //function : Prepare
 //purpose  : 
 //=======================================================================
 void BOPAlgo_Builder::Prepare()
 {
-  myErrorStatus=0;
-  //
   BRep_Builder aBB;
   TopoDS_Compound aC;
   //
@@ -267,7 +266,7 @@ void BOPAlgo_Builder::Prepare()
 //=======================================================================
 void BOPAlgo_Builder::Perform()
 {
-  myErrorStatus=0;
+  GetReport()->Clear();
   //
   if (myEntryPoint==1) {
     if (myPaveFiller) {
@@ -299,6 +298,7 @@ void BOPAlgo_Builder::Perform()
 //=======================================================================
 void BOPAlgo_Builder::PerformWithFiller(const BOPAlgo_PaveFiller& theFiller)
 {
+  GetReport()->Clear();
   myEntryPoint=0;
   myNonDestructive = theFiller.NonDestructive();
   myFuzzyValue = theFiller.FuzzyValue();
@@ -311,14 +311,16 @@ void BOPAlgo_Builder::PerformWithFiller(const BOPAlgo_PaveFiller& theFiller)
 //=======================================================================
 void BOPAlgo_Builder::PerformInternal(const BOPAlgo_PaveFiller& theFiller)
 {
-  try { 
+  GetReport()->Clear();
+  //
+  try {
     OCC_CATCH_SIGNALS
     PerformInternal1(theFiller);
   }
   //
   catch (Standard_Failure) {
-    myErrorStatus=191;
-  }  
+    AddError (new BOPAlgo_AlertBuilderFailed);
+  }
 }
 //=======================================================================
 //function : PerformInternal1
@@ -326,8 +328,6 @@ void BOPAlgo_Builder::PerformInternal(const BOPAlgo_PaveFiller& theFiller)
 //=======================================================================
 void BOPAlgo_Builder::PerformInternal1(const BOPAlgo_PaveFiller& theFiller)
 {
-  myErrorStatus=0;
-  //
   myPaveFiller=(BOPAlgo_PaveFiller*)&theFiller;
   myDS=myPaveFiller->PDS();
   myContext=myPaveFiller->Context();
@@ -336,98 +336,98 @@ void BOPAlgo_Builder::PerformInternal1(const BOPAlgo_PaveFiller& theFiller)
   //
   // 1. CheckData
   CheckData();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   // 2. Prepare
   Prepare();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   // 3. Fill Images
   // 3.1 Vertice
   FillImagesVertices();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   BuildResult(TopAbs_VERTEX);
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   // 3.2 Edges
   FillImagesEdges();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   BuildResult(TopAbs_EDGE);
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   // 3.3 Wires
   FillImagesContainers(TopAbs_WIRE);
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   BuildResult(TopAbs_WIRE);
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   
   // 3.4 Faces
   FillImagesFaces();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   BuildResult(TopAbs_FACE);
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   // 3.5 Shells
   FillImagesContainers(TopAbs_SHELL);
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   
   BuildResult(TopAbs_SHELL);
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   // 3.6 Solids
   FillImagesSolids();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   
   BuildResult(TopAbs_SOLID);
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   // 3.7 CompSolids
   FillImagesContainers(TopAbs_COMPSOLID);
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   
   BuildResult(TopAbs_COMPSOLID);
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   
   // 3.8 Compounds
   FillImagesCompounds();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   
   BuildResult(TopAbs_COMPOUND);
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
index 2938917..b61e5f2 100644 (file)
@@ -40,8 +40,27 @@ class IntTools_Context;
 class TopoDS_Shape;
 class BOPAlgo_PaveFiller;
 
-
-
+//!
+//! The class is a General Fuse algorithm - base algorithm for the
+//! algorithms in the Boolean Component. Its main purpose is to build
+//! the split parts of the argument shapes from which the result of
+//! the operations is combined.<br>
+//! The result of the General Fuse algorithm itself is a compound
+//! containing all split parts of the arguments. <br>
+//!
+//! Additionally to the options of the base classes, the algorithm has
+//! the following options:<br>
+//! - *Safe processing mode* - allows to avoid modification of the input
+//!                            shapes during the operation (by default it is off);<br>
+//! - *Gluing options* - allows to speed up the calculation of the intersections
+//!                      on the special cases, in which some sub-shapes are coinciding.<br>
+//!
+//! The algorithm returns the following Error statuses:
+//! - *BOPAlgo_AlertTooFewArguments* - in case there are no enough arguments to perform the operation;
+//! - *BOPAlgo_AlertNoFiller* - in case the intersection tool has not been created;
+//! - *BOPAlgo_AlertIntersectionFailed* - in case the intersection of the arguments has failed;
+//! - *BOPAlgo_AlertBuilderFailed* - in case building splits of arguments has failed with some unexpected error.
+//!
 class BOPAlgo_Builder  : public BOPAlgo_BuilderShape
 {
 public:
@@ -54,7 +73,7 @@ Standard_EXPORT virtual ~BOPAlgo_Builder();
   
   Standard_EXPORT BOPAlgo_Builder(const BOPCol_BaseAllocator& theAllocator);
   
-  Standard_EXPORT virtual void Clear();
+  Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
   
   Standard_EXPORT BOPAlgo_PPaveFiller PPaveFiller();
   
@@ -124,6 +143,9 @@ protected:
   Standard_EXPORT virtual void PerformInternal1 (const BOPAlgo_PaveFiller& thePF);
   
   Standard_EXPORT virtual void CheckData() Standard_OVERRIDE;
+
+  //! Checks if the intersection algorithm has Errors/Warnings
+  Standard_EXPORT void CheckFiller();
   
   Standard_EXPORT virtual void Prepare();
   
index 6830e6b..f576009 100644 (file)
@@ -20,6 +20,7 @@
 #include <BOPAlgo_BuilderFace.hxx>
 #include <BOPAlgo_WireEdgeSet.hxx>
 #include <BOPAlgo_WireSplitter.hxx>
+#include <BOPAlgo_Alerts.hxx>
 #include <BOPCol_Box2DBndTree.hxx>
 #include <BOPCol_DataMapOfShapeListOfShape.hxx>
 #include <BOPCol_DataMapOfShapeShape.hxx>
@@ -187,10 +188,8 @@ const TopoDS_Face& BOPAlgo_BuilderFace::Face()const
 //=======================================================================
 void BOPAlgo_BuilderFace::CheckData()
 {
-  myErrorStatus=0;
-  //
   if (myFace.IsNull()) {
-    myErrorStatus=12;// Null face generix
+    AddError (new BOPAlgo_AlertNullInputShapes);
     return;
   }
   if (myContext.IsNull()) {
@@ -203,38 +202,38 @@ void BOPAlgo_BuilderFace::CheckData()
 //=======================================================================
 void BOPAlgo_BuilderFace::Perform()
 {
-  myErrorStatus=0;
+  GetReport()->Clear();
   //
   CheckData();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   UserBreak();
   //
   PerformShapesToAvoid();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   UserBreak();
   //
   PerformLoops();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   UserBreak();
   //
   PerformAreas();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   UserBreak();
   //
   PerformInternalShapes();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
 }
@@ -317,10 +316,8 @@ void BOPAlgo_BuilderFace::PerformShapesToAvoid()
 //=======================================================================
 void BOPAlgo_BuilderFace::PerformLoops()
 {
-  myErrorStatus=0;
-  //
   Standard_Boolean bFlag;
-  Standard_Integer i, iErr, aNbEA;
+  Standard_Integer i, aNbEA;
   BOPCol_ListIteratorOfListOfShape aIt;
   BOPCol_IndexedDataMapOfShapeListOfShape aVEMap;
   BOPCol_MapOfOrientedShape aMAdded;
@@ -345,8 +342,7 @@ void BOPAlgo_BuilderFace::PerformLoops()
   aWSp.SetRunParallel(myRunParallel);
   aWSp.SetContext(myContext);
   aWSp.Perform();
-  iErr=aWSp.ErrorStatus();
-  if (iErr) {
+  if (aWSp.HasErrors()) {
     return;
   }
   //
@@ -458,7 +454,6 @@ void BOPAlgo_BuilderFace::PerformAreas()
   BOPCol_Box2DBndTree aBBTree;
   NCollection_UBTreeFiller <Standard_Integer, Bnd_Box2d> aTreeFiller(aBBTree);
   //
-  myErrorStatus=0;
   aNbHoles=0;
   //
   aTol=BRep_Tool::Tolerance(myFace);
@@ -682,7 +677,6 @@ void GetWire(const TopoDS_Shape& aF, TopoDS_Shape& aW)
 //=======================================================================
 void BOPAlgo_BuilderFace::PerformInternalShapes()
 {
-  myErrorStatus=0;
   if (myAvoidInternalShapes) {
     return;
   }
@@ -872,9 +866,3 @@ Standard_Boolean IsGrowthWire(const TopoDS_Shape& theWire,
   }
   return bRet;
 }
-
-//BRepTools::Write(aFF, "ff");
-//
-//  ErrorStatus :
-// 11 - Null Context
-// 12 - Null face generix
index 2b4377b..3f32e32 100644 (file)
 class TopoDS_Face;
 
 
-//! The algorithm to build faces from set of edges
+//! The algorithm to build new faces from the given faces and
+//! set of edges lying on this face.
+//!
+//! The algorithm returns the following Error statuses:
+//! - *BOPAlgo_AlertNullInputShapes* - in case the given face is a null shape.
+//!
 class BOPAlgo_BuilderFace  : public BOPAlgo_BuilderArea
 {
 public:
@@ -53,11 +58,7 @@ Standard_EXPORT virtual ~BOPAlgo_BuilderFace();
   
   Standard_EXPORT TopAbs_Orientation Orientation() const;
 
-
-
-
 protected:
-
   
   //! Collect the edges that
   //! a) are internal
index 8ca9708..aa199ef 100644 (file)
 class TopoDS_Shape;
 
 
-//! Root class for algorithms that has shape as result
+//! Root class for algorithms that has shape as result.<br>
+//! The class provides the History mechanism, which allows
+//! tracking the modification of the input shapes during
+//! the operation.
 class BOPAlgo_BuilderShape  : public BOPAlgo_Algo
 {
 public:
index eaf8258..fa19419 100644 (file)
@@ -17,6 +17,7 @@
 //
 #include <BOPAlgo_BuilderSolid.hxx>
 #include <BOPAlgo_ShellSplitter.hxx>
+#include <BOPAlgo_Alerts.hxx>
 #include <BOPCol_BoxBndTree.hxx>
 #include <BOPCol_DataMapOfShapeListOfShape.hxx>
 #include <BOPCol_DataMapOfShapeShape.hxx>
@@ -297,7 +298,7 @@ const TopoDS_Solid& BOPAlgo_BuilderSolid::Solid()const
 //=======================================================================
 void BOPAlgo_BuilderSolid::Perform()
 {
-  myErrorStatus=0;
+  GetReport()->Clear();
   //
   if (myContext.IsNull()) {
     myContext=new IntTools_Context;
@@ -317,28 +318,28 @@ void BOPAlgo_BuilderSolid::Perform()
   UserBreak();
   //
   PerformShapesToAvoid();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   UserBreak();
   //
   PerformLoops();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   UserBreak();
   //
   PerformAreas();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   UserBreak();
   //
   PerformInternalShapes();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
 }
@@ -428,12 +429,11 @@ void BOPAlgo_BuilderSolid::PerformShapesToAvoid()
 //=======================================================================
 void BOPAlgo_BuilderSolid::PerformLoops()
 {
-  Standard_Integer iErr, i, aNbSh;
+  Standard_Integer i, aNbSh;
   BOPCol_ListIteratorOfListOfShape aIt;
   TopoDS_Iterator aItS;
   Handle(NCollection_BaseAllocator) aAlr;
   // 
-  myErrorStatus=0;
   myLoops.Clear();
   //
   aAlr=
@@ -461,8 +461,17 @@ void BOPAlgo_BuilderSolid::PerformLoops()
   //
   aSSp.SetRunParallel(myRunParallel);
   aSSp.Perform();
-  iErr=aSSp.ErrorStatus();
-  if (iErr) {
+  if (aSSp.HasErrors()) {
+    // add warning status
+    {
+      TopoDS_Compound aFacesSp;
+      BRep_Builder().MakeCompound(aFacesSp);
+      BOPCol_ListIteratorOfListOfShape aItLF(aSSp.StartElements());
+      for (; aItLF.More(); aItLF.Next()) {
+        BRep_Builder().Add(aFacesSp, aItLF.Value());
+      }
+      AddWarning (new BOPAlgo_AlertShellSplitterFailed (aFacesSp));
+    }
     return;
   }
   //
@@ -579,8 +588,6 @@ void BOPAlgo_BuilderSolid::PerformAreas()
   BOPCol_IndexedDataMapOfShapeListOfShape aMSH;
   BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB aItDMISB;
   //
-  myErrorStatus=0;
-  //
   myAreas.Clear();
   //
   //  Draft solids [aNewSolids]
@@ -750,7 +757,6 @@ void BOPAlgo_BuilderSolid::PerformAreas()
 //=======================================================================
 void BOPAlgo_BuilderSolid::PerformInternalShapes()
 {
-  myErrorStatus=0;
   if (myAvoidInternalShapes) {
     return;
   }
@@ -877,7 +883,7 @@ void BOPAlgo_BuilderSolid::PerformInternalShapes()
   if (!aNbVFS) {
     return;
   }
-  // 4. Refine candidares
+  // 4. Refine candidates
   //=============================================================
   BOPAlgo_FaceSolidCnt::Perform(myRunParallel, aVFS, myContext);
   //=============================================================
index e1cba04..2af32e3 100644 (file)
@@ -50,11 +50,7 @@ Standard_EXPORT virtual ~BOPAlgo_BuilderSolid();
   //! Performs the algorithm
   Standard_EXPORT virtual void Perform() Standard_OVERRIDE;
 
-
-
-
 protected:
-
   
   //! Collect the faces that
   //! a) are internal
index 7541264..f18fd3b 100644 (file)
@@ -40,8 +40,6 @@
 //=======================================================================
 void BOPAlgo_Builder::FillImagesVertices()
 {
-  myErrorStatus=0;
-  //
   Standard_Integer nV, nVSD;
   BOPCol_DataMapIteratorOfDataMapOfIntegerInteger aIt;
   //
@@ -73,8 +71,6 @@ void BOPAlgo_Builder::FillImagesVertices()
 //=======================================================================
   void BOPAlgo_Builder::FillImagesEdges()
 {
-  myErrorStatus=0;
-  //
   Standard_Integer i, aNbS = myDS->NbSourceShapes();
   for (i = 0; i < aNbS; ++i) {
     const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
@@ -144,8 +140,6 @@ void BOPAlgo_Builder::FillImagesVertices()
 //=======================================================================
   void BOPAlgo_Builder::BuildResult(const TopAbs_ShapeEnum theType)
 {
-  myErrorStatus=0;
-  //
   TopAbs_ShapeEnum aType;
   BRep_Builder aBB;
   BOPCol_MapOfShape aM;
@@ -180,8 +174,6 @@ void BOPAlgo_Builder::FillImagesVertices()
 //=======================================================================
   void BOPAlgo_Builder::FillImagesContainers(const TopAbs_ShapeEnum theType)
 {
-  myErrorStatus=0;
-  //
   Standard_Integer i, aNbS;
   BOPCol_MapOfShape aMFP(100, myAllocator);
   //
@@ -200,8 +192,6 @@ void BOPAlgo_Builder::FillImagesVertices()
 //=======================================================================
   void BOPAlgo_Builder::FillImagesCompounds()
 {
-  myErrorStatus=0;
-  //
   Standard_Integer i, aNbS;
   BOPCol_MapOfShape aMFP(100, myAllocator);
   //
index 54ed083..e70c957 100644 (file)
@@ -228,8 +228,6 @@ typedef BOPCol_ContextCnt
 //=======================================================================
 void BOPAlgo_Builder::FillImagesFaces()
 {
-  myErrorStatus=0;
-  //
   BuildSplitFaces();
   FillSameDomainFaces();
   FillImagesFaces1();
@@ -254,8 +252,6 @@ void BOPAlgo_Builder::BuildSplitFaces()
   BOPCol_ListOfShape aLFIm(myAllocator);
   BOPAlgo_VectorOfBuilderFace aVBF;
   //
-  myErrorStatus=0;
-  //
   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~scope f
   aAllocator=
     NCollection_BaseAllocator::CommonBaseAllocator();
@@ -474,8 +470,6 @@ void BOPAlgo_Builder::FillSameDomainFaces()
   BOPAlgo_IndexedDataMapOfSetInteger aIDMSS;
   BOPAlgo_VectorOfVectorOfShape aVVS;
   //
-  myErrorStatus=0;
-  //
   const BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
   //
   aNbFFs=aFFs.Extent();
index 040de79..ca5c985 100644 (file)
@@ -503,8 +503,6 @@ void BOPAlgo_Builder::FillImagesSolids()
   Standard_Boolean bHasSolids;
   Standard_Integer i, aNbS;
   //
-  myErrorStatus=0;
-  //
   bHasSolids=Standard_False;
   aNbS=myDS->NbSourceShapes();
   for (i=0; i<aNbS; ++i) {
@@ -558,7 +556,6 @@ void BOPAlgo_Builder::FillIn3DParts
   BOPCol_MapOfShape aMFence(100, aAlr0);
   BOPAlgo_VectorOfShapeBox aVSB(256, aAlr0);
   //
-  myErrorStatus=0;
   theDraftSolids.Clear();
   //
   // 1. aVSB vector Index/FaceBox 
@@ -704,8 +701,6 @@ void BOPAlgo_Builder::BuildDraftSolid(const TopoDS_Shape& theSolid,
                                       TopoDS_Shape& theDraftSolid,
                                       BOPCol_ListOfShape& theLIF)
 {
-  myErrorStatus=0;
-  //
   Standard_Boolean bToReverse;
   Standard_Integer iFlag;
   TopAbs_Orientation aOrF, aOrSh, aOrSd;
@@ -798,8 +793,6 @@ void BOPAlgo_Builder::BuildSplitSolids
    BOPCol_DataMapOfShapeShape& theDraftSolids,
    const BOPCol_BaseAllocator&  )
 {
-  myErrorStatus=0;
-  //
   Standard_Boolean bFlagSD;
   Standard_Integer i, aNbS;
   TopExp_Explorer aExp;
@@ -928,8 +921,6 @@ void BOPAlgo_Builder::BuildSplitSolids
 //=======================================================================
 void BOPAlgo_Builder::FillInternalShapes()
 {
-  myErrorStatus=0;
-  //
   Standard_Integer i, j,  aNbS, aNbSI, aNbSx;
   TopAbs_ShapeEnum aType;
   TopAbs_State aState; 
@@ -1191,7 +1182,3 @@ void TreatCompound(const TopoDS_Shape& theS,
     TreatCompound(aS, aMFence, theLS);
   }
 }
-//
-// ErrorStatus
-// 30 - SolidBuilder failed
-
index f725224..ffc95d7 100644 (file)
@@ -25,6 +25,7 @@
 #include <BOPTools_AlgoTools.hxx>
 
 #include <BOPAlgo_BuilderSolid.hxx>
+#include <BOPAlgo_Alerts.hxx>
 
 #include <BOPCol_MapOfInteger.hxx>
 
@@ -117,7 +118,7 @@ void BOPAlgo_CellsBuilder::PerformInternal1(const BOPAlgo_PaveFiller& theFiller)
 {
   BOPAlgo_Builder::PerformInternal1(theFiller);
   //
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
@@ -446,8 +447,6 @@ void BOPAlgo_CellsBuilder::RemoveAllFromResult()
 //=======================================================================
 void BOPAlgo_CellsBuilder::RemoveInternalBoundaries()
 {
-  myWarningStatus = 0;
-  //
   if (myMaterials.IsEmpty()) {
     return;
   }
@@ -489,7 +488,15 @@ void BOPAlgo_CellsBuilder::RemoveInternalBoundaries()
     //
     BOPCol_ListOfShape aLSNew;
     if (aItLS.More()) {
-      myWarningStatus |= RemovalOfIBForMDimShapes;
+      // add the warning
+      {
+        TopoDS_Compound aMultiDimS;
+        aBB.MakeCompound(aMultiDimS);
+        aBB.Add(aMultiDimS, aLS.First());
+        aBB.Add(aMultiDimS, aItLS.Value());
+        //
+        AddWarning (new BOPAlgo_AlertRemovalOfIBForMDimShapes (aMultiDimS));
+      }
       aLSNew.Assign(aLS);
     }
     else {
@@ -755,7 +762,12 @@ Standard_Boolean BOPAlgo_CellsBuilder::RemoveInternals(const BOPCol_ListOfShape&
     }
     //
     if (theLSNew.IsEmpty()) {
-      myWarningStatus |= (bFaces ? RemovalOfIBForFacesFailed : RemovalOfIBForEdgesFailed);
+      // add the warning
+      if (bFaces)
+        AddWarning (new BOPAlgo_AlertRemovalOfIBForFacesFailed (aShape));
+      else
+        AddWarning (new BOPAlgo_AlertRemovalOfIBForEdgesFailed (aShape));
+      //
       theLSNew.Assign(theLS);
       return bRemoved;
     }
@@ -855,8 +867,18 @@ Standard_Boolean BOPAlgo_CellsBuilder::RemoveInternals(const BOPCol_ListOfShape&
       aBS.SetShapes(aLFUnique);
       aBS.Perform();
       //
-      if (aBS.ErrorStatus() || aBS.Areas().Extent() != 1) {
-        myWarningStatus |= RemovalOfIBForSolidsFailed;
+      if (aBS.HasErrors() || aBS.Areas().Extent() != 1) {
+        // add the warning
+        {
+          TopoDS_Compound aUniqeFaces;
+          aBB.MakeCompound(aUniqeFaces);
+          BOPCol_ListIteratorOfListOfShape aItLFUniqe(aLFUnique);
+          for (; aItLFUniqe.More(); aItLFUniqe.Next()) {
+            aBB.Add(aUniqeFaces, aItLFUniqe.Value());
+          }
+          //
+          AddWarning (new BOPAlgo_AlertRemovalOfIBForSolidsFailed (aUniqeFaces));
+        }
         //
         aItS.Initialize(aCB);
         for (; aItS.More(); aItS.Next()) {
@@ -1078,30 +1100,3 @@ TopAbs_ShapeEnum TypeToExplore(const Standard_Integer theDim)
   }
   return aRet;
 }
-
-//=======================================================================
-//function : DumpWarnings
-//purpose  : 
-//=======================================================================
-void BOPAlgo_CellsBuilder::DumpWarnings(Standard_OStream& theOS) const
-{
-  Standard_Integer aWarningStatus[4] = {
-    RemovalOfIBForMDimShapes,
-    RemovalOfIBForSolidsFailed,
-    RemovalOfIBForFacesFailed,
-    RemovalOfIBForEdgesFailed,
-  };
-  //
-  Standard_CString aWarningMessage[4] = {
-    "Removal of internal boundaries among the multi-dimensional shapes is not supported yet.",
-    "Removal of internal boundaries among Solids has failed.",
-    "Removal of internal boundaries among Faces has failed.",
-    "Removal of internal boundaries among Edges has failed."
-  };
-  //
-  for (Standard_Integer i = 0; i < 4; ++i) {
-    if (myWarningStatus & aWarningStatus[i]) {
-      theOS << "Warning: " << aWarningMessage[i] << "\n";
-    }
-  }
-}
index 6339a99..8cfff60 100644 (file)
 //! There could be Generated shapes only after removing of the internal boundaries
 //! between faces and edges, i.e. after using ShapeUpgrade_UnifySameDomain tool.<br>
 //!
-//! The algorithm can return the following Error Statuses:<br>
-//! - 0 - in case of success;<br>
-//! - Error status acquired in the General Fuse algorithm.<br>
-//! The Error status can be checked with ErrorStatus() method.
-//! If the Error status is not equal to zero, the result cannot be trustworthy.<br>
+//! The algorithm can return the following Error Statuses:
+//! - Error status acquired in the General Fuse algorithm.
+//! The Error status can be checked with HasErrors() method.
+//! If the Error status is not equal to zero, the result cannot be trustworthy.
 //!
-//! The algorithm can return the following Warning Statuses:<br>
-//! - 0 - no warnings occurred;<br>
-//! - Warning status acquired in the General Fuse algorithm;<br>
-//! - One of the warnings from BOPAlgo_CellsBuilder_WarningStatusEnum.<br>
-//! The Warning status can be checked with WarningStatus() method or
-//! printed with the DumpWarnings() method. If the Warning status is not equal
-//! to zero, the result may be not as expected.<br>
+//! The algorithm can set the following Warning Statuses:
+//! - Warning status acquired in the General Fuse algorithm;
+//! - BOPAlgo_AlertRemovalOfIBForMDimShapes
+//! - BOPAlgo_AlertRemovalOfIBForFacesFailed
+//! - BOPAlgo_AlertRemovalOfIBForEdgesFailed
+//! - BOPAlgo_AlertRemovalOfIBForSolidsFailed
+//!
+//! The Warning status can be checked with HasWarnings() method or
+//! printed with the DumpWarnings() method. If warnings are recorded,
+//! the result may be not as expected.<br>
 //!
 //! Examples:<br>
 //! 1. API<br>
 //! aCBuilder.SetFuzzyValue(aTol);<br>
 //! //<br>
 //! aCBuilder.Perform();<br>
-//! if (aCBuilder.ErrorStatus()) { // check error status<br>
+//! if (aCBuilder.HasErrors()) { // check error status<br>
 //!   return;<br>
 //! }<br>
 //! /* empty compound, as nothing has been added yet */<br>
@@ -226,8 +228,8 @@ class BOPAlgo_CellsBuilder : public BOPAlgo_Builder
   //! Removes internal boundaries between cells with the same material.<br>
   //! If the result contains the cells with same material but of different dimension
   //! the removal of internal boundaries between these cells will not be performed.<br>
-  //! In case of some errors during the removal the method will set the appropriate warning status -
-  //! see the WarningStatusEnum enumeration.
+  //! In case of some errors during the removal the method will set the appropriate warning 
+  //! status - use GetReport() to access them.
   Standard_EXPORT void RemoveInternalBoundaries();
 
   //! Get all split parts.
@@ -242,23 +244,6 @@ class BOPAlgo_CellsBuilder : public BOPAlgo_Builder
   //! Returns true if the shape theS has been deleted.
   Standard_EXPORT virtual Standard_Boolean IsDeleted (const TopoDS_Shape& theS) Standard_OVERRIDE;
 
-  //! Define possible warning statuses of the CellsBuilder algorithm:<br>
-  //! - RemovalOfIBForMDimShapes - The result contains multi-dimensional shapes with the same
-  //!                              material. Removal of internal boundaries has not been performed.<br>
-  //! - RemovalOfIBForSolidsFailed - Removal of internal boundaries among Solids has failed.<br>
-  //! - RemovalOfIBForFacesFailed  - Removal of internal boundaries among Faces has failed.<br>
-  //! - RemovalOfIBForEdgesFailed  - Removal of internal boundaries among Edges has failed.<br>
-  enum WarningStatusEnum
-  {
-    RemovalOfIBForMDimShapes = 2,
-    RemovalOfIBForSolidsFailed = 4,
-    RemovalOfIBForFacesFailed = 8,
-    RemovalOfIBForEdgesFailed = 16
-  };
-
-  //! Dumps the warning status
-  Standard_EXPORT virtual void DumpWarnings(Standard_OStream& theOS) const;
-
  protected:
 
    //! Redefined method Prepare - no need to prepare history
index 06d6360..35dfe50 100644 (file)
@@ -18,6 +18,7 @@
 //
 
 #include <BOPAlgo_CheckerSI.hxx>
+#include <BOPAlgo_Alerts.hxx>
 #include <BOPCol_MapOfShape.hxx>
 #include <BOPCol_Parallel.hxx>
 #include <BOPDS_DS.hxx>
@@ -151,8 +152,6 @@ void BOPAlgo_CheckerSI::SetLevelOfCheck(const Standard_Integer theLevel)
 //=======================================================================
 void BOPAlgo_CheckerSI::Init()
 {
-  myErrorStatus=0;
-  //
   Clear();
   //
   // 1. myDS
@@ -170,8 +169,6 @@ void BOPAlgo_CheckerSI::Init()
   //
   // 3 myContext
   myContext=new IntTools_Context;
-  //
-  myErrorStatus=0;
 }
 //=======================================================================
 //function : Perform
@@ -182,9 +179,8 @@ void BOPAlgo_CheckerSI::Perform()
   try {
     OCC_CATCH_SIGNALS
     //
-    myErrorStatus = 0;
     if (myArguments.Extent() != 1) {
-      myErrorStatus = 10;
+      AddError (new BOPAlgo_AlertMultipleArguments);
       return;
     }
     //
@@ -194,16 +190,16 @@ void BOPAlgo_CheckerSI::Perform()
     CheckFaceSelfIntersection();
     
     // Perform intersection with solids
-    if (!myErrorStatus)
+    if (!HasErrors())
       PerformVZ();
     //
-    if (!myErrorStatus)
+    if (!HasErrors())
       PerformEZ();
     //
-    if (!myErrorStatus)
+    if (!HasErrors())
       PerformFZ();
     //
-    if (!myErrorStatus)
+    if (!HasErrors())
       PerformZZ();
     //
     // Treat the intersection results
@@ -211,7 +207,7 @@ void BOPAlgo_CheckerSI::Perform()
   }
   //
   catch (Standard_Failure) {
-    myErrorStatus = 11;
+    AddError (new BOPAlgo_AlertIntersectionFailed);
   }
 }
 //=======================================================================
@@ -223,8 +219,6 @@ void BOPAlgo_CheckerSI::PostTreat()
   Standard_Integer i, aNb, n1, n2; 
   BOPDS_Pair aPK;
   //
-  myErrorStatus=0;
-  //
   BOPDS_MapOfPair& aMPK=
     *((BOPDS_MapOfPair*)&myDS->Interferences());
 
index f764f59..da10832 100644 (file)
 #include <BOPAlgo_PaveFiller.hxx>
 
 
-//! Checks the shape on self-interference.<br>
-//! In case of error the algorithm may return the following ErrorStatus:<br>
-//! 10 - The number of the input arguments is not one;<br>
-//! 11 - The check has been aborted during intersection of sub-shapes.<br>
+//! Checks the shape on self-interference.
+//!
+//! The algorithm can set the following errors:
+//! - *BOPAlgo_AlertMultipleArguments* - The number of the input arguments is not one;
+//! - *BOPALgo_ErrorIntersectionFailed* - The check has been aborted during intersection of sub-shapes.
 //! In case the error has occurred during intersection of sub-shapes, i.e.
-//! in BOPAlgo_PaveFiller::PerformInternal() method, the ErrorStatus from this method
+//! in BOPAlgo_PaveFiller::PerformInternal() method, the errors from this method
 //! directly will be returned.
 
 class BOPAlgo_CheckerSI  : public BOPAlgo_PaveFiller
index 1214605..469c48f 100644 (file)
@@ -247,8 +247,6 @@ void BOPAlgo_CheckerSI::PerformVZ()
   TopAbs_State aState;
   BOPDS_MapOfPair aMPK;
   //
-  myErrorStatus=0;
-  //
   myIterator->Initialize(TopAbs_VERTEX, TopAbs_SOLID);
   iSize=myIterator->ExpectedLength();
   if (!iSize) {
@@ -327,8 +325,6 @@ void BOPAlgo_CheckerSI::PerformZZ()
   Standard_Boolean bHasInterf;
   Standard_Integer iSize, nZ1, nZ, k, aNbSolidSolid;
   //
-  myErrorStatus=0;
-  //
   myIterator->Initialize(TopAbs_SOLID, TopAbs_SOLID);
   iSize=myIterator->ExpectedLength();
   if (!iSize) {
@@ -376,8 +372,6 @@ void BOPAlgo_CheckerSI::PerformSZ(const TopAbs_ShapeEnum aTS)
   Standard_Boolean bHasInterf;
   Standard_Integer iSize, nS, nZ, k, aNbShapeSolid;
   //
-  myErrorStatus=0;
-  //
   myIterator->Initialize(aTS, TopAbs_SOLID);
   iSize=myIterator->ExpectedLength();
   if (!iSize) {
index 6bda860..695118a 100644 (file)
@@ -16,6 +16,7 @@
 #include <BOPAlgo_BuilderSolid.hxx>
 #include <BOPAlgo_MakerVolume.hxx>
 #include <BOPAlgo_PaveFiller.hxx>
+#include <BOPAlgo_Alerts.hxx>
 #include <BOPCol_DataMapOfShapeListOfShape.hxx>
 #include <BOPCol_ListOfShape.hxx>
 #include <BOPDS_DS.hxx>
@@ -40,20 +41,11 @@ static
 void BOPAlgo_MakerVolume::CheckData()
 {
   if (myArguments.IsEmpty()) {
-    myErrorStatus = 100; // no arguments to process
-    return;
-  }
-  // myPaveFiller
-  if (!myPaveFiller) {
-    myErrorStatus = 101; 
+    AddError (new BOPAlgo_AlertTooFewArguments); // no arguments to process
     return;
   }
   //
-  myErrorStatus = myPaveFiller->ErrorStatus();
-  if (myErrorStatus) {
-    myErrorStatus = 102; // PaveFiller is failed
-    return;
-  }
+  CheckFiller();
 }
 
 //=======================================================================
@@ -62,7 +54,7 @@ void BOPAlgo_MakerVolume::CheckData()
 //=======================================================================
 void BOPAlgo_MakerVolume::Perform()
 {
-  myErrorStatus = 0;
+  GetReport()->Clear();
   //
   if (myEntryPoint == 1) {
     if (myPaveFiller) {
@@ -115,21 +107,19 @@ void BOPAlgo_MakerVolume::Perform()
 void BOPAlgo_MakerVolume::PerformInternal1
   (const BOPAlgo_PaveFiller& theFiller)
 {
-  myErrorStatus=0;
-  //
   myPaveFiller = (BOPAlgo_PaveFiller*)&theFiller;
   myDS = myPaveFiller->PDS();
   myContext = myPaveFiller->Context();
   //
   // 1. CheckData
   CheckData();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   // 2. Prepare
   Prepare();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
@@ -137,29 +127,29 @@ void BOPAlgo_MakerVolume::PerformInternal1
   // 3.1. Vertice
   if (myIntersect) {
     FillImagesVertices();
-    if (myErrorStatus) {
+    if (HasErrors()) {
       return;
     }
     // 3.2. Edges
     FillImagesEdges();
-    if (myErrorStatus) {
+    if (HasErrors()) {
       return;
     }
     // 3.3. Wires
     FillImagesContainers(TopAbs_WIRE);
-    if (myErrorStatus) {
+    if (HasErrors()) {
       return;
     }
     // 3.4. Faces
     FillImagesFaces();
-    if (myErrorStatus) {
+    if (HasErrors()) {
       return;
     }
   }
   //
   // 4. Collect faces
   CollectFaces();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
@@ -171,7 +161,7 @@ void BOPAlgo_MakerVolume::PerformInternal1
   //
   // 6. Make volumes
   BuildSolids(aLSR);
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
@@ -272,8 +262,9 @@ void BOPAlgo_MakerVolume::BuildSolids(BOPCol_ListOfShape& theLSR)
   aBS.SetRunParallel(myRunParallel);
   aBS.SetAvoidInternalShapes(myAvoidInternalShapes);
   aBS.Perform();
-  if (aBS.ErrorStatus()) {
-    myErrorStatus = 103;
+  if (aBS.HasErrors())
+  {
+    AddError (new BOPAlgo_AlertSolidBuilderFailed); // SolidBuilder failed
     return;
   }
   //
@@ -472,4 +463,3 @@ void TreatCompound(const TopoDS_Shape& theS,
     TreatCompound(aS, aMFence, theLS);
   }
 }
-
index ce9e15c..f4ea8e0 100644 (file)
@@ -89,11 +89,9 @@ class BOPAlgo_PaveFiller;
 //!
 //! <myRunParallel> - Defines whether the parallel processing is
 //! switched on or not.
-//! <myErrorStatus> - Error status of the operation:
-//! 0   - operation successful;
-//! 100 - no shapes to process;
-//! 102 - BOPAlgo_PaveFiller algorithm has failed;
-//! 103 - BOPAlgo_BuilderSolid algorithm has failed.
+//! <myReport> - Error status of the operation. Additionally to the
+//! errors of the parent algorithm it can have the following values:
+//! - *BOPAlgo_AlertSolidBuilderFailed* - BOPAlgo_BuilderSolid algorithm has failed.
 //!
 //! Example:
 //!
@@ -181,6 +179,7 @@ protected:
   //! Builds the result.
   Standard_EXPORT void BuildShape (const BOPCol_ListOfShape& theLSR);
 
+
   Standard_Boolean myIntersect;
   Bnd_Box myBBox;
   TopoDS_Solid mySBox;
diff --git a/src/BOPAlgo/BOPAlgo_Options.cxx b/src/BOPAlgo/BOPAlgo_Options.cxx
new file mode 100644 (file)
index 0000000..ddbade6
--- /dev/null
@@ -0,0 +1,151 @@
+// Created by: Eugeny MALTCHIKOV
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+
+#include <BOPAlgo_Options.hxx>
+#include <Message_MsgFile.hxx>
+#include <Message_ProgressIndicator.hxx>
+#include <NCollection_BaseAllocator.hxx>
+#include <Precision.hxx>
+#include <Standard_NotImplemented.hxx>
+#include <Standard_ProgramError.hxx>
+
+namespace
+{
+  Standard_Boolean myGlobalRunParallel = Standard_False;
+
+  // Initialize textual messages for errors and warnings defined in BOPAlgo
+  #include "BOPAlgo_BOPAlgo_msg.pxx"
+  bool BOPAlgo_InitMessages = false;
+  void BOPAlgo_LoadMessages ()
+  {
+    if (BOPAlgo_InitMessages)
+      return;
+    BOPAlgo_InitMessages = true;
+
+    if (! Message_MsgFile::HasMsg ("BOPAlgo_LOAD_CHECKER"))
+    {
+      Message_MsgFile::LoadFromString (BOPAlgo_BOPAlgo_msg);
+    }
+  }
+}
+
+//=======================================================================
+// function: 
+// purpose: 
+//=======================================================================
+BOPAlgo_Options::BOPAlgo_Options()
+:
+  myAllocator(NCollection_BaseAllocator::CommonBaseAllocator()),
+  myReport(new Message_Report),
+  myRunParallel(myGlobalRunParallel),
+  myFuzzyValue(Precision::Confusion())
+{
+  BOPAlgo_LoadMessages();
+}
+
+//=======================================================================
+// function: 
+// purpose: 
+//=======================================================================
+BOPAlgo_Options::BOPAlgo_Options
+  (const Handle(NCollection_BaseAllocator)& theAllocator)
+:
+  myAllocator(theAllocator),
+  myReport(new Message_Report),
+  myRunParallel(myGlobalRunParallel),
+  myFuzzyValue(Precision::Confusion())
+{
+  BOPAlgo_LoadMessages();
+}
+
+//=======================================================================
+// function: ~
+// purpose: 
+//=======================================================================
+BOPAlgo_Options::~BOPAlgo_Options()
+{
+}
+
+//=======================================================================
+//function : DumpErrors
+//purpose  : 
+//=======================================================================
+void BOPAlgo_Options::DumpErrors(Standard_OStream& theOS) const
+{
+  myReport->Dump (theOS, Message_Fail);
+}
+
+//=======================================================================
+//function : DumpWarnings
+//purpose  : 
+//=======================================================================
+void BOPAlgo_Options::DumpWarnings(Standard_OStream& theOS) const
+{
+  myReport->Dump (theOS, Message_Warning);
+}
+
+//=======================================================================
+// function: 
+// purpose: 
+//=======================================================================
+void BOPAlgo_Options::SetParallelMode(Standard_Boolean theNewMode)
+{
+  myGlobalRunParallel = theNewMode;
+}
+
+//=======================================================================
+// function: 
+// purpose: 
+//=======================================================================
+Standard_Boolean BOPAlgo_Options::GetParallelMode()
+{
+  return myGlobalRunParallel;
+}
+
+
+//=======================================================================
+//function : SetFuzzyValue
+//purpose  : 
+//=======================================================================
+void BOPAlgo_Options::SetFuzzyValue(const Standard_Real theFuzz)
+{
+  myFuzzyValue = Max(theFuzz, Precision::Confusion());
+}
+
+
+//=======================================================================
+//function : SetProgressIndicator
+//purpose  : 
+//=======================================================================
+void BOPAlgo_Options::SetProgressIndicator
+  (const Handle(Message_ProgressIndicator)& theObj)
+{
+  if (!theObj.IsNull()) {
+    myProgressIndicator = theObj;
+  }
+}
+//=======================================================================
+//function : UserBreak
+//purpose  : 
+//=======================================================================
+void BOPAlgo_Options::UserBreak() const
+{
+  if (myProgressIndicator.IsNull()) {
+    return;
+  }
+  if (myProgressIndicator->UserBreak()) {
+    throw Standard_NotImplemented("BOPAlgo_Options::UserBreak(), method is not implemented");
+  }
+}
diff --git a/src/BOPAlgo/BOPAlgo_Options.hxx b/src/BOPAlgo/BOPAlgo_Options.hxx
new file mode 100644 (file)
index 0000000..4be0ec0
--- /dev/null
@@ -0,0 +1,175 @@
+// Created by: Eugeny MALTCHIKOV
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BOPAlgo_Options_HeaderFile
+#define _BOPAlgo_Options_HeaderFile
+
+#include <Message_Report.hxx>
+#include <Standard_OStream.hxx>
+
+#include <BOPCol_BaseAllocator.hxx>
+
+class Message_ProgressIndicator;
+
+//! The class provides the following options for the algorithms in Boolean Component:
+//! - *Memory allocation tool* - tool for memory allocations;
+//! - *Error and warning reporting* - allows recording warnings and errors occurred 
+//!                              during the operation.
+//!                              Error means that the algorithm has failed.
+//! - *Parallel processing mode* - provides the possibility to perform operation in parallel mode;
+//! - *Fuzzy tolerance* - additional tolerance for the operation to detect
+//!                       touching or coinciding cases;
+//! - *Progress indicator* - provides interface to track the progress of
+//!                          operation and stop the operation by user's break.
+//!
+class BOPAlgo_Options
+{
+public:
+
+  DEFINE_STANDARD_ALLOC
+
+  //! Empty constructor
+  Standard_EXPORT BOPAlgo_Options();
+
+  //! Constructor with allocator
+  Standard_EXPORT BOPAlgo_Options(const BOPCol_BaseAllocator& theAllocator);
+
+  //! Destructor
+  Standard_EXPORT virtual ~BOPAlgo_Options();
+
+  //! Returns allocator
+  const BOPCol_BaseAllocator& Allocator() const
+  {
+    return myAllocator;
+  }
+
+  //! Clears all warnings and errors, and any data cached by the algorithm.
+  //! User defined options are not cleared.
+  virtual void Clear()
+  {
+    myReport->Clear();
+  }
+
+public:
+  //!@name Error reporting mechanism
+
+  //! Adds the alert as error (fail)
+  void AddError (const Handle(Message_Alert)& theAlert)
+  {
+    myReport->AddAlert (Message_Fail, theAlert);
+  }
+
+  //! Adds the alert as warning
+  void AddWarning (const Handle(Message_Alert)& theAlert)
+  {
+    myReport->AddAlert (Message_Warning, theAlert);
+  }
+
+  //! Returns true if algorithm has failed
+  Standard_Boolean HasErrors() const
+  {
+    return ! myReport->GetAlerts(Message_Fail).IsEmpty();
+  }
+
+  //! Returns true if algorithm has generated error of specified type
+  Standard_Boolean HasError (const Handle(Standard_Type)& theType) const
+  {
+    return myReport->HasAlert(theType, Message_Fail);
+  }
+
+  //! Returns true if algorithm has generated some warning alerts
+  Standard_Boolean HasWarnings() const
+  {
+    return ! myReport->GetAlerts(Message_Warning).IsEmpty();
+  }
+
+  //! Returns true if algorithm has generated warning of specified type
+  Standard_Boolean HasWarning (const Handle(Standard_Type)& theType) const
+  {
+    return myReport->HasAlert(theType, Message_Warning);
+  }
+
+  //! Returns report collecting all errors and warnings
+  const Handle(Message_Report)& GetReport () const { return myReport; }
+
+  //! Dumps the error status into the given stream
+  Standard_EXPORT void DumpErrors(Standard_OStream& theOS) const;
+
+  //! Dumps the warning statuses into the given stream
+  Standard_EXPORT void DumpWarnings(Standard_OStream& theOS) const;
+
+  //! Clears the warnings of the algorithm
+  void ClearWarnings()
+  {
+    myReport->Clear (Message_Warning);
+  }
+
+public:
+  //!@name Parallel processing mode
+
+  //! Gets the global parallel mode
+  Standard_EXPORT static Standard_Boolean GetParallelMode();
+
+  //! Sets the global parallel mode
+  Standard_EXPORT static void SetParallelMode(const Standard_Boolean theNewMode);
+
+  //! Set the flag of parallel processing
+  //! if <theFlag> is true  the parallel processing is switched on
+  //! if <theFlag> is false the parallel processing is switched off
+  void SetRunParallel(const Standard_Boolean theFlag)
+  {
+    myRunParallel = theFlag;
+  }
+
+  //! Returns the flag of parallel processing
+  Standard_Boolean RunParallel() const
+  {
+    return myRunParallel;
+  }
+
+public:
+  //!@name Fuzzy tolerance
+
+  //! Sets the additional tolerance
+  Standard_EXPORT void SetFuzzyValue(const Standard_Real theFuzz);
+
+  //! Returns the additional tolerance
+  Standard_Real FuzzyValue() const
+  {
+    return myFuzzyValue;
+  }
+
+public:
+  //!@name Progress indicator
+
+  //! Set the Progress Indicator object.
+  Standard_EXPORT void SetProgressIndicator(const Handle(Message_ProgressIndicator)& theObj);
+
+protected:
+
+  //! Breaks the execution if the break signal
+  //! is indicated by myProgressIndicator.
+  Standard_EXPORT void UserBreak() const;
+
+protected:
+
+  BOPCol_BaseAllocator myAllocator;
+  Handle(Message_Report) myReport;
+  Standard_Boolean myRunParallel;
+  Standard_Real myFuzzyValue;
+  Handle(Message_ProgressIndicator) myProgressIndicator;
+
+};
+
+#endif // _BOPAlgo_Options_HeaderFile
index 0ee5f44..5867221 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <BOPAlgo_PaveFiller.hxx>
 #include <BOPAlgo_SectionAttribute.hxx>
+#include <BOPAlgo_Alerts.hxx>
 #include <BOPDS_Curve.hxx>
 #include <BOPDS_DS.hxx>
 #include <BOPDS_Iterator.hxx>
@@ -124,6 +125,7 @@ Standard_Boolean BOPAlgo_PaveFiller::IsPrimary()const
 //=======================================================================
 void BOPAlgo_PaveFiller::Clear()
 {
+  BOPAlgo_Algo::Clear();
   if (myIterator) {
     delete myIterator;
     myIterator=NULL;
@@ -188,13 +190,19 @@ const BOPCol_ListOfShape& BOPAlgo_PaveFiller::Arguments()const
 //=======================================================================
 void BOPAlgo_PaveFiller::Init()
 {
-  myErrorStatus=0;
-  //
   if (!myArguments.Extent()) {
-    myErrorStatus=10;
+    AddError (new BOPAlgo_AlertTooFewArguments);
     return;
   }
   //
+  BOPCol_ListIteratorOfListOfShape aIt(myArguments);
+  for (; aIt.More(); aIt.Next()) {
+    if (aIt.Value().IsNull()) {
+      AddError (new BOPAlgo_AlertNullInputShapes);
+      return;
+    }
+  }
+  //
   // 0 Clear
   Clear();
   //
@@ -214,8 +222,6 @@ void BOPAlgo_PaveFiller::Init()
   //
   // 4 NonDestructive flag
   SetNonDestructive();
-  //
-  myErrorStatus=0;
 }
 //=======================================================================
 // function: Perform
@@ -223,15 +229,14 @@ void BOPAlgo_PaveFiller::Init()
 //=======================================================================
 void BOPAlgo_PaveFiller::Perform()
 {
-  myErrorStatus=0;
-  try { 
+  try {
     OCC_CATCH_SIGNALS
     //
     PerformInternal();
   }
   //
   catch (Standard_Failure) {
-    myErrorStatus=11;
+    AddError (new BOPAlgo_AlertIntersectionFailed);
   } 
 }
 //=======================================================================
@@ -240,44 +245,42 @@ void BOPAlgo_PaveFiller::Perform()
 //=======================================================================
 void BOPAlgo_PaveFiller::PerformInternal()
 {
-  myErrorStatus=0;
-  //
   Init();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return; 
   }
   //
   Prepare();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return; 
   }
   // 00
   PerformVV();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return; 
   }
   // 01
   PerformVE();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return; 
   }
   //
   UpdatePaveBlocksWithSDVertices();
   // 11
   PerformEE();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return; 
   }
   UpdatePaveBlocksWithSDVertices();
   // 02
   PerformVF();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return; 
   }
   UpdatePaveBlocksWithSDVertices();
   // 12
   PerformEF();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return; 
   }
   UpdatePaveBlocksWithSDVertices();
@@ -285,35 +288,37 @@ void BOPAlgo_PaveFiller::PerformInternal()
   //
   // 22
   PerformFF();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return; 
   }
   //
   UpdateBlocksWithSharedVertices();
   //
   MakeSplitEdges();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return; 
   }
   //
   UpdatePaveBlocksWithSDVertices();
   //
   MakeBlocks();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return; 
   }
   //
+  CheckSelfInterference();
+  //
   UpdateInterfsWithSDVertices();
   myDS->ReleasePaveBlocks();
   myDS->RefineFaceInfoOn();
   //
   MakePCurves();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return; 
   }
   //
   ProcessDE();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return; 
   }
 }
index 7112894..ab79f4e 100644 (file)
@@ -51,6 +51,7 @@
 #include <BOPCol_IndexedDataMapOfShapeInteger.hxx>
 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
 #include <BOPAlgo_GlueEnum.hxx>
+#include <IntTools_ShrunkRange.hxx>
 class IntTools_Context;
 class BOPDS_DS;
 class BOPAlgo_SectionAttribute;
@@ -62,7 +63,44 @@ class TopoDS_Vertex;
 class TopoDS_Edge;
 class TopoDS_Face;
 
-
+//!
+//! The class represents the Intersection phase of the
+//! Boolean Operations algorithm.<br>
+//! It performs the pairwise intersection of the sub-shapes of
+//! the arguments in the following order:<br>
+//! 1. Vertex/Vertex;<br>
+//! 2. Vertex/Edge;<br>
+//! 3. Edge/Edge;<br>
+//! 4. Vertex/Face;<br>
+//! 5. Edge/Face;<br>
+//! 6. Face/Face.<br>
+//!
+//! The results of intersection are stored into the Data Structure
+//! of the algorithm.<br>
+//!
+//! Additionally to the options provided by the parent class,
+//! the algorithm has the following options:<br>
+//! - *Section attributes* - allows to customize the intersection of the faces
+//!                          (avoid approximation or building 2d curves);<br>
+//! - *Safe processing mode* - allows to avoid modification of the input
+//!                            shapes during the operation (by default it is off);<br>
+//! - *Gluing options* - allows to speed up the calculation on the special
+//!                      cases, in which some sub-shapes are coincide.<br>
+//!
+//! The algorithm returns the following Warning statuses:<br>
+//! - *BOPAlgo_AlertSelfInterferingShape* - in case some of the argument shapes are self-interfering shapes;<br>
+//! - *BOPAlgo_AlertTooSmallEdge* - in case some edges of the input shapes have no valid range;<br>
+//! - *BOPAlgo_AlertNotSplittableEdge* - in case some edges of the input shapes has such a small
+//!                         valid range so it cannot be split;<br>
+//! - *BOPAlgo_AlertBadPositioning* - in case the positioning of the input shapes leads to creation
+//!                      of small edges.<br>
+//!
+//! The algorithm returns the following Error alerts:
+//! - *BOPAlgo_AlertTooFewArguments* - in case there are no enough arguments to
+//!                      perform the operation;<br>
+//! - *BOPAlgo_AlertIntersectionFailed* - in case some unexpected error occurred;<br>
+//! - *BOPAlgo_AlertNullInputShapes* - in case some of the arguments are null shapes.<br>
+//!
 class BOPAlgo_PaveFiller  : public BOPAlgo_Algo
 {
 public:
@@ -140,7 +178,7 @@ protected:
 
   Standard_EXPORT virtual void PerformInternal();
   
-  Standard_EXPORT virtual void Clear();
+  Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
   
   Standard_EXPORT virtual void Init();
   
@@ -193,6 +231,12 @@ protected:
   
   Standard_EXPORT void FillShrunkData (const TopAbs_ShapeEnum theType1, const TopAbs_ShapeEnum theType2);
 
+  //! Analyzes the results of computation of the valid range for the
+  //! pave block and in case of error adds the warning status, otherwise
+  //! saves the valid range in the pave block.
+  Standard_EXPORT void AnalyzeShrunkData(const Handle(BOPDS_PaveBlock)& thePB,
+                                         const IntTools_ShrunkRange& theSR);
+
   //! Performs intersection of new vertices, obtained in E/E and E/F intersections
   Standard_EXPORT void PerformNewVertices(BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB,
                                           const BOPCol_BaseAllocator& theAllocator,
@@ -242,11 +286,11 @@ protected:
   
 
   //! Treatment of section edges.
-  Standard_EXPORT Standard_Integer PostTreatFF (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB,
-                                                BOPDS_DataMapOfPaveBlockListOfPaveBlock& theDMExEdges,
-                                                BOPCol_DataMapOfIntegerInteger& theDMNewSD,
-                                                const BOPCol_IndexedMapOfShape& theMicroEdges,
-                                                const BOPCol_BaseAllocator& theAllocator);
+  Standard_EXPORT void PostTreatFF (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB,
+                                    BOPDS_DataMapOfPaveBlockListOfPaveBlock& theDMExEdges,
+                                    BOPCol_DataMapOfIntegerInteger& theDMNewSD,
+                                    const BOPCol_IndexedMapOfShape& theMicroEdges,
+                                    const BOPCol_BaseAllocator& theAllocator);
   
   Standard_EXPORT void FindPaveBlocks (const Standard_Integer theV, const Standard_Integer theF, BOPDS_ListOfPaveBlock& theLPB);
   
@@ -420,6 +464,17 @@ protected:
   //! and will be used for splitting.
   Standard_EXPORT void PutSEInOtherFaces();
 
+  //! Analyzes the results of interferences of sub-shapes of the shapes
+  //! looking for self-interfering entities by the following rules:<br>
+  //! 1. The Faces of the same shape considered interfering in case they:<br>
+  //!    - Interfere with the other shapes in the same place (in the same vertex) or;<br>
+  //!    - Included in the same common block.
+  //! 2. The Faces of the same shape considered interfering in case they
+  //!    share the IN or SECTION edges.<br>
+  //! In case self-interference is found the warning is added.
+  Standard_EXPORT void CheckSelfInterference();
+
+
   BOPCol_ListOfShape myArguments;
   BOPDS_PDS myDS;
   BOPDS_PIterator myIterator;
index 063237e..5b5505c 100644 (file)
@@ -19,6 +19,7 @@
 #include <Bnd_Box.hxx>
 #include <BOPAlgo_PaveFiller.hxx>
 #include <BOPAlgo_Tools.hxx>
+#include <BOPAlgo_Alerts.hxx>
 #include <BOPCol_DataMapOfIntegerInteger.hxx>
 #include <BOPCol_DataMapOfIntegerListOfInteger.hxx>
 #include <BOPCol_IndexedDataMapOfIntegerListOfInteger.hxx>
@@ -30,6 +31,7 @@
 #include <BOPDS_ShapeInfo.hxx>
 #include <BOPDS_VectorOfInterfVV.hxx>
 #include <BOPTools_AlgoTools.hxx>
+#include <BRep_Builder.hxx>
 #include <BRep_TVertex.hxx>
 #include <BRep_Tool.hxx>
 #include <gp_Pnt.hxx>
@@ -39,6 +41,7 @@
 #include <TopoDS.hxx>
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Vertex.hxx>
+#include <TopoDS_Compound.hxx>
 
 //=======================================================================
 // function: PerformVV
@@ -49,8 +52,6 @@ void BOPAlgo_PaveFiller::PerformVV()
   Standard_Integer n1, n2, iFlag, aSize;
   Handle(NCollection_BaseAllocator) aAllocator;
   //
-  myErrorStatus=0;
-  //
   myIterator->Initialize(TopAbs_VERTEX, TopAbs_VERTEX);
   aSize=myIterator->ExpectedLength();
   if (!aSize) {
@@ -163,12 +164,27 @@ Standard_Integer BOPAlgo_PaveFiller::MakeSDVertices
     Standard_Integer n1 = aItLI.Value();
     myDS->AddShapeSD(n1, nV);
     //
-    if (theAddInterfs) {
-      BOPCol_ListIteratorOfListOfInteger aItLI2 = aItLI;
-      aItLI2.Next();
-      for (; aItLI2.More(); aItLI2.Next()) {
-        Standard_Integer n2 = aItLI2.Value();
+    Standard_Integer iR1 = myDS->Rank(n1);
+    const TopoDS_Shape& aV1 = myDS->Shape(n1);
+    //
+    BOPCol_ListIteratorOfListOfInteger aItLI2 = aItLI;
+    aItLI2.Next();
+    for (; aItLI2.More(); aItLI2.Next()) {
+      Standard_Integer n2 = aItLI2.Value();
+      //
+      if (iR1 >= 0 && iR1 == myDS->Rank(n2)) {
+        // add warning status
+        const TopoDS_Shape& aV2 = myDS->Shape(n2);
         //
+        TopoDS_Compound aWC;
+        BRep_Builder().MakeCompound(aWC);
+        BRep_Builder().Add(aWC, aV1);
+        BRep_Builder().Add(aWC, aV2);
+        //
+        AddWarning (new BOPAlgo_AlertSelfInterferingShape (aWC));
+      }
+      //
+      if (theAddInterfs) {
         myDS->AddInterf(n1, n2);
         BOPDS_InterfVV& aVV = aVVs.Append1();
         //
diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_11.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_11.cxx
new file mode 100644 (file)
index 0000000..c8341c5
--- /dev/null
@@ -0,0 +1,184 @@
+// Created by: Eugeny MALTCHIKOV
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+
+#include <BOPAlgo_PaveFiller.hxx>
+#include <BOPAlgo_Alerts.hxx>
+
+#include <BOPDS_DS.hxx>
+#include <BOPDS_MapOfCommonBlock.hxx>
+
+#include <BRep_Builder.hxx>
+
+#include <TopoDS_Compound.hxx>
+
+//=======================================================================
+//function : CheckSelfInterference
+//purpose  : 
+//=======================================================================
+void BOPAlgo_PaveFiller::CheckSelfInterference()
+{
+  if (myArguments.Extent() == 1) {
+    // Self-interference mode
+    return;
+  }
+  //
+  BRep_Builder aBB;
+  //
+  Standard_Integer i, aNbR = myDS->NbRanges();
+  for (i = 0; i < aNbR; ++i) {
+    const BOPDS_IndexRange& aR = myDS->Range(i);
+    //
+    // Map of connections of interfering shapes
+    NCollection_IndexedDataMap<TopoDS_Shape,
+                               BOPCol_IndexedMapOfShape,
+                               TopTools_ShapeMapHasher> aMCSI;
+    BOPDS_MapOfCommonBlock aMCBFence;
+    //
+    Standard_Integer j = aR.First(), aRLast = aR.Last();
+    for (; j <= aRLast; ++j) {
+      const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(j);
+      if (!aSI.HasReference()) {
+        // No pave blocks and no face info
+        continue;
+      }
+      //
+      const TopoDS_Shape& aS = aSI.Shape();
+      //
+      if (aSI.ShapeType() == TopAbs_EDGE) {
+        if (aSI.HasFlag()) {
+          continue;
+        }
+        //
+        // Analyze the shared vertices and common blocks
+        //
+        BOPCol_MapOfInteger aMSubS;
+        BOPCol_ListIteratorOfListOfInteger aItLI(aSI.SubShapes());
+        for (; aItLI.More(); aItLI.Next()) {
+          Standard_Integer nV = aItLI.Value();
+          myDS->HasShapeSD(nV, nV);
+          aMSubS.Add(nV);
+        }
+        //
+        const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks(j);
+        Standard_Boolean bAnalyzeV = aLPB.Extent() > 1;
+        //
+        BOPDS_ListIteratorOfListOfPaveBlock aIt(aLPB);
+        for (; aIt.More(); aIt.Next()) {
+          const Handle(BOPDS_PaveBlock)& aPB = aIt.Value();
+          //
+          // Check the vertices
+          if (bAnalyzeV) {
+            Standard_Integer nV[2];
+            aPB->Indices(nV[0], nV[1]);
+            for (Standard_Integer k = 0; k < 2; ++k) {
+              if (!aR.Contains(nV[k]) && !aMSubS.Contains(nV[k])) {
+                // Add connection
+                const TopoDS_Shape& aV = myDS->Shape(nV[k]);
+                BOPCol_IndexedMapOfShape* pMSOr = aMCSI.ChangeSeek(aV);
+                if (!pMSOr) {
+                  pMSOr = &aMCSI(aMCSI.Add(aV, BOPCol_IndexedMapOfShape()));
+                }
+                pMSOr->Add(aS);
+              }
+            }
+          }
+          //
+          // Check common blocks
+          if (myDS->IsCommonBlock(aPB)) {
+            const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(aPB);
+            if (aMCBFence.Add(aCB)) {
+              const BOPDS_ListOfPaveBlock& aLPBCB = aCB->PaveBlocks();
+              //
+              BOPCol_ListOfInteger aLE;
+              BOPDS_ListIteratorOfListOfPaveBlock aItCB(aLPBCB);
+              for (; aItCB.More(); aItCB.Next()) {
+                const Handle(BOPDS_PaveBlock)& aPBCB = aItCB.Value();
+                Standard_Integer nEOr = aPBCB->OriginalEdge();
+                if (aR.Contains(nEOr)) {
+                  aLE.Append(nEOr);
+                }
+              }
+              //
+              if (aLE.Extent() > 1) {
+                // Add warning
+                TopoDS_Compound aWC;
+                aBB.MakeCompound(aWC);
+                //
+                BOPCol_ListIteratorOfListOfInteger aItLE(aLE);
+                for (; aItLE.More(); aItLE.Next()) {
+                  const TopoDS_Shape& aE1 = myDS->Shape(aItLE.Value());
+                  aBB.Add(aWC, aE1);
+                }
+                //
+                AddWarning (new BOPAlgo_AlertSelfInterferingShape (aWC));
+              }
+            }
+          }
+        }
+      }
+      else if(aSI.ShapeType() == TopAbs_FACE) {
+        // Analyze IN and Section vertices and edges of the faces
+        const BOPDS_FaceInfo& aFI = myDS->FaceInfo(j);
+        //
+        for (Standard_Integer k = 0; k < 2; ++k) {
+          const BOPCol_MapOfInteger& aMVF = !k ? aFI.VerticesIn() : aFI.VerticesSc();
+          BOPCol_MapIteratorOfMapOfInteger aItM(aMVF);
+          for (; aItM.More(); aItM.Next()) {
+            const TopoDS_Shape& aV = myDS->Shape(aItM.Value());
+            // add connection
+            BOPCol_IndexedMapOfShape* pMSOr = aMCSI.ChangeSeek(aV);
+            if (!pMSOr) {
+              pMSOr = &aMCSI(aMCSI.Add(aV, BOPCol_IndexedMapOfShape()));
+            }
+            pMSOr->Add(aS);
+          }
+        }
+        //
+        for (Standard_Integer k = 0; k < 2; ++k) {
+          const BOPDS_IndexedMapOfPaveBlock& aMPBF = !k ? aFI.PaveBlocksIn() : aFI.PaveBlocksSc();
+          Standard_Integer iPB, aNbPB = aMPBF.Extent();
+          for (iPB = 1; iPB <= aNbPB; ++iPB) {
+            const Handle(BOPDS_PaveBlock)& aPB = aMPBF(iPB);
+            const TopoDS_Shape& aE = myDS->Shape(aPB->Edge());
+            // add connection
+            BOPCol_IndexedMapOfShape* pMSOr = aMCSI.ChangeSeek(aE);
+            if (!pMSOr) {
+              pMSOr = &aMCSI(aMCSI.Add(aE, BOPCol_IndexedMapOfShape()));
+            }
+            pMSOr->Add(aS);
+          }
+        }
+      }
+    }
+    //
+    // Analyze connections
+    Standard_Integer aNbC = aMCSI.Extent();
+    for (j = 1; j <= aNbC; ++j) {
+      const BOPCol_IndexedMapOfShape& aMCS = aMCSI(j);
+      if (aMCS.Extent() > 1) {
+        // Add self-interference warning
+        TopoDS_Compound aWC;
+        aBB.MakeCompound(aWC);
+        //
+        Standard_Integer iS, aNbS = aMCS.Extent();
+        for (iS = 1; iS <= aNbS; ++iS) {
+          const TopoDS_Shape& aSx = aMCS(iS);
+          aBB.Add(aWC, aSx);
+        }
+        AddWarning (new BOPAlgo_AlertSelfInterferingShape (aWC));
+      }
+    }
+  }
+}
index 5dbe506..c496668 100644 (file)
@@ -145,8 +145,6 @@ typedef BOPCol_ContextCnt
 //=======================================================================
 void BOPAlgo_PaveFiller::PerformVE()
 {
-  myErrorStatus=0;
-  //
   FillShrunkData(TopAbs_VERTEX, TopAbs_EDGE);
   //
   myIterator->Initialize(TopAbs_VERTEX, TopAbs_EDGE);
index 407bc31..3a8892e 100644 (file)
@@ -19,6 +19,7 @@
 #include <Bnd_Box.hxx>
 #include <BOPAlgo_PaveFiller.hxx>
 #include <BOPAlgo_Tools.hxx>
+#include <BOPAlgo_Alerts.hxx>
 #include <BOPCol_NCVector.hxx>
 #include <BOPCol_Parallel.hxx>
 #include <BOPDS_CommonBlock.hxx>
@@ -33,6 +34,7 @@
 #include <BOPTools_AlgoTools.hxx>
 #include <BndLib_Add3dCurve.hxx>
 #include <BRep_Tool.hxx>
+#include <BRep_Builder.hxx>
 #include <BRepAdaptor_Curve.hxx>
 #include <gp_Pnt.hxx>
 #include <IntTools_CommonPrt.hxx>
@@ -118,14 +120,10 @@ typedef BOPCol_Cnt
 //=======================================================================
 void BOPAlgo_PaveFiller::PerformEE()
 {
-  Standard_Integer iSize;
-  //
-  myErrorStatus=0;
-  //
   FillShrunkData(TopAbs_EDGE, TopAbs_EDGE);
   //
   myIterator->Initialize(TopAbs_EDGE, TopAbs_EDGE);
-  iSize=myIterator->ExpectedLength();
+  Standard_Integer iSize = myIterator->ExpectedLength();
   if (!iSize) {
     return; 
   }
@@ -582,40 +580,72 @@ void BOPAlgo_PaveFiller::TreatNewVertices
 //=======================================================================
 void BOPAlgo_PaveFiller::FillShrunkData(Handle(BOPDS_PaveBlock)& thePB)
 {
-  Standard_Integer nE, nV1, nV2;
-  Standard_Real aT1, aT2, aTS1, aTS2;
-  IntTools_ShrunkRange aSR;
-  //
-  myErrorStatus=0;
-  myWarningStatus = 0;
-  //
-  const BOPDS_Pave& aPave1=thePB->Pave1();
-  nV1=aPave1.Index();
-  aT1=aPave1.Parameter();
+  // Vertices
+  Standard_Integer nV1, nV2;
+  thePB->Indices(nV1, nV2);
   const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1))); 
-  //
-  const BOPDS_Pave& aPave2=thePB->Pave2();
-  nV2=aPave2.Index();
-  aT2=aPave2.Parameter();
   const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2))); 
-  //
-  nE=thePB->OriginalEdge();
+  // Original edge
+  Standard_Integer nE = thePB->OriginalEdge();
   const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
+  // Range
+  Standard_Real aT1, aT2;
+  thePB->Range(aT1, aT2);
   //
+  IntTools_ShrunkRange aSR;
   aSR.SetContext(myContext);
   aSR.SetData(aE, aT1, aT2, aV1, aV2);
-  //
   aSR.Perform();
-  if (!aSR.IsDone()) {
-    myWarningStatus = 1;
-    return;
+  // Analyze the results of computations
+  AnalyzeShrunkData(thePB, aSR);
+}
+//=======================================================================
+// function: AnalyzeShrunkData
+// purpose: 
+//=======================================================================
+void BOPAlgo_PaveFiller::AnalyzeShrunkData(const Handle(BOPDS_PaveBlock)& thePB,
+                                           const IntTools_ShrunkRange& theSR)
+{
+  // in case of error treat the warning status
+  Standard_Boolean bWholeEdge = Standard_False;
+  TopoDS_Shape aWarnShape;
+  //
+  if (!theSR.IsDone() || !theSR.IsSplittable()) {
+    Standard_Real aEFirst, aELast, aPBFirst, aPBLast;
+    BRep_Tool::Range(theSR.Edge(), aEFirst, aELast);
+    thePB->Range(aPBFirst, aPBLast);
+    bWholeEdge = !(aPBFirst > aEFirst || aPBLast < aELast);
+    if (bWholeEdge) {
+      aWarnShape = theSR.Edge();
+    }
+    else {
+      const TopoDS_Shape& aV1 = myDS->Shape(thePB->Pave1().Index());
+      const TopoDS_Shape& aV2 = myDS->Shape(thePB->Pave2().Index());
+      BRep_Builder().MakeCompound(TopoDS::Compound(aWarnShape));
+      BRep_Builder().Add(aWarnShape, theSR.Edge());
+      BRep_Builder().Add(aWarnShape, aV1);
+      BRep_Builder().Add(aWarnShape, aV2);
+    }
+    //
+    if (!theSR.IsDone()) {
+      if (bWholeEdge)
+        AddWarning (new BOPAlgo_AlertTooSmallEdge (aWarnShape));
+      else
+        AddWarning (new BOPAlgo_AlertBadPositioning (aWarnShape));
+      return;
+    }
+    //
+    if (bWholeEdge)
+      AddWarning (new BOPAlgo_AlertNotSplittableEdge (aWarnShape));
+    else
+      AddWarning (new BOPAlgo_AlertBadPositioning (aWarnShape));
   }
   //
-  aSR.ShrunkRange(aTS1, aTS2);
-  const Bnd_Box& aBox=aSR.BndBox();
-  Standard_Boolean bIsSplittable = aSR.IsSplittable();
-  //
-  thePB->SetShrunkData(aTS1, aTS2, aBox, bIsSplittable);
+  Standard_Real aTS1, aTS2;
+  theSR.ShrunkRange(aTS1, aTS2);
+  Bnd_Box aBox = theSR.BndBox();
+  aBox.SetGap(aBox.GetGap() + myFuzzyValue / 2.);
+  thePB->SetShrunkData(aTS1, aTS2, aBox, theSR.IsSplittable());
 }
 //=======================================================================
 //function : ForceInterfVE
@@ -637,7 +667,7 @@ void BOPAlgo_PaveFiller::ForceInterfVE(const Standard_Integer nV,
   //
   if (myDS->HasInterf(nV, nE)) {
     return;
-  }   
+  }
   //
   if (myDS->HasInterfShapeSubShapes(nV, nE)) {
     return;
@@ -682,6 +712,17 @@ void BOPAlgo_PaveFiller::ForceInterfVE(const Standard_Integer nV,
     aPB->AppendExtPave(aPave);
     //
     theMEdges.Add(nE);
+    //
+    // check for self-interference
+    Standard_Integer iRV = myDS->Rank(nV);
+    if (iRV >= 0 && iRV == myDS->Rank(nE)) {
+      // add warning status
+      TopoDS_Compound aWC;
+      BRep_Builder().MakeCompound(aWC);
+      BRep_Builder().Add(aWC, aV);
+      BRep_Builder().Add(aWC, aE);
+      AddWarning (new BOPAlgo_AlertSelfInterferingShape (aWC));
+    }
   }
 }
 
index ce679ce..291edb2 100644 (file)
@@ -142,8 +142,6 @@ typedef BOPCol_ContextCnt
 //=======================================================================
 void BOPAlgo_PaveFiller::PerformVF()
 {
-  myErrorStatus=0;
-  //
   myIterator->Initialize(TopAbs_VERTEX, TopAbs_FACE);
   Standard_Integer iSize = myIterator->ExpectedLength();
   //
@@ -260,9 +258,6 @@ void BOPAlgo_PaveFiller::TreatVerticesEE()
   BOPCol_MapOfInteger aMI(100, aAllocator);
   BOPDS_MapOfPaveBlock aMPBF(100, aAllocator);
   //
-  myErrorStatus=0;
-  //
-  
   aNbS=myDS->NbSourceShapes();
   //
   BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
index e218303..84fc6d1 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <Bnd_Box.hxx>
 #include <BOPAlgo_PaveFiller.hxx>
+#include <BOPAlgo_Alerts.hxx>
 #include <BOPAlgo_Tools.hxx>
 #include <BOPCol_MapOfInteger.hxx>
 #include <BOPCol_NCVector.hxx>
@@ -132,8 +133,6 @@ typedef BOPCol_ContextCnt
 //=======================================================================
 void BOPAlgo_PaveFiller::PerformEF()
 {
-  myErrorStatus=0;
-  //
   FillShrunkData(TopAbs_EDGE, TopAbs_FACE);
   //
   myIterator->Initialize(TopAbs_EDGE, TopAbs_FACE);
@@ -564,6 +563,18 @@ Standard_Boolean BOPAlgo_PaveFiller::ForceInterfVF
     BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
     BOPCol_MapOfInteger& aMVIn=aFI.ChangeVerticesIn();
     aMVIn.Add(nVx);
+    //
+    // check for self-interference
+    Standard_Integer iRV = myDS->Rank(nV);
+    if (iRV >= 0 && iRV == myDS->Rank(nF)) {
+      // add warning status
+      TopoDS_Compound aWC;
+      BRep_Builder().MakeCompound(aWC);
+      BRep_Builder().Add(aWC, aV);
+      BRep_Builder().Add(aWC, aF);
+      AddWarning (new BOPAlgo_AlertSelfInterferingShape (aWC));
+    }
+
   }
   return bRet;
 }
index 8355984..038f0c5 100644 (file)
@@ -19,6 +19,7 @@
 #include <BOPAlgo_PaveFiller.hxx>
 #include <BOPAlgo_SectionAttribute.hxx>
 #include <BOPAlgo_Tools.hxx>
+#include <BOPAlgo_Alerts.hxx>
 #include <BOPCol_DataMapOfShapeInteger.hxx>
 #include <BOPCol_ListOfInteger.hxx>
 #include <BOPCol_ListOfShape.hxx>
@@ -172,8 +173,6 @@ typedef BOPCol_Cnt
 //=======================================================================
 void BOPAlgo_PaveFiller::PerformFF()
 {
-  myErrorStatus = 0;
-  //
   myIterator->Initialize(TopAbs_FACE, TopAbs_FACE);
   Standard_Integer iSize = myIterator->ExpectedLength();
   if (!iSize) {
@@ -339,12 +338,8 @@ void BOPAlgo_PaveFiller::MakeBlocks()
     return;
   }
   //
-  Standard_Integer aNbFF;
-  //
-  myErrorStatus=0;
-  //
   BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
-  aNbFF=aFFs.Extent();
+  Standard_Integer aNbFF = aFFs.Extent();
   if (!aNbFF) {
     return;
   }
@@ -644,8 +639,8 @@ void BOPAlgo_PaveFiller::MakeBlocks()
   // 
   // post treatment
   MakeSDVerticesFF(aDMVLV, aDMNewSD);
-  myErrorStatus=PostTreatFF(aMSCPB, aDMExEdges, aDMNewSD, aMicroEdges, aAllocator);
-  if (myErrorStatus) {
+  PostTreatFF(aMSCPB, aDMExEdges, aDMNewSD, aMicroEdges, aAllocator);
+  if (HasErrors()) {
     return;
   }
   // reduce tolerances of section edges where it is appropriate
@@ -697,23 +692,20 @@ void BOPAlgo_PaveFiller::MakeSDVerticesFF
 //function : PostTreatFF
 //purpose  : 
 //=======================================================================
-Standard_Integer BOPAlgo_PaveFiller::PostTreatFF
+void BOPAlgo_PaveFiller::PostTreatFF
     (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB,
      BOPDS_DataMapOfPaveBlockListOfPaveBlock& aDMExEdges,
      BOPCol_DataMapOfIntegerInteger& aDMNewSD,
      const BOPCol_IndexedMapOfShape& theMicroEdges,
      const Handle(NCollection_BaseAllocator)& theAllocator)
 {
-  Standard_Integer iRet, aNbS;
-  //
-  iRet=0;
-  aNbS=theMSCPB.Extent();
+  Standard_Integer aNbS = theMSCPB.Extent();
   if (!aNbS) {
-    return iRet;
+    return;
   }
   //
   Standard_Boolean bHasPaveBlocks, bOld;
-  Standard_Integer iErr, nSx, nVSD, iX, iP, iC, j, nV, iV = 0, iE, k;
+  Standard_Integer nSx, nVSD, iX, iP, iC, j, nV, iV = 0, iE, k;
   Standard_Integer aNbLPBx;
   TopAbs_ShapeEnum aType;
   TopoDS_Shape aV, aE;
@@ -765,7 +757,7 @@ Standard_Integer BOPAlgo_PaveFiller::PostTreatFF
         aPB1->SetEdge(iE);
       }
     }
-    return iRet;
+    return;
   }
   //
   // 1 prepare arguments
@@ -838,9 +830,9 @@ Standard_Integer BOPAlgo_PaveFiller::PostTreatFF
   aPF.SetRunParallel(myRunParallel);
   aPF.SetArguments(aLS);
   aPF.Perform();
-  iErr=aPF.ErrorStatus();
-  if (iErr) {
-    return iRet;
+  if (aPF.HasErrors()) {
+    AddError (new BOPAlgo_AlertPostTreatFF);
+    return;
   }
   aPDS=aPF.PDS();
   //
@@ -1061,7 +1053,7 @@ Standard_Integer BOPAlgo_PaveFiller::PostTreatFF
       myDS->AddShapeSD(itDM.Key(), *pSD);
     }
   }
-  return iRet;
+  return;
 }
 
 //=======================================================================
@@ -2753,8 +2745,6 @@ void BOPAlgo_PaveFiller::UpdateBlocksWithSharedVertices()
     return;
   }
   //
-  myErrorStatus=0;
-  //
   Standard_Integer aNbFF;
   //
   BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
index a712323..bf02175 100644 (file)
@@ -356,12 +356,8 @@ typedef BOPCol_Cnt
 //=======================================================================
 void BOPAlgo_PaveFiller::MakeSplitEdges()
 {
-  Standard_Integer aNbPBP;
-  //
-  myErrorStatus=0;
-  //
   BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
-  aNbPBP=aPBP.Extent();
+  Standard_Integer aNbPBP = aPBP.Extent();
   if(!aNbPBP) {
     return;
   }
@@ -541,8 +537,6 @@ void BOPAlgo_PaveFiller::MakePCurves()
   TopoDS_Face aF1F, aF2F;
   BOPAlgo_VectorOfMPC aVMPC;
   //
-  myErrorStatus=0;
-  //
   // 1. Process Common Blocks 
   const BOPDS_VectorOfFaceInfo& aFIP=myDS->FaceInfoPool();
   //
@@ -746,8 +740,6 @@ void BOPAlgo_PaveFiller::Prepare()
   TopExp_Explorer aExp;
   BOPCol_IndexedMapOfShape aMF;
   //
-  myErrorStatus=0;
-  //
   aNb=3;
   for(i=0; i<aNb; ++i) {
     myIterator->Initialize(aType[i], aType[2]);
index c1208e5..495c640 100644 (file)
@@ -63,8 +63,6 @@ void BOPAlgo_PaveFiller::ProcessDE()
   Handle(BOPDS_PaveBlock) aPBD;
   BOPCol_ListIteratorOfListOfInteger aItLI;
   //
-  myErrorStatus=0;
-  //
   // 1. Find degnerated edges
   //-----------------------------------------------------scope f
   //
index f5ca43a..84fca4e 100644 (file)
@@ -84,19 +84,14 @@ typedef BOPCol_ContextCnt
 void BOPAlgo_PaveFiller::FillShrunkData(const TopAbs_ShapeEnum aType1,
                                         const TopAbs_ShapeEnum aType2)
 {
-  Standard_Integer iSize;
-  
-  //
-  myErrorStatus=0;
-  //
   myIterator->Initialize(aType1, aType2);
-  iSize=myIterator->ExpectedLength();
+  Standard_Integer iSize = myIterator->ExpectedLength();
   if (!iSize) {
     return; 
   }
   //
   Standard_Integer i, nS[2], nE, nV1, nV2, aNbVSD, k;
-  Standard_Real aT1, aT2, aTS1, aTS2;
+  Standard_Real aT1, aT2;
   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
   BOPCol_MapOfInteger aMI; 
   BOPAlgo_VectorOfShrunkRange aVSD;
@@ -149,19 +144,8 @@ void BOPAlgo_PaveFiller::FillShrunkData(const TopAbs_ShapeEnum aType1,
   BOPAlgo_ShrunkRangeCnt::Perform(myRunParallel, aVSD, myContext);
   //=============================================================
   //
-  Standard_Real aFuzz = myFuzzyValue / 2.;
   for (k=0; k < aNbVSD; ++k) {
-    BOPAlgo_ShrunkRange& aSD=aVSD(k);
-    if (!aSD.IsDone()) {
-      continue;
-    }
-    //
-    Handle(BOPDS_PaveBlock)& aPB=aSD.PaveBlock();
-    aSD.ShrunkRange(aTS1, aTS2);
-    Bnd_Box aBox=aSD.BndBox();
-    aBox.SetGap(aBox.GetGap() + aFuzz);
-    Standard_Boolean bIsSplittable = aSD.IsSplittable();
-    //
-    aPB->SetShrunkData(aTS1, aTS2, aBox, bIsSplittable);
+    BOPAlgo_ShrunkRange& aSD = aVSD(k);
+    AnalyzeShrunkData(aSD.PaveBlock(), aSD);
   }
 }
index d7985e4..dd5eba5 100644 (file)
@@ -16,6 +16,7 @@
 #include <BOPAlgo_BuilderSolid.hxx>
 #include <BOPAlgo_PaveFiller.hxx>
 #include <BOPAlgo_Section.hxx>
+#include <BOPAlgo_Alerts.hxx>
 #include <BOPCol_DataMapOfShapeShape.hxx>
 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
 #include <BOPCol_IndexedMapOfShape.hxx>
@@ -79,23 +80,13 @@ void BOPAlgo_Section::CheckData()
 {
   Standard_Integer aNbArgs;
   //
-  myErrorStatus=0;
-  //
   aNbArgs=myArguments.Extent();
   if (!aNbArgs) {
-    myErrorStatus=100; // invalid number of Arguments
+    AddError (new BOPAlgo_AlertTooFewArguments);
     return;
   }
   //
-  if (!myPaveFiller) {
-    myErrorStatus=101; 
-    return;
-  }
-  //
-  myErrorStatus=myPaveFiller->ErrorStatus();
-  if (myErrorStatus) {
-    return;
-  }
+  CheckFiller();
 }
 //=======================================================================
 //function : PerformInternal1
@@ -104,59 +95,53 @@ void BOPAlgo_Section::CheckData()
 void BOPAlgo_Section::PerformInternal1
   (const BOPAlgo_PaveFiller& theFiller)
 {
-  myErrorStatus=0;
-  myWarningStatus=0;
-  //
   myPaveFiller=(BOPAlgo_PaveFiller*)&theFiller;
   myDS=myPaveFiller->PDS();
   myContext=myPaveFiller->Context();
   //
   // 1. CheckData
   CheckData();
-  if (myErrorStatus && !myWarningStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   // 2. Prepare
   Prepare();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
-  if(myWarningStatus == 2) {
-    return;
-  }
   // 3. Fill Images
   // 3.1 Vertices
   FillImagesVertices();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   BuildResult(TopAbs_VERTEX);
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   // 3.2 Edges
   FillImagesEdges();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
   BuildResult(TopAbs_EDGE);
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   // 4. Section
   BuildSection();
   //
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   // 5.History
   PrepareHistory();
   //
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   } 
   // 6. Post-treatment
@@ -181,7 +166,7 @@ void BOPAlgo_Section::BuildSection()
   BOPCol_MapIteratorOfMapOfInteger aItMI; 
   BOPDS_ListIteratorOfListOfPaveBlock aItPB;
   //
-  myErrorStatus=0;
+  GetReport()->Clear();
   //
   BOPTools_AlgoTools::MakeContainer(TopAbs_COMPOUND, aRC1);
   //
@@ -413,4 +398,3 @@ const TopTools_ListOfShape& BOPAlgo_Section::Generated
   //
   return myHistShapes;
 }
-
index ca52f93..d0c1281 100644 (file)
@@ -40,10 +40,9 @@ public:
 
   DEFINE_STANDARD_ALLOC
 
-  
   //! Empty constructor
   Standard_EXPORT BOPAlgo_Section();
-Standard_EXPORT virtual ~BOPAlgo_Section();
+  Standard_EXPORT virtual ~BOPAlgo_Section();
   
   //! Empty constructor
   //!
@@ -57,32 +56,16 @@ Standard_EXPORT virtual ~BOPAlgo_Section();
   Standard_EXPORT virtual const TopTools_ListOfShape& Generated (const TopoDS_Shape& theS) Standard_OVERRIDE;
 
 
-
-
 protected:
 
-  
   Standard_EXPORT virtual void CheckData() Standard_OVERRIDE;
   
   //! Performs calculations using prepared Filler
   //! object <thePF>
   Standard_EXPORT virtual void PerformInternal1 (const BOPAlgo_PaveFiller& thePF) Standard_OVERRIDE;
 
-
-
-
 private:
 
-
-
-
-
 };
 
-
-
-
-
-
-
 #endif // _BOPAlgo_Section_HeaderFile
index bdcbb65..0770782 100644 (file)
@@ -150,10 +150,10 @@ const BOPCol_ListOfShape& BOPAlgo_ShellSplitter::Shells()const
 //=======================================================================
 void BOPAlgo_ShellSplitter::Perform()
 {
-  myErrorStatus=0;
+  GetReport()->Clear();
   //
   MakeConnexityBlocks();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
@@ -178,8 +178,6 @@ void BOPAlgo_ShellSplitter::MakeConnexityBlocks()
   BOPCol_MapOfShape aMES(100, myAllocator);
   BOPCol_ListIteratorOfListOfShape aIt;
   //
-  myErrorStatus=0;
-  //
   myLCB.Clear();
   //
   const BOPCol_ListOfShape& aLSE=myStartShapes;
@@ -696,7 +694,6 @@ void BOPAlgo_ShellSplitter::MakeShells()
   BOPCol_ListIteratorOfListOfShape aIt;
   BOPAlgo_VectorOfCBK aVCBK;
   //
-  myErrorStatus=0;
   myShells.Clear();
   //
   aItCB.Initialize(myLCB);
index 84e10fc..980fa56 100644 (file)
@@ -59,13 +59,10 @@ Standard_EXPORT virtual ~BOPAlgo_ShellSplitter();
   Standard_EXPORT static void SplitBlock (BOPTools_ConnexityBlock& theCB);
 
 
-
-
 protected:
 
-  
   Standard_EXPORT void MakeConnexityBlocks();
-  
+
   Standard_EXPORT void MakeShells();
 
 
@@ -73,19 +70,8 @@ protected:
   BOPCol_ListOfShape myShells;
   BOPTools_ListOfConnexityBlock myLCB;
 
-
 private:
 
-
-
-
-
 };
 
-
-
-
-
-
-
 #endif // _BOPAlgo_ShellSplitter_HeaderFile
index 74a0ecb..0d073b0 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <BOPAlgo_Splitter.hxx>
 #include <BOPAlgo_PaveFiller.hxx>
+#include <BOPAlgo_Alerts.hxx>
 
 //=======================================================================
 //function : 
@@ -85,24 +86,14 @@ void BOPAlgo_Splitter::SetTools(const BOPCol_ListOfShape& theShapes)
 //=======================================================================
 void BOPAlgo_Splitter::CheckData()
 {
-  myErrorStatus = 0;
   if (myArguments.IsEmpty() ||
       (myArguments.Extent() + myTools.Extent()) < 2) {
     // too few arguments to process
-    myErrorStatus = 100;
+    AddError (new BOPAlgo_AlertTooFewArguments);
     return;
   }
   //
-  // Check the PaveFiller
-  if (!myPaveFiller) {
-    myErrorStatus = 101;
-    return;
-  }
-  //
-  if (myPaveFiller->ErrorStatus()) {
-    // PaveFiller has failed
-    myErrorStatus = 102;
-  }
+  CheckFiller();
 }
 
 //=======================================================================
@@ -111,7 +102,7 @@ void BOPAlgo_Splitter::CheckData()
 //=======================================================================
 void BOPAlgo_Splitter::Perform()
 {
-  myErrorStatus = 0;
+  GetReport()->Clear();
   //
   if (myEntryPoint == 1) {
     if (myPaveFiller) {
index c11a85d..2fd2b9f 100644 (file)
@@ -77,6 +77,7 @@ public:
   //! Performs the operation
   Standard_EXPORT virtual void Perform() Standard_OVERRIDE;
 
+
 protected:
 
   //! Checks the input data
index 9647254..d91da14 100644 (file)
@@ -346,7 +346,7 @@ Standard_Integer BOPAlgo_Tools::EdgesToWires(const TopoDS_Shape& theEdges,
     BOPAlgo_Builder aGF;
     aGF.SetArguments(aLE);
     aGF.Perform();
-    if (aGF.ErrorStatus()) {
+    if (aGF.HasErrors()) {
       // unable to share the edges
       iErr = 2;
       return iErr;
@@ -666,7 +666,7 @@ Standard_Boolean BOPAlgo_Tools::WiresToFaces(const TopoDS_Shape& theWires,
       aBF.SetShapes(aLE);
       aBF.SetFace(aFF);
       aBF.Perform();
-      if (aBF.ErrorStatus()) {
+      if (aBF.HasErrors()) {
         continue;
       }
       //
index e6de3f2..2875930 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <BOPAlgo_WireEdgeSet.hxx>
 #include <BOPAlgo_WireSplitter.hxx>
+#include <BOPAlgo_Alerts.hxx>
 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
 #include <BOPCol_IndexedMapOfShape.hxx>
 #include <BOPCol_ListOfShape.hxx>
@@ -100,9 +101,8 @@ const Handle(IntTools_Context)& BOPAlgo_WireSplitter::Context()
 //=======================================================================
 void BOPAlgo_WireSplitter::CheckData()
 {
-  myErrorStatus=0;
   if (!myWES) {
-    myErrorStatus=10;
+    AddError (new BOPAlgo_AlertNullInputShapes);
     return;
   }
 }
@@ -112,10 +112,10 @@ void BOPAlgo_WireSplitter::CheckData()
 //=======================================================================
 void BOPAlgo_WireSplitter::Perform()
 {
-  myErrorStatus=0;
+  GetReport()->Clear();
   //
   CheckData();
-  if (myErrorStatus) {
+  if (HasErrors()) {
     return;
   }
   //
index d0589a6..6b2f6e0 100644 (file)
@@ -31,6 +31,11 @@ class TopoDS_Wire;
 class TopoDS_Face;
 
 
+//! The class is to build loops from the given set of edges.
+//!
+//! It returns the following Error statuses
+//! - *BOPAlgo_AlertNullInputShapes* - in case there no input edges to build the loops.
+//!
 class BOPAlgo_WireSplitter  : public BOPAlgo_Algo
 {
 public:
@@ -73,8 +78,6 @@ protected:
   BOPTools_ListOfConnexityBlock myLCB;
   Handle(IntTools_Context) myContext;
 
-private:
-
 };
 
 #include <BOPAlgo_WireSplitter.lxx>
index e32194e..6317810 100644 (file)
@@ -30,6 +30,8 @@ BOPAlgo_MakerVolume.cxx
 BOPAlgo_MakerVolume.hxx
 BOPAlgo_MakerVolume.lxx
 BOPAlgo_Operation.hxx
+BOPAlgo_Options.cxx
+BOPAlgo_Options.hxx
 BOPAlgo_PArgumentAnalyzer.hxx
 BOPAlgo_PaveFiller.cxx
 BOPAlgo_PaveFiller.hxx
@@ -43,6 +45,7 @@ BOPAlgo_PaveFiller_7.cxx
 BOPAlgo_PaveFiller_8.cxx
 BOPAlgo_PaveFiller_9.cxx
 BOPAlgo_PaveFiller_10.cxx
+BOPAlgo_PaveFiller_11.cxx
 BOPAlgo_PBOP.hxx
 BOPAlgo_PBuilder.hxx
 BOPAlgo_PPaveFiller.hxx
@@ -67,4 +70,7 @@ BOPAlgo_CellsBuilder.cxx
 BOPAlgo_CellsBuilder.hxx
 BOPAlgo_GlueEnum.hxx
 BOPAlgo_Splitter.hxx
-BOPAlgo_Splitter.cxx
\ No newline at end of file
+BOPAlgo_Splitter.cxx
+BOPAlgo_Alerts.hxx
+BOPAlgo.msg
+BOPAlgo_BOPAlgo_msg.pxx
index 661e8cf..edd9c37 100644 (file)
 #include <GeometryTest.hxx>
 #include <GeomliteTest.hxx>
 #include <HLRTest.hxx>
+#include <NCollection_Map.hxx>
 #include <MeshTest.hxx>
+#include <Message.hxx>
+#include <Message_Msg.hxx>
+#include <Message_Messenger.hxx>
 #include <SWDRAW.hxx>
+#include <TopoDS_AlertWithShape.hxx>
+
+#include <BOPAlgo_Algo.hxx>
+#include <BOPTest_Objects.hxx>
 
 //=======================================================================
 //function : AllCommands
@@ -70,3 +78,57 @@ void  BOPTest::AllCommands(Draw_Interpretor& theCommands)
 }
 // Declare entry point PLUGINFACTORY
 DPLUGIN(BOPTest)
+
+//=======================================================================
+//function : ReportAlerts
+//purpose  : 
+//=======================================================================
+
+void BOPTest::ReportAlerts (const BOPAlgo_Algo& theAlgorithm)
+{
+  // first report warnings, then errors
+  Message_Gravity anAlertTypes[2] = { Message_Warning, Message_Fail };
+  for (int iGravity = 0; iGravity < 2; iGravity++)
+  {
+    // report shapes for the same type of alert together
+    NCollection_Map<Handle(Standard_Transient)> aPassedTypes;
+    const Message_ListOfAlert& aList = theAlgorithm.GetReport()->GetAlerts (anAlertTypes[iGravity]);
+    for (Message_ListOfAlert::Iterator aIt (aList); aIt.More(); aIt.Next())
+    {
+      // check that this type of warnings has not yet been processed
+      if (! aPassedTypes.Add (aIt.Value()->DynamicType()))
+        continue;
+
+      // get alert message
+      Message_Msg aMsg (aIt.Value()->GetMessageKey());
+      TCollection_ExtendedString aText = aMsg.Get();
+
+      // collect all shapes if any attached to this alert
+      if (BOPTest_Objects::DrawWarnShapes())
+      {
+        TCollection_AsciiString aShapeList;
+        Standard_Integer aNbShapes = 0;
+        for (Message_ListOfAlert::Iterator aIt2 (aIt); aIt2.More(); aIt2.Next())
+        {
+          Handle(TopoDS_AlertWithShape) aShapeAlert = Handle(TopoDS_AlertWithShape)::DownCast (aIt2.Value());
+
+          if (! aShapeAlert.IsNull() && ! aShapeAlert->GetShape().IsNull()) 
+          {
+            //
+            char aName[80];
+            Sprintf(aName, "%ss_%d_%d", (iGravity ? "e" : "w"), aPassedTypes.Extent(), ++aNbShapes);
+            DBRep::Set(aName, aShapeAlert->GetShape());
+            //
+            aShapeList += " ";
+            aShapeList += aName;
+          }
+        }
+        aText += (aNbShapes ? ": " : "(no shapes attached)");
+        aText += aShapeList;
+      }
+
+      // output message with list of shapes
+      Message::DefaultMessenger()->Send (aText, anAlertTypes[iGravity]);
+    }
+  }
+}
index df17232..774ffb0 100644 (file)
@@ -23,8 +23,7 @@
 #include <Draw_Interpretor.hxx>
 class BOPTest_Objects;
 class BOPTest_DrawableShape;
-
-
+class BOPAlgo_Algo;
 
 class BOPTest 
 {
@@ -60,27 +59,18 @@ public:
   Standard_EXPORT static void CellsCommands  (Draw_Interpretor& aDI);
   
   Standard_EXPORT static void UtilityCommands (Draw_Interpretor& aDI);
-  
-protected:
-
-
 
+  //! Prints errors and warnings if any and draws attached shapes 
+  //! if flag BOPTest_Objects::DrawWarnShapes() is set
+  Standard_EXPORT static void ReportAlerts (const BOPAlgo_Algo& theAlgorithm);
 
+protected:
 
 private:
 
-
-
-
 friend class BOPTest_Objects;
 friend class BOPTest_DrawableShape;
 
 };
 
-
-
-
-
-
-
 #endif // _BOPTest_HeaderFile
index 87bc4d3..d6737c6 100644 (file)
@@ -68,9 +68,8 @@ Standard_Integer bapibop(Draw_Interpretor& di,
     return 0;
   }
   //
-  char buf[128];
   Standard_Boolean bRunParallel, bNonDestructive;
-  Standard_Integer iErr, iOp;
+  Standard_Integer iOp;
   Standard_Real aFuzzyValue;
   BRepAlgoAPI_Common aCommon;
   BRepAlgoAPI_Fuse aFuse;
@@ -82,7 +81,7 @@ Standard_Integer bapibop(Draw_Interpretor& di,
   pBuilder=NULL;
   iOp=atoi(a[2]);
   if (iOp<0 || iOp>4) {
-    printf(" invalid operation type\n");
+    di << "invalid operation type\n";
     return 0;
   }
   aOp=(BOPAlgo_Operation)iOp;
@@ -136,10 +135,17 @@ Standard_Integer bapibop(Draw_Interpretor& di,
   pBuilder->SetGlue(aGlue);
   //
   pBuilder->Build(); 
-  iErr=pBuilder->ErrorStatus();
-  if (iErr) {
-    Sprintf(buf, " error: %d\n",  iErr);
-    di << buf;
+  //
+  if (pBuilder->HasWarnings()) {
+    Standard_SStream aSStream;
+    pBuilder->DumpWarnings(aSStream);
+    di << aSStream;
+  }
+  //
+  if (pBuilder->HasErrors()) {
+    Standard_SStream aSStream;
+    pBuilder->DumpErrors(aSStream);
+    di << aSStream;
     return 0;
   }
   //
@@ -165,7 +171,6 @@ Standard_Integer bapibuild(Draw_Interpretor& di,
     return 0;
   }
   //
-  char buf[128];
   Standard_Boolean bRunParallel, bNonDestructive;
   Standard_Integer iErr;
   Standard_Real aFuzzyValue;
@@ -190,10 +195,18 @@ Standard_Integer bapibuild(Draw_Interpretor& di,
   aBuilder.SetGlue(aGlue);
   //
   aBuilder.Build(); 
-  iErr=aBuilder.ErrorStatus();
+  //
+  if (aBuilder.HasWarnings()) {
+    Standard_SStream aSStream;
+    aBuilder.DumpWarnings(aSStream);
+    di << aSStream;
+  }
+  //
+  iErr=aBuilder.HasErrors();
   if (iErr) {
-    Sprintf(buf, " error: %d\n",  iErr);
-    di << buf;
+    Standard_SStream aSStream;
+    aBuilder.DumpErrors(aSStream);
+    di << aSStream;
     return 0;
   }
   //
@@ -221,7 +234,6 @@ void ConvertList(const BOPCol_ListOfShape& aLSB,
     aLS.Append(aS);
   }
 }
-  
 
 //=======================================================================
 //function : bapisplit
@@ -248,10 +260,18 @@ Standard_Integer bapisplit(Draw_Interpretor& di,
   //
   // performing operation
   aSplitter.Build();
+  // check warning status
+  if (aSplitter.HasWarnings()) {
+    Standard_SStream aSStream;
+    aSplitter.DumpWarnings(aSStream);
+    di << aSStream;
+  }
   // checking error status
-  Standard_Integer iErr = aSplitter.ErrorStatus();
+  Standard_Integer iErr = aSplitter.HasErrors();
   if (iErr) {
-    di << "Error: " << iErr << "\n";
+    Standard_SStream aSStream;
+    aSplitter.DumpErrors(aSStream);
+    di << aSStream;
     return 0;
   }
   //
index 59c7a23..8475b92 100644 (file)
@@ -119,9 +119,7 @@ Standard_Integer bop(Draw_Interpretor& di,
                      Standard_Integer n, 
                      const char** a)
 {
-  char buf[32];
   Standard_Boolean bRunParallel, bNonDestructive;
-  Standard_Integer iErr;
   Standard_Real aTol;
   TopoDS_Shape aS1, aS2;
   BOPCol_ListOfShape aLC;
@@ -162,12 +160,7 @@ Standard_Integer bop(Draw_Interpretor& di,
   pPF->SetGlue(aGlue);
   //
   pPF->Perform();
-  iErr=pPF->ErrorStatus();
-  if (iErr) {
-    Sprintf(buf, " ErrorStatus : %d\n",  iErr);
-    di << buf;
-    return 0;
-  }
+  BOPTest::ReportAlerts(*pPF);
   //
   return 0;
 }
@@ -230,14 +223,14 @@ Standard_Integer bopsmt(Draw_Interpretor& di,
     return 0;
   }
   //
-  if (pPF->ErrorStatus()) {
+  if (pPF->HasErrors()) {
     di << " PaveFiller has not been done\n";
     return 0;
   }
   //
   char buf[64];
   Standard_Boolean bRunParallel;
-  Standard_Integer aNb, iErr;
+  Standard_Integer aNb;
   BOPAlgo_BOP aBOP;
   //
   const BOPCol_ListOfShape& aLC=pPF->Arguments();
@@ -259,10 +252,8 @@ Standard_Integer bopsmt(Draw_Interpretor& di,
   aBOP.SetRunParallel (bRunParallel);
   //
   aBOP.PerformWithFiller(*pPF);
-  iErr=aBOP.ErrorStatus();
-  if (iErr) {
-    Sprintf(buf, " ErrorStatus : %d\n",  iErr);
-    di << buf;
+  BOPTest::ReportAlerts(aBOP);
+  if (aBOP.HasErrors()) {
     return 0;
   }
   //
@@ -293,14 +284,14 @@ Standard_Integer bopsection(Draw_Interpretor& di,
     return 0;
   }
   //
-  if (pPF->ErrorStatus()) {
+  if (pPF->HasErrors()) {
     di << " PaveFiller has not been done\n";
     return 0;
   }
   //
   char buf[64];
   Standard_Boolean bRunParallel;
-  Standard_Integer aNb, iErr;
+  Standard_Integer aNb;
   BOPAlgo_Section aBOP;
   //
   const BOPCol_ListOfShape& aLC=pPF->Arguments();
@@ -321,10 +312,8 @@ Standard_Integer bopsection(Draw_Interpretor& di,
   aBOP.SetRunParallel (bRunParallel);
   //
   aBOP.PerformWithFiller(*pPF);
-  iErr=aBOP.ErrorStatus();
-  if (iErr) {
-    Sprintf(buf, " ErrorStatus : %d\n",  iErr);
-    di << buf;
+  BOPTest::ReportAlerts(aBOP);
+  if (aBOP.HasErrors()) {
     return 0;
   }
   //
@@ -399,9 +388,7 @@ Standard_Integer  bsection(Draw_Interpretor& di,
     return 0;
   }
   // 
-  char buf[80];
   Standard_Boolean bRunParallel, bNonDestructive, bApp, bPC1, bPC2;
-  Standard_Integer i, iErr;
   Standard_Real aTol;
   //
   bApp = Standard_True;
@@ -412,7 +399,7 @@ Standard_Integer  bsection(Draw_Interpretor& di,
   bNonDestructive = BOPTest_Objects::NonDestructive();
   BOPAlgo_GlueEnum aGlue = BOPTest_Objects::Glue();
   //
-  for (i = 4; i < n; ++i) {
+  for (Standard_Integer i = 4; i < n; ++i) {
     if (!strcmp(a[i], "-n2d")) {
       bPC1 = Standard_False;
       bPC2 = Standard_False;
@@ -440,10 +427,17 @@ Standard_Integer  bsection(Draw_Interpretor& di,
   aSec.SetGlue(aGlue);
   //
   aSec.Build();
-  iErr=aSec.ErrorStatus();
+  //
+  if (aSec.HasWarnings()) {
+    Standard_SStream aSStream;
+    aSec.DumpWarnings(aSStream);
+    di << aSStream;
+  }
+  //
   if (!aSec.IsDone()) {
-    Sprintf(buf, " ErrorStatus : %d\n",  iErr);
-    di << buf;
+    Standard_SStream aSStream;
+    aSec.DumpErrors(aSStream);
+    di << aSStream;
     return 0;
   }
   //
@@ -464,9 +458,7 @@ Standard_Integer bsmt (Draw_Interpretor& di,
                        const char** a,
                        const BOPAlgo_Operation aOp)
 {
-  char buf[32];
   Standard_Boolean bRunParallel, bNonDestructive;
-  Standard_Integer iErr;
   TopoDS_Shape aS1, aS2;
   BOPCol_ListOfShape aLC;
   Standard_Real aTol;
@@ -504,10 +496,8 @@ Standard_Integer bsmt (Draw_Interpretor& di,
   aPF.SetGlue(aGlue);
   //
   aPF.Perform();
-  iErr=aPF.ErrorStatus();
-  if (iErr) {
-    Sprintf(buf, " ErrorStatus : %d\n",  iErr);
-    di << buf;
+  BOPTest::ReportAlerts(aPF);
+  if (aPF.HasErrors()) {
     return 0;
   }
   //
@@ -520,11 +510,8 @@ Standard_Integer bsmt (Draw_Interpretor& di,
   aBOP.SetRunParallel(bRunParallel);
   // 
   aBOP.PerformWithFiller(aPF);
-  //
-  iErr=aBOP.ErrorStatus();
-  if (iErr) {
-    Sprintf(buf, " ErrorStatus : %d\n",  iErr);
-    di << buf;
+  BOPTest::ReportAlerts(aBOP);
+  if (aBOP.HasErrors()) {
     return 0;
   }
   const TopoDS_Shape& aR=aBOP.Shape();
@@ -830,9 +817,9 @@ Standard_Integer mkvolume(Draw_Interpretor& di, Standard_Integer n, const char**
   aMV.SetGlue(aGlue);
   //
   aMV.Perform();
-  if (aMV.ErrorStatus()) {
-    di << "Error status: " << aMV.ErrorStatus();
-    return 1;
+  BOPTest::ReportAlerts(aMV);
+  if (aMV.HasErrors()) {
+    return 0;
   }
   //
   const TopoDS_Shape& aR = aMV.Shape();
index 58f93a1..719f57b 100644 (file)
@@ -80,7 +80,6 @@ Standard_Integer bcbuild(Draw_Interpretor& di,
     return 1;
   }
   //
-  Standard_Integer iErr;
   BOPCol_ListIteratorOfListOfShape aIt;
   //
   BOPAlgo_PaveFiller& aPF = BOPTest_Objects::PaveFiller();
@@ -114,10 +113,9 @@ Standard_Integer bcbuild(Draw_Interpretor& di,
   aCBuilder.SetGlue(aGlue);
   //
   aCBuilder.PerformWithFiller(aPF); 
-  iErr = aCBuilder.ErrorStatus();
-  if (iErr) {
-    di << "error: " << iErr << "\n";
-    return 1;
+  BOPTest::ReportAlerts(aCBuilder);
+  if (aCBuilder.HasErrors()) {
+    return 0;
   }
   //
   BOPTest_Objects::SetBuilder(&aCBuilder);
@@ -160,11 +158,9 @@ Standard_Integer bcaddall(Draw_Interpretor& di,
   //
   BOPAlgo_CellsBuilder& aCBuilder = BOPTest_Objects::CellsBuilder();
   //
+  aCBuilder.ClearWarnings();
   aCBuilder.AddAllToResult(iMaterial, bUpdate);
-  //
-  Standard_SStream aSStream;
-  aCBuilder.DumpWarnings(aSStream);
-  di << aSStream;
+  BOPTest::ReportAlerts(aCBuilder);
   //
   const TopoDS_Shape& aR = aCBuilder.Shape();
   //
@@ -245,11 +241,10 @@ Standard_Integer bcadd(Draw_Interpretor& di,
   }
   //
   BOPAlgo_CellsBuilder& aCBuilder = BOPTest_Objects::CellsBuilder();
-  aCBuilder.AddToResult(aLSToTake, aLSToAvoid, iMaterial, bUpdate);
   //
-  Standard_SStream aSStream;
-  aCBuilder.DumpWarnings(aSStream);
-  di << aSStream;
+  aCBuilder.ClearWarnings();
+  aCBuilder.AddToResult(aLSToTake, aLSToAvoid, iMaterial, bUpdate);
+  BOPTest::ReportAlerts(aCBuilder);
   //
   const TopoDS_Shape& aR = aCBuilder.Shape();
   //
@@ -317,11 +312,10 @@ Standard_Integer bcremoveint(Draw_Interpretor& di,
   }
   //
   BOPAlgo_CellsBuilder& aCBuilder = BOPTest_Objects::CellsBuilder();
-  aCBuilder.RemoveInternalBoundaries();
   //
-  Standard_SStream aSStream;
-  aCBuilder.DumpWarnings(aSStream);
-  di << aSStream;
+  aCBuilder.ClearWarnings();
+  aCBuilder.RemoveInternalBoundaries();
+  BOPTest::ReportAlerts(aCBuilder);
   //
   const TopoDS_Shape& aR = aCBuilder.Shape();
   //
index 69655ac..618e86c 100644 (file)
@@ -235,7 +235,7 @@ Standard_Integer bopcheck (Draw_Interpretor& di,
   //
   aTimer.Stop();
   //
-  iErr=aChecker.ErrorStatus();
+  iErr=aChecker.HasErrors();
   //
   const BOPDS_DS& aDS=*(aChecker.PDS());
   //
index 28e91cc..f5b5279 100644 (file)
@@ -1347,11 +1347,9 @@ Standard_Integer bopbface (Draw_Interpretor& di,
   aBF.SetFace(aF);
   aBF.SetShapes(aLE);
   aBF.Perform();
-  //
-  Standard_Integer iErr = aBF.ErrorStatus();
-  if (iErr != 0) {
-    di << " Error: " << iErr << "\n";
-    return 1;
+  BOPTest::ReportAlerts(aBF);
+  if (aBF.HasErrors()) {
+    return 0;
   }
   //
   char buf[128];
@@ -1409,11 +1407,9 @@ Standard_Integer bopbsolid (Draw_Interpretor& di,
   BOPAlgo_BuilderSolid aBS;
   aBS.SetShapes(aLF);
   aBS.Perform();
-  //
-  Standard_Integer iErr = aBS.ErrorStatus();
-  if (iErr != 0) {
-    di << " Error: " << iErr << "\n";
-    return 1;
+  BOPTest::ReportAlerts(aBS);
+  if (aBS.HasErrors()) {
+    return 0;
   }
   //
   Standard_Integer i;
index 7c703e8..d4da66d 100644 (file)
@@ -54,6 +54,7 @@ class BOPTest_Session {
     myNonDestructive = Standard_False;
     myFuzzyValue = 0.;
     myGlue = BOPAlgo_GlueOff;
+    myDrawWarnShapes = Standard_False;
   };
   //
   // Clear
@@ -133,6 +134,14 @@ class BOPTest_Session {
     return myGlue;
   };
   //
+  void SetDrawWarnShapes(const Standard_Boolean bDraw) {
+    myDrawWarnShapes = bDraw;
+  };
+  //
+  Standard_Boolean DrawWarnShapes() const {
+    return myDrawWarnShapes;
+  };
+  //
 protected:
   //
   BOPTest_Session(const BOPTest_Session&);
@@ -150,6 +159,7 @@ protected:
   Standard_Boolean myNonDestructive;
   Standard_Real myFuzzyValue;
   BOPAlgo_GlueEnum myGlue;
+  Standard_Boolean myDrawWarnShapes;
 };
 //
 //=======================================================================
@@ -344,6 +354,22 @@ BOPAlgo_GlueEnum BOPTest_Objects::Glue()
   return GetSession().Glue();
 }
 //=======================================================================
+//function : SetDrawWarnShapes
+//purpose  : 
+//=======================================================================
+void BOPTest_Objects::SetDrawWarnShapes(const Standard_Boolean bDraw)
+{
+  GetSession().SetDrawWarnShapes(bDraw);
+}
+//=======================================================================
+//function : DrawWarnShapes
+//purpose  : 
+//=======================================================================
+Standard_Boolean BOPTest_Objects::DrawWarnShapes()
+{
+  return GetSession().DrawWarnShapes();
+}
+//=======================================================================
 //function : Allocator1
 //purpose  : 
 //=======================================================================
index 96cdd85..48237ad 100644 (file)
@@ -83,6 +83,9 @@ public:
 
   Standard_EXPORT static BOPAlgo_GlueEnum Glue();
 
+  Standard_EXPORT static void SetDrawWarnShapes(const Standard_Boolean bDraw);
+
+  Standard_EXPORT static Standard_Boolean DrawWarnShapes();
 
 protected:
 
index 8e38fb7..6366168 100644 (file)
@@ -26,6 +26,7 @@ static Standard_Integer brunparallel (Draw_Interpretor&, Standard_Integer, const
 static Standard_Integer bnondestructive(Draw_Interpretor&, Standard_Integer, const char**);
 static Standard_Integer bfuzzyvalue(Draw_Interpretor&, Standard_Integer, const char**);
 static Standard_Integer bGlue(Draw_Interpretor&, Standard_Integer, const char**);
+static Standard_Integer bdrawwarnshapes(Draw_Interpretor&, Standard_Integer, const char**);
 
 //=======================================================================
 //function : OptionCommands
@@ -44,6 +45,9 @@ void BOPTest::OptionCommands(Draw_Interpretor& theCommands)
   theCommands.Add("bnondestructive", "use bnondestructive [0/1]", __FILE__, bnondestructive, g);
   theCommands.Add("bfuzzyvalue", "use bfuzzyvalue value", __FILE__, bfuzzyvalue, g);
   theCommands.Add("bglue", "use bglue [0 (off) / 1 (shift) / 2 (full)]", __FILE__, bGlue, g);
+  theCommands.Add("bdrawwarnshapes", "Defines whether to draw warning shapes or not\n"
+                  "Usage: bdrawwarnshapes [0 (do not draw) / 1 (draw warning shapes)",
+                  __FILE__, bdrawwarnshapes, g);
 }
 //=======================================================================
 //function : boptions
@@ -67,6 +71,7 @@ Standard_Integer boptions(Draw_Interpretor& di,
   bNonDestructive = BOPTest_Objects::NonDestructive();
   aFuzzyValue = BOPTest_Objects::FuzzyValue();
   aGlue = BOPTest_Objects::Glue();
+  Standard_Boolean bDrawWarnShapes = BOPTest_Objects::DrawWarnShapes();
   //
   Sprintf(buf, " RunParallel: %d\n",  bRunParallel);
   di << buf;
@@ -77,6 +82,8 @@ Standard_Integer boptions(Draw_Interpretor& di,
   Sprintf(buf, " GlueOption: %s\n", ((aGlue == BOPAlgo_GlueOff) ? "Off" :
     ((aGlue == BOPAlgo_GlueFull) ? "Full" : "Shift")));
   di << buf;
+  Sprintf(buf, " Draw Warning Shapes: %s\n", bDrawWarnShapes ? "Yes" : "No");
+  di << buf;
   //
   return 0;
 }
@@ -184,3 +191,21 @@ Standard_Integer bGlue(Draw_Interpretor& di,
   //
   return 0;
 }
+
+//=======================================================================
+//function : bdrawwarnshapes
+//purpose  : 
+//=======================================================================
+Standard_Integer bdrawwarnshapes(Draw_Interpretor& di,
+                              Standard_Integer n, 
+                              const char** a) 
+{ 
+  if (n != 2) {
+    di << " use bdrawwarnshapes [0 (do not draw) / 1 (draw warning shapes)\n";
+    return 1;
+  }
+  //
+  Standard_Integer iDraw = Draw::Atoi(a[1]);
+  BOPTest_Objects::SetDrawWarnShapes(iDraw != 0);
+  return 0;
+}
index ea60954..7926a39 100644 (file)
@@ -70,7 +70,7 @@ Standard_Integer bfillds(Draw_Interpretor& di,
   //
   char buf[32];
   Standard_Boolean bRunParallel, bNonDestructive, bShowTime;
-  Standard_Integer i, aNbS, iErr;
+  Standard_Integer i, aNbS;
   Standard_Real aTol;
   BOPCol_ListIteratorOfListOfShape aIt;
   BOPCol_ListOfShape aLC;
@@ -120,10 +120,8 @@ Standard_Integer bfillds(Draw_Interpretor& di,
   aTimer.Start();
   //
   aPF.Perform();
-  iErr=aPF.ErrorStatus();
-  if (iErr) {
-    Sprintf(buf, " error: %d\n",  iErr);
-    di << buf;
+  BOPTest::ReportAlerts(aPF);
+  if (aPF.HasErrors()) {
     return 0;
   }
   //
@@ -158,7 +156,7 @@ Standard_Integer bbuild(Draw_Interpretor& di,
   //
   char buf[128];
   Standard_Boolean bRunParallel, bShowTime;
-  Standard_Integer i, iErr;
+  Standard_Integer i;
 
   BOPCol_ListIteratorOfListOfShape aIt;
   //
@@ -196,10 +194,8 @@ Standard_Integer bbuild(Draw_Interpretor& di,
   aTimer.Start();
   //
   aBuilder.PerformWithFiller(aPF); 
-  iErr=aBuilder.ErrorStatus();
-  if (iErr) {
-    Sprintf(buf, " error: %d\n",  iErr);
-    di << buf;
+  BOPTest::ReportAlerts(aBuilder);
+  if (aBuilder.HasErrors()) {
     return 0;
   }
   //
@@ -241,7 +237,7 @@ Standard_Integer bbop(Draw_Interpretor& di,
   //
   char buf[32];
   Standard_Boolean bRunParallel, bShowTime;
-  Standard_Integer iErr, iOp, i;
+  Standard_Integer iOp, i;
   BOPAlgo_Operation aOp;
   BOPCol_ListIteratorOfListOfShape aIt; 
   //
@@ -307,10 +303,8 @@ Standard_Integer bbop(Draw_Interpretor& di,
   aTimer.Start();
   //
   pBuilder->PerformWithFiller(aPF);
-  iErr=pBuilder->ErrorStatus();
-  if (iErr) {
-    Sprintf(buf, " error: %d\n",  iErr);
-    di << buf;
+  BOPTest::ReportAlerts(*pBuilder);
+  if (pBuilder->HasErrors()) {
     return 0;
   }
   //
@@ -378,10 +372,8 @@ Standard_Integer bsplit(Draw_Interpretor& di,
   pSplitter->PerformWithFiller(aPF);
   //
   aTimer.Stop();
-  //
-  Standard_Integer iErr = pSplitter->ErrorStatus();
-  if (iErr) {
-    di << " error: " << iErr << "\n";
+  BOPTest::ReportAlerts(*pSplitter);
+  if (pSplitter->HasErrors()) {
     return 0;
   }
   //
index c5c9ce5..a7bf17e 100644 (file)
@@ -14,9 +14,7 @@
 
 
 #include <BRepAlgoAPI_Algo.hxx>
-#include <Message_ProgressIndicator.hxx>
 #include <NCollection_BaseAllocator.hxx>
-#include <Standard_NotImplemented.hxx>
 #include <TopoDS_Shape.hxx>
 
 //=======================================================================
 //=======================================================================
 BRepAlgoAPI_Algo::BRepAlgoAPI_Algo()
 :
-  myAllocator(NCollection_BaseAllocator::CommonBaseAllocator()),
-  myErrorStatus(1),
-  myWarningStatus(0),
-  myRunParallel(Standard_False)
+  BOPAlgo_Options(NCollection_BaseAllocator::CommonBaseAllocator())
 {}
 //=======================================================================
 // function: 
@@ -37,10 +32,7 @@ BRepAlgoAPI_Algo::BRepAlgoAPI_Algo()
 BRepAlgoAPI_Algo::BRepAlgoAPI_Algo
   (const Handle(NCollection_BaseAllocator)& theAllocator)
 :
-  myAllocator(theAllocator),
-  myErrorStatus(1),
-  myWarningStatus(0),
-  myRunParallel(Standard_False)
+  BOPAlgo_Options(theAllocator)
 {}
 
 //=======================================================================
@@ -51,70 +43,6 @@ BRepAlgoAPI_Algo::~BRepAlgoAPI_Algo()
 {
 }
 //=======================================================================
-//function : Allocator
-//purpose  : 
-//=======================================================================
-const Handle(NCollection_BaseAllocator)& BRepAlgoAPI_Algo::Allocator()const
-{
-  return myAllocator;
-}
-//=======================================================================
-// function: ErrorStatus
-// purpose: 
-//=======================================================================
-Standard_Integer BRepAlgoAPI_Algo::ErrorStatus()const
-{
-  return myErrorStatus;
-}
-//=======================================================================
-// function: WarningStatus
-// purpose: 
-//=======================================================================
-Standard_Integer BRepAlgoAPI_Algo::WarningStatus()const
-{
-  return myWarningStatus;
-}
-//=======================================================================
-//function : SetRunParallel
-//purpose  : 
-//=======================================================================
-void BRepAlgoAPI_Algo::SetRunParallel(const Standard_Boolean theFlag)
-{
-  myRunParallel=theFlag;
-}
-//=======================================================================
-//function : RunParallel
-//purpose  : 
-//=======================================================================
-Standard_Boolean BRepAlgoAPI_Algo::RunParallel()const
-{
-  return myRunParallel;
-}
-//=======================================================================
-//function : SetProgressIndicator
-//purpose  : 
-//=======================================================================
-void BRepAlgoAPI_Algo::SetProgressIndicator
-  (const Handle(Message_ProgressIndicator)& theObj)
-{
-  if (!theObj.IsNull()) {
-    myProgressIndicator=theObj;
-  }
-}
-//=======================================================================
-//function : UserBreak
-//purpose  : 
-//=======================================================================
-void BRepAlgoAPI_Algo::UserBreak() const
-{
-  if (myProgressIndicator.IsNull()) {
-    return;
-  }
-  if (myProgressIndicator->UserBreak()) {
-    throw Standard_NotImplemented ("BRepAlgoAPI_Algo::UserBreak(), method is not implemented");
-  }
-} 
-//=======================================================================
 //function : Shape
 //purpose  : 
 //=======================================================================
@@ -122,13 +50,3 @@ const TopoDS_Shape& BRepAlgoAPI_Algo::Shape()
 {
   return myShape;
 }
-//=======================================================================
-//function : Clear
-//purpose  : 
-//=======================================================================
-void BRepAlgoAPI_Algo::Clear()
-{
-}
-//  myErrorStatus
-//
-// 1 - object is just initialized
index 6e890e6..4758f38 100644 (file)
 #include <Standard_Integer.hxx>
 #include <Standard_Boolean.hxx>
 #include <BRepBuilderAPI_MakeShape.hxx>
+#include <BOPAlgo_Options.hxx>
 class Message_ProgressIndicator;
 class TopoDS_Shape;
 
 
-//! provides the root interface for algorithms
-class BRepAlgoAPI_Algo  : public BRepBuilderAPI_MakeShape
+//! Provides the root interface for the API algorithms
+
+class BRepAlgoAPI_Algo : public BRepBuilderAPI_MakeShape,
+                         protected BOPAlgo_Options
 {
 public:
 
   DEFINE_STANDARD_ALLOC
 
-  
-  //! Returns error status of the algorithm
-  //! ==0 - no errors occured
-  //! !=0 - is in the event of various error conditions
-  Standard_EXPORT Standard_Integer ErrorStatus() const;
-  
-  //! Returns warning  status of the algorithm
-  //! ==0 - no warning occured
-  //! !=0 - is in the event of various warning conditions
-  Standard_EXPORT Standard_Integer WarningStatus() const;
-  
-  Standard_EXPORT const BOPCol_BaseAllocator& Allocator() const;
-  
-  //! Set the flag of parallel processing
-  //! if <theFlag> is true  the parallel processing is switched on
-  //! if <theFlag> is false the parallel processing is switched off
-  Standard_EXPORT void SetRunParallel (const Standard_Boolean theFlag);
-  
-  //! Returns the flag of parallel processing
-  Standard_EXPORT Standard_Boolean RunParallel() const;
-  
-  //! Set the Progress Indicator object.
-  Standard_EXPORT void SetProgressIndicator (const Handle(Message_ProgressIndicator)& theObj);
-  
   Standard_EXPORT virtual const TopoDS_Shape& Shape() Standard_OVERRIDE;
 
-
-
+  // Provide access to methods of protected base class BOPAlgo_Options
+  // (inherited as protected to avoid problems with SWIG wrapper)
+  using BOPAlgo_Options::Clear;
+  using BOPAlgo_Options::SetRunParallel;
+  using BOPAlgo_Options::RunParallel;
+  using BOPAlgo_Options::SetFuzzyValue;
+  using BOPAlgo_Options::FuzzyValue;
+  using BOPAlgo_Options::HasErrors;
+  using BOPAlgo_Options::HasWarnings;
+  using BOPAlgo_Options::HasError;
+  using BOPAlgo_Options::HasWarning;
+  using BOPAlgo_Options::DumpErrors;
+  using BOPAlgo_Options::DumpWarnings;
+  using BOPAlgo_Options::ClearWarnings;
+  using BOPAlgo_Options::GetReport;
+  using BOPAlgo_Options::SetProgressIndicator;
 
 protected:
 
-  
   //! Empty constructor
   Standard_EXPORT BRepAlgoAPI_Algo();
-Standard_EXPORT virtual ~BRepAlgoAPI_Algo();
-  
-  //! Empty constructor
-  Standard_EXPORT BRepAlgoAPI_Algo(const BOPCol_BaseAllocator& theAllocator);
-  
-  //! Breaks the execution if the break signal
-  //! is indicated by myProgressIndicator.
-  Standard_EXPORT void UserBreak() const;
-  
-  Standard_EXPORT virtual void Clear();
 
+  //! Destructor
+  Standard_EXPORT virtual ~BRepAlgoAPI_Algo();
 
-  BOPCol_BaseAllocator myAllocator;
-  Standard_Integer myErrorStatus;
-  Standard_Integer myWarningStatus;
-  Standard_Boolean myRunParallel;
-  Handle(Message_ProgressIndicator) myProgressIndicator;
-
+  //! Empty constructor
+  Standard_EXPORT BRepAlgoAPI_Algo(const BOPCol_BaseAllocator& theAllocator);
 
 private:
 
-
-
-
-
 };
 
-
-
-
-
-
-
 #endif // _BRepAlgoAPI_Algo_HeaderFile
index 33e7f9a..6fe309e 100644 (file)
@@ -18,6 +18,7 @@
 #include <BOPAlgo_BOP.hxx>
 #include <BOPAlgo_PaveFiller.hxx>
 #include <BOPAlgo_Section.hxx>
+#include <BOPAlgo_Alerts.hxx>
 #include <BOPDS_Curve.hxx>
 #include <BOPDS_DS.hxx>
 #include <BOPDS_Interf.hxx>
@@ -179,7 +180,7 @@ BRepAlgoAPI_BooleanOperation::~BRepAlgoAPI_BooleanOperation()
 void BRepAlgoAPI_BooleanOperation::Clear()
 {
   BRepAlgoAPI_BuilderAlgo::Clear();
+  //
   myModifFaces.Clear();
   myEdgeMap.Clear();
 }
@@ -262,21 +263,22 @@ void BRepAlgoAPI_BooleanOperation::SetAttributes()
 //=======================================================================
 void BRepAlgoAPI_BooleanOperation::Build()
 {
-  Standard_Integer iErr, aNbArgs, aNbTools;  
+  GetReport()->Clear();
+
+  Standard_Integer aNbArgs, aNbTools;
   BRepAlgoAPI_DumpOper aDumpOper;
   //
   myBuilderCanWork=Standard_False;
-  myErrorStatus=0;
   NotDone();
   //
   aNbArgs=myArguments.Extent();
   aNbTools=myTools.Extent();
   if (aNbArgs<1 && aNbTools<1) {
-    myErrorStatus=2;
+    AddError (new BOPAlgo_AlertTooFewArguments);
     return;
   }
   if (myOperation==BOPAlgo_UNKNOWN) {
-    myErrorStatus=6;
+    AddError (new BOPAlgo_AlertBOPNotSet);
     return;
   }
   //
@@ -313,9 +315,10 @@ void BRepAlgoAPI_BooleanOperation::Build()
     SetAttributes();
     //
     myDSFiller->Perform(); 
-    iErr=myDSFiller->ErrorStatus();
-    if (iErr) {
-      myErrorStatus=100+iErr;
+    //
+    GetReport()->Merge (myDSFiller->GetReport());
+    if (HasErrors())
+    {
       return;
     }
   }// if (myEntryType) {
@@ -331,6 +334,7 @@ void BRepAlgoAPI_BooleanOperation::Build()
   // 
   if (myBuilder) {
     delete myBuilder;
+    myBuilder = NULL;
   }
   //
   BOPAlgo_BOP *pBOP;
@@ -351,9 +355,10 @@ void BRepAlgoAPI_BooleanOperation::Build()
   myBuilder->SetProgressIndicator(myProgressIndicator);
   //
   myBuilder->PerformWithFiller(*myDSFiller);
-  iErr = myBuilder->ErrorStatus();
-  if (iErr) {
-    myErrorStatus=200+iErr;
+  //
+  GetReport()->Merge (myBuilder->GetReport());
+  if (HasErrors())
+  {
     return;
   }
   //
@@ -698,4 +703,3 @@ void BRepAlgoAPI_DumpOper::Dump (const TopoDS_Shape& theShape1,
   fprintf(afile, "%s\n",aBopString.ToCString());
   fclose(afile);
 }
-//XXXX
index a7bdc75..566805b 100644 (file)
@@ -33,10 +33,16 @@ class TopoDS_Shape;
 
 //! The abstract class BooleanOperation is the root
 //! class of Boolean Operations (see Overview).
-//! Boolean Operations algorithm is divided onto two parts.
-//! - The first one is computing interference between arguments.
-//! - The second one is building the result of operation.
-//! The class BooleanOperation provides API level of both parts
+//! Boolean Operations algorithm is divided onto two parts:<br>
+//! - The first one is computing interference between arguments;<br>
+//! - The second one is building the result of operation;<br>
+//! The class BooleanOperation provides API level of both parts.<br>
+//!
+//! Additionally to the errors of the parent class the algorithm
+//! returns the following Error statuses:<br>
+//! - 0 - in case of success;<br>
+//! - *BOPAlgo_AlertBOPNotSet* - in case the type of Boolean Operation is not set.<br>
+//!
 class BRepAlgoAPI_BooleanOperation  : public BRepAlgoAPI_BuilderAlgo
 {
 public:
@@ -108,11 +114,7 @@ Standard_EXPORT virtual ~BRepAlgoAPI_BooleanOperation();
   //! For use in BRepNaming.
   Standard_EXPORT virtual Standard_Boolean HasDeleted() const Standard_OVERRIDE;
 
-
-
-
 protected:
-
   
   //! Empty constructor
   Standard_EXPORT BRepAlgoAPI_BooleanOperation();
index f086acb..824b5f4 100644 (file)
@@ -28,7 +28,6 @@ BRepAlgoAPI_BuilderAlgo::BRepAlgoAPI_BuilderAlgo()
   myEntryType(1),
   myDSFiller(NULL),
   myBuilder(NULL),
-  myFuzzyValue(0.),
   myNonDestructive(Standard_False),
   myGlue(BOPAlgo_GlueOff)
 {}
@@ -42,7 +41,6 @@ BRepAlgoAPI_BuilderAlgo::BRepAlgoAPI_BuilderAlgo
   BRepAlgoAPI_Algo(),
   myEntryType(0),
   myBuilder(NULL),
-  myFuzzyValue(0.),
   myNonDestructive(Standard_False),
   myGlue(BOPAlgo_GlueOff)
 {
@@ -58,22 +56,6 @@ BRepAlgoAPI_BuilderAlgo::~BRepAlgoAPI_BuilderAlgo()
   Clear();
 }
 //=======================================================================
-//function : SetFuzzyValue
-//purpose  : 
-//=======================================================================
-void BRepAlgoAPI_BuilderAlgo::SetFuzzyValue(const Standard_Real theFuzz)
-{
-  myFuzzyValue = (theFuzz < 0.) ? 0. : theFuzz;
-}
-//=======================================================================
-//function : FuzzyValue
-//purpose  : 
-//=======================================================================
-Standard_Real BRepAlgoAPI_BuilderAlgo::FuzzyValue() const
-{
-  return myFuzzyValue;
-}
-//=======================================================================
 //function : SetNonDestructive
 //purpose  : 
 //=======================================================================
@@ -111,6 +93,7 @@ BOPAlgo_GlueEnum BRepAlgoAPI_BuilderAlgo::Glue() const
 //=======================================================================
 void BRepAlgoAPI_BuilderAlgo::Clear()
 {
+  BRepAlgoAPI_Algo::Clear();
   if (myDSFiller && myEntryType) {
     delete myDSFiller;
     myDSFiller=NULL;
@@ -143,10 +126,7 @@ const TopTools_ListOfShape& BRepAlgoAPI_BuilderAlgo::Arguments()const
 //=======================================================================
 void BRepAlgoAPI_BuilderAlgo::Build()
 {
-  Standard_Integer iErr;
-  //
   NotDone();
-  myErrorStatus=0;
   //
   Clear();
   //
@@ -165,14 +145,17 @@ void BRepAlgoAPI_BuilderAlgo::Build()
     myDSFiller->SetGlue(myGlue);
     //
     myDSFiller->Perform();
-    iErr=myDSFiller->ErrorStatus();
-    if (iErr) {
-      myErrorStatus=100+iErr;
+    //
+    GetReport()->Merge (myDSFiller->GetReport());
+    if (HasErrors())
+    {
+      return;
     }
   }// if (myEntryType) {
   // 
   if (myBuilder) {
     delete myBuilder;
+    myBuilder = NULL;
   }
   myBuilder=new BOPAlgo_Builder(myAllocator);
   //
@@ -182,10 +165,8 @@ void BRepAlgoAPI_BuilderAlgo::Build()
   myBuilder->SetProgressIndicator(myProgressIndicator);
   //
   myBuilder->PerformWithFiller(*myDSFiller);
-  iErr=myBuilder->ErrorStatus();
-  if (iErr) {
-    myErrorStatus=200+iErr;
-  }
+  //
+  GetReport()->Merge (myBuilder->GetReport());
   //
   Done();
   myShape=myBuilder->Shape();
index d7e5640..f138351 100644 (file)
@@ -32,7 +32,16 @@ class TopoDS_Shape;
 
 
 
-//! The clsss contains API level of General Fuse algorithm
+//! The class contains API level of the General Fuse algorithm.<br>
+//!
+//! It returns the following Error statuses:<br>
+//! - 0 - in case of success;<br>
+//! - *BOPAlgo_AlertTooFewArguments* - in case there are no enough arguments to perform the operation;<br>
+//! - *BOPAlgo_AlertIntersectionFailed* - in case the intersection of the arguments has failed;<br>
+//! - *BOPAlgo_AlertBuilderFailed* - in case building of the result shape has failed.<br>
+//!
+//! Warnings statuses from underlying DS Filler and Builder algorithms
+//! are collected in the report.
 class BRepAlgoAPI_BuilderAlgo  : public BRepAlgoAPI_Algo
 {
 public:
@@ -47,12 +56,6 @@ Standard_EXPORT virtual ~BRepAlgoAPI_BuilderAlgo();
   //! Empty constructor
   Standard_EXPORT BRepAlgoAPI_BuilderAlgo(const BOPAlgo_PaveFiller& thePF);
   
-  //! Sets the additional tolerance
-  Standard_EXPORT void SetFuzzyValue (const Standard_Real theFuzz);
-  
-  //! Returns the additional tolerance
-  Standard_EXPORT Standard_Real FuzzyValue() const;
-
   //! Sets the flag that defines the mode of treatment.
   //! In non-destructive mode the argument shapes are not modified. Instead
   //! a copy of a sub-shape is created in the result if it is needed to be updated.
@@ -105,19 +108,25 @@ Standard_EXPORT virtual ~BRepAlgoAPI_BuilderAlgo();
   //! protected methods
   Standard_EXPORT virtual Standard_Boolean HasDeleted() const;
 
+  //! Returns the Intersection tool
+  const BOPAlgo_PPaveFiller& DSFiller() const
+  {
+    return myDSFiller;
+  }
 
-
+  //! Returns the Building tool
+  const BOPAlgo_PBuilder& Builder() const
+  {
+    return myBuilder;
+  }
 
 protected:
 
-  
   Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
 
-
   Standard_Integer myEntryType;
   BOPAlgo_PPaveFiller myDSFiller;
   BOPAlgo_PBuilder myBuilder;
-  Standard_Real myFuzzyValue;
   Standard_Boolean myNonDestructive;
   TopTools_ListOfShape myArguments;
   BOPAlgo_GlueEnum myGlue;
index 7c5c0ea..c229093 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <BOPAlgo_PaveFiller.hxx>
 #include <BOPAlgo_Splitter.hxx>
+#include <BOPAlgo_Alerts.hxx>
 
 //=======================================================================
 // function: Empty constructor
@@ -64,16 +65,15 @@ const TopTools_ListOfShape& BRepAlgoAPI_Splitter::Tools() const
 void BRepAlgoAPI_Splitter::Build()
 {
   NotDone();
-  myErrorStatus = 0;
+  //
+  Clear();
   //
   if (myArguments.IsEmpty() ||
     (myArguments.Extent() + myTools.Extent()) < 2) {
-    myErrorStatus = 1;
+    AddError (new BOPAlgo_AlertTooFewArguments);
     return;
   }
   //
-  Clear();
-  //
   if (myEntryType) {
     if (myDSFiller) {
       delete myDSFiller;
@@ -100,9 +100,11 @@ void BRepAlgoAPI_Splitter::Build()
     myDSFiller->SetGlue(myGlue);
     //
     myDSFiller->Perform();
-    Standard_Integer iErr = myDSFiller->ErrorStatus();
-    if (iErr) {
-      myErrorStatus = 2;
+    //
+    GetReport()->Merge (myDSFiller->GetReport());
+    if (HasErrors()) 
+    {
+      return;
     }
   }
   //
@@ -121,10 +123,8 @@ void BRepAlgoAPI_Splitter::Build()
   myBuilder->SetProgressIndicator(myProgressIndicator);
   //
   myBuilder->PerformWithFiller(*myDSFiller);
-  Standard_Integer iErr = myBuilder->ErrorStatus();
-  if (iErr) {
-    myErrorStatus = 3;
-  }
+  //
+  GetReport()->Merge (myBuilder->GetReport());
   //
   Done();
   myShape = myBuilder->Shape();
index 56b0cc6..1da8a50 100644 (file)
@@ -44,9 +44,9 @@
 //!
 //! The algorithm returns the following Error statuses:<br>
 //! - 0 - in case of success;<br>
-//! - 1 - in case there is no enough arguments for the operation;<br>
-//! - 2 - in case the Intersection of the arguments has failed;<br>
-//! - 3 - in case the Building of the result has failed.
+//! - *BOPAlgo_AlertTooFewArguments*    - in case there is no enough arguments for the operation;<br>
+//! - *BOPAlgo_AlertIntersectionFailed* - in case the Intersection of the arguments has failed;<br>
+//! - *BOPAlgo_AlertBuilderFailed*      - in case the Building of the result has failed.
 class BRepAlgoAPI_Splitter : public BRepAlgoAPI_BuilderAlgo
 {
 public:
index e1d3de5..59b2440 100644 (file)
 //=======================================================================
   void BRepFeat_Builder::Prepare()
 {
-  myErrorStatus=0;
+  GetReport()->Clear();
   //
   BRep_Builder aBB;
   TopoDS_Compound aC;
     RebuildFaces();
     //
     FillImagesContainers(TopAbs_SHELL);
-    if (myErrorStatus) {
+    if (HasErrors()) {
       return;
     }
     //
     FillImagesSolids();
-    if (myErrorStatus) {
+    if (HasErrors()) {
       return;
     }
     //
     CheckSolidImages();
     //
     BuildResult(TopAbs_SOLID);
-    if (myErrorStatus) {
+    if (HasErrors()) {
       return;
     }
     // 
     FillImagesCompounds();
-    if (myErrorStatus) {
+    if (HasErrors()) {
       return;
     }
     //
     BuildResult(TopAbs_COMPOUND);
-    if (myErrorStatus) {
+    if (HasErrors()) {
       return;
     }
   }
                                        BOPCol_DataMapOfShapeShape& theDraftSolids,
                                        const Handle(NCollection_BaseAllocator)& theAllocator)
 {
-  myErrorStatus=0;
+  GetReport()->Clear();
   //
   Standard_Boolean bIsIN, bHasImage;
   Standard_Integer aNbS, i, j, aNbFP, aNbFPx, aNbFIN, aNbLIF, aNbEFP;
index edea267..d2b3682 100644 (file)
@@ -587,7 +587,7 @@ void BRepFeat_MakeCylindricalHole::Build ()
 {
   if (myStatus == BRepFeat_NoError) {
     PerformResult();
-    if (!ErrorStatus()) {
+    if (!HasErrors()) {
       myStatus = (myValidate) ? Validate() : BRepFeat_NoError;
       if (myStatus == BRepFeat_NoError) {
         myShape = Shape();
index 65d6a2c..9d3e925 100644 (file)
@@ -300,7 +300,7 @@ void BRepFill_TrimShellCorner::Perform()
   aPF.SetArguments(aLS);
   //
   aPF.Perform();
-  if (aPF.ErrorStatus()) {
+  if (aPF.HasErrors()) {
     return;
   }
   //
index 5fdeb1c..9499673 100644 (file)
@@ -4087,7 +4087,7 @@ Standard_Boolean BuildShellsCompleteInter(const BOPCol_ListOfShape& theLF,
   aMV1.SetAvoidInternalShapes(Standard_True);
   aMV1.Perform();
   //
-  Standard_Boolean bDone = (aMV1.ErrorStatus() == 0);
+  Standard_Boolean bDone = ! aMV1.HasErrors();
   if (!bDone) {
     return bDone;
   }
@@ -4130,7 +4130,7 @@ Standard_Boolean BuildShellsCompleteInter(const BOPCol_ListOfShape& theLF,
   aMV2.SetIntersect(Standard_False);
   aMV2.SetAvoidInternalShapes(Standard_True);
   aMV2.Perform();
-  bDone = (aMV2.ErrorStatus() == 0);
+  bDone = ! aMV2.HasErrors();
   if (!bDone) {
     return bDone;
   }
@@ -4175,7 +4175,7 @@ Standard_Boolean BuildShellsCompleteInter(const BOPCol_ListOfShape& theLF,
   aMV3.SetIntersect(Standard_False);
   aMV3.SetAvoidInternalShapes(Standard_True);
   aMV3.Perform();
-  bDone = (aMV3.ErrorStatus() == 0);
+  bDone = ! aMV3.HasErrors();
   if (!bDone) {
     return bDone;
   }
index 87702f2..221226c 100644 (file)
@@ -1172,7 +1172,7 @@ void IntersectTrimmedEdges(const TopTools_ListOfShape& theLF,
   BOPAlgo_Builder aGFE;
   aGFE.SetArguments(aLS);
   aGFE.Perform();
-  if (aGFE.ErrorStatus()) {
+  if (aGFE.HasErrors()) {
     return;
   }
   //
@@ -1363,7 +1363,7 @@ void BuildSplitsOfTrimmedFace(const TopoDS_Face& theFace,
   aGF.AddArgument(theFace);
   aGF.AddArgument(theEdges);
   aGF.Perform();
-  if (aGF.ErrorStatus()) {
+  if (aGF.HasErrors()) {
     return;
   }
   //
@@ -4833,7 +4833,7 @@ void IntersectAndTrimEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theF
   BOPAlgo_Builder aGF;
   aGF.SetArguments(aLArgs);
   aGF.Perform();
-  if (aGF.ErrorStatus()) {
+  if (aGF.HasErrors()) {
     return;
   }
   //
@@ -4902,7 +4902,7 @@ void IntersectAndTrimEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theF
   aGFCE.AddArgument(aCEIm);
   aGFCE.Perform();
   //
-  if (aGFCE.ErrorStatus()) {
+  if (aGFCE.HasErrors()) {
     return;
   }
   //
@@ -5324,7 +5324,7 @@ void TrimNewIntersectionEdges(const TopTools_ListOfShape& theLE,
       aMV.Add(aV2);
       //
       aGFE.Perform();
-      if (!aGFE.ErrorStatus()) {
+      if (!aGFE.HasErrors()) {
         // get images of bounding vertices to remove splits containing them
         // in case some of the bounding edges has been interfered
         // during operation it is necessary to update their images as well
@@ -5415,7 +5415,7 @@ void IntersectEdges(const BOPCol_ListOfShape& theLA,
   BOPAlgo_Builder aGFA;
   aGFA.SetArguments(theLA);
   aGFA.Perform();
-  if (aGFA.ErrorStatus()) {
+  if (aGFA.HasErrors()) {
     // just copy input to the result
     TopoDS_Compound aSp;
     BRep_Builder aBB;
index 3945720..50eadac 100644 (file)
@@ -169,7 +169,7 @@ const TopoDS_Shape& BRepOffsetAPI_DraftAngle::ProblematicShape () const
 
 
 //=======================================================================
-//function : ErrorStatus
+//function : Status
 //purpose  : 
 //=======================================================================
 
index d69a51a..7f5f4d1 100644 (file)
@@ -202,7 +202,7 @@ static Standard_Integer Loc(Draw_Interpretor& theCommands,
   }
 #endif
   BLoc.PerformResult();
-  if (!BLoc.ErrorStatus()) {
+  if (!BLoc.HasErrors()) {
 //    dout.Clear();
     DBRep::Set(a[1],BLoc.Shape());
     dout.Flush();
@@ -237,7 +237,7 @@ static Standard_Integer HOLE1(Draw_Interpretor& theCommands,
   }
 
   theHole.Build();
-  if (!theHole.ErrorStatus()) {
+  if (!theHole.HasErrors()) {
 //    dout.Clear();
     DBRep::Set(a[1],theHole.Shape());
     dout.Flush();
@@ -263,7 +263,7 @@ static Standard_Integer HOLE2(Draw_Interpretor& theCommands,
   theHole.PerformThruNext(Radius,WithControl);
 
   theHole.Build();
-  if (!theHole.ErrorStatus()) {
+  if (!theHole.HasErrors()) {
 //    dout.Clear();
     DBRep::Set(a[1],theHole.Shape());
     dout.Flush();
@@ -288,7 +288,7 @@ static Standard_Integer HOLE3(Draw_Interpretor& theCommands,
   theHole.Init(S,gp_Ax1(Or,Di));
   theHole.PerformUntilEnd(Radius,WithControl);
   theHole.Build();
-  if (!theHole.ErrorStatus()) {
+  if (!theHole.HasErrors()) {
 //    dout.Clear();
     DBRep::Set(a[1],theHole.Shape());
     dout.Flush();
@@ -315,7 +315,7 @@ static Standard_Integer HOLE4(Draw_Interpretor& theCommands,
   theHole.Init(S,gp_Ax1(Or,Di));
   theHole.PerformBlind(Radius,Length,WithControl);
   theHole.Build();
-  if (!theHole.ErrorStatus()) {
+  if (!theHole.HasErrors()) {
 //    dout.Clear();
     DBRep::Set(a[1],theHole.Shape());
     dout.Flush();
index 1f4d76f..d9c2737 100644 (file)
@@ -352,7 +352,7 @@ Standard_Integer boptopoblend(Draw_Interpretor& di, Standard_Integer narg, const
   theDSFiller.SetArguments(aLS);
   //
   theDSFiller.Perform();
-  if (theDSFiller.ErrorStatus()) {
+  if (theDSFiller.HasErrors()) {
     printf("Check types of the arguments, please\n");
     return 1;
   }
@@ -367,7 +367,7 @@ Standard_Integer boptopoblend(Draw_Interpretor& di, Standard_Integer narg, const
   Standard_Boolean anIsDone = pBuilder->IsDone();
   if (!anIsDone)
   {
-    printf("boolean operation not done ErrorStatus()=%d\n", pBuilder->ErrorStatus());
+    printf("boolean operation not done HasErrors()=%d\n", pBuilder->HasErrors());
     return 1;
   }
 
index a94d9f0..a19626a 100755 (executable)
@@ -35,3 +35,8 @@ Message_SequenceOfPrinters.hxx
 Message_SequenceOfProgressScale.hxx
 Message_Status.hxx
 Message_StatusType.hxx
+Message_Alert.cxx
+Message_Alert.hxx
+Message_ListOfAlert.hxx
+Message_Report.cxx
+Message_Report.hxx
diff --git a/src/Message/Message_Alert.cxx b/src/Message/Message_Alert.cxx
new file mode 100644 (file)
index 0000000..5901a49
--- /dev/null
@@ -0,0 +1,50 @@
+// Created on: 2017-06-26
+// Created by: Andrey Betenev
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Message_Alert.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Message_Alert,Standard_Transient)
+
+//=======================================================================
+//function : GetMessageKey
+//purpose  :
+//=======================================================================
+
+Standard_CString Message_Alert::GetMessageKey () const
+{
+  return DynamicType()->Name();
+}
+
+//=======================================================================
+//function : SupportsMerge
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean Message_Alert::SupportsMerge () const
+{
+  // by default, support merge
+  return Standard_True;
+}
+
+//=======================================================================
+//function : Merge
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean Message_Alert::Merge (const Handle(Message_Alert)& /*theTarget*/)
+{
+  // by default, merge trivially
+  return Standard_True;
+}
diff --git a/src/Message/Message_Alert.hxx b/src/Message/Message_Alert.hxx
new file mode 100644 (file)
index 0000000..030efb0
--- /dev/null
@@ -0,0 +1,64 @@
+// Created on: 2017-06-26
+// Created by: Andrey Betenev
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Message_Alert_HeaderFile
+#define _Message_Alert_HeaderFile
+
+#include <Standard_Type.hxx>
+
+class Message_Alert;
+DEFINE_STANDARD_HANDLE(Message_Alert, MMgt_TShared)
+
+//! Base class of the hierarchy of classes describing various situations
+//! occurring during execution of some algorithm or procedure.
+//!
+//! Alert should provide unique text identifier that can be used to distinguish 
+//! particular type of alerts, e.g. to get text message string describing it. 
+//! See method GetMessageKey(); by default, dynamic type name is used.
+//!
+//! Alert can contain some data. To avoid duplication of data, new alert
+//! can be merged with another one of the same type. Method SupportsMerge() 
+//! should return true if merge is supported; method Merge() should do the
+//! merge if possible and return true in that case and false otherwise.
+//! 
+class Message_Alert : public Standard_Transient
+{
+public:
+
+  //! Return a C string to be used as a key for generating text user 
+  //! messages describing this alert.
+  //! The messages are generated with help of Message_Msg class, in
+  //! Message_Report::Dump().
+  //! Base implementation returns dynamic type name of the instance.
+  virtual Standard_EXPORT Standard_CString GetMessageKey () const;
+  
+  //! Return true if this type of alert can be merged with other
+  //! of the same type to avoid duplication.
+  //! Basis implementation returns true.
+  virtual Standard_EXPORT Standard_Boolean SupportsMerge () const;
+  
+  //! If possible, merge data contained in this alert to theTarget.
+  //! @return True if merged.
+  //! Base implementation always returns true.
+  virtual Standard_EXPORT Standard_Boolean Merge (const Handle(Message_Alert)& theTarget);
+  
+  // OCCT RTTI
+  DEFINE_STANDARD_RTTIEXT(Message_Alert,Standard_Transient)
+};
+
+//! Macro allowing to define simple alert (without data) in single line of code
+#define DEFINE_SIMPLE_ALERT(Alert) class Alert : public Message_Alert { DEFINE_STANDARD_RTTI_INLINE(Alert,Message_Alert) };
+
+#endif // _Message_Alert_HeaderFile
index 14847b3..34a69f7 100644 (file)
@@ -34,7 +34,7 @@
 IMPLEMENT_STANDARD_RTTIEXT(Message_Algorithm,MMgt_TShared)
 
 //=======================================================================
-//function : SetMessenger
+//function : Message_Algorithm
 //purpose  :
 //=======================================================================
 Message_Algorithm::Message_Algorithm ()
diff --git a/src/Message/Message_ListOfAlert.hxx b/src/Message/Message_ListOfAlert.hxx
new file mode 100644 (file)
index 0000000..3f25998
--- /dev/null
@@ -0,0 +1,24 @@
+// Created on: 2017-06-26
+// Created by: Andrey Betenev
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Message_ListOfAlert_HeaderFile
+#define _Message_ListOfAlert_HeaderFile
+
+#include <Message_Alert.hxx>
+#include <NCollection_List.hxx>
+
+typedef NCollection_List<Handle(Message_Alert)> Message_ListOfAlert;
+
+#endif // _Message_ListOfAlert_HeaderFile
diff --git a/src/Message/Message_Report.cxx b/src/Message/Message_Report.cxx
new file mode 100644 (file)
index 0000000..012c644
--- /dev/null
@@ -0,0 +1,250 @@
+// Created on: 2017-06-26
+// Created by: Andrey Betenev
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Message_Report.hxx>
+#include <Message_Msg.hxx>
+#include <Message_Messenger.hxx>
+#include <NCollection_Map.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Message_Report,Standard_Transient)
+
+//=======================================================================
+//function : Message_Report
+//purpose  :
+//=======================================================================
+
+Message_Report::Message_Report ()
+{
+}
+
+//=======================================================================
+//function : AddAlert
+//purpose  :
+//=======================================================================
+
+void Message_Report::AddAlert (Message_Gravity theGravity, const Handle(Message_Alert)& theAlert)
+{
+  Standard_ASSERT_RETURN (! theAlert.IsNull(), "Attempt to add null alert",);
+  Standard_ASSERT_RETURN (theGravity >= 0 && theGravity < sizeof(myAlerts)/sizeof(myAlerts[0]), 
+                          "Adding alert with gravity not in valid range",);
+
+  Standard_Mutex::Sentry aSentry (myMutex);
+
+  // iterate by already recorded alerts and try to merge new one with one of those
+  Message_ListOfAlert &aList = myAlerts[theGravity];
+  if (theAlert->SupportsMerge() && ! aList.IsEmpty())
+  {
+    // merge is performed only for alerts of exactly same type
+    const Handle(Standard_Type)& aType = theAlert->DynamicType();
+    for (Message_ListOfAlert::Iterator anIt(aList); anIt.More(); anIt.Next())
+    {
+      // if merged successfully, just return
+      if (aType == anIt.Value()->DynamicType() && theAlert->Merge (anIt.Value()))
+        return;
+    }
+  }
+
+  // if not merged, just add to the list
+  aList.Append (theAlert);
+}
+
+//=======================================================================
+//function : GetAlerts
+//purpose  :
+//=======================================================================
+
+const Message_ListOfAlert& Message_Report::GetAlerts (Message_Gravity theGravity) const
+{
+  static const Message_ListOfAlert anEmptyList;
+  Standard_ASSERT_RETURN (theGravity >= 0 && theGravity < sizeof(myAlerts)/sizeof(myAlerts[0]), 
+                          "Requesting alerts for gravity not in valid range", anEmptyList);
+  return myAlerts[theGravity];
+}
+
+//=======================================================================
+//function : HasAlert
+//purpose  :
+//=======================================================================
+
+Standard_Boolean Message_Report::HasAlert (const Handle(Standard_Type)& theType)
+{
+  for (int iGravity = Message_Trace; iGravity <= Message_Fail; ++iGravity)
+  {
+    if (HasAlert (theType, (Message_Gravity)iGravity))
+      return Standard_True;
+  }
+  return Standard_False;
+}
+
+//=======================================================================
+//function : HasAlert
+//purpose  :
+//=======================================================================
+
+Standard_Boolean Message_Report::HasAlert (const Handle(Standard_Type)& theType, Message_Gravity theGravity)
+{
+  Standard_ASSERT_RETURN (theGravity >= 0 && theGravity < sizeof(myAlerts)/sizeof(myAlerts[0]), 
+                          "Requesting alerts for gravity not in valid range", Standard_False);
+  for (Message_ListOfAlert::Iterator anIt (myAlerts[theGravity]); anIt.More(); anIt.Next())
+  {
+    if (anIt.Value()->IsInstance(theType))
+      return Standard_True;
+  }
+  return Standard_False;
+}
+
+//=======================================================================
+//function : Clear
+//purpose  :
+//=======================================================================
+
+void Message_Report::Clear ()
+{
+  for (unsigned int i = 0; i < sizeof(myAlerts)/sizeof(myAlerts[0]); ++i)
+  {
+    myAlerts[i].Clear();
+  }
+}
+
+//=======================================================================
+//function : Clear
+//purpose  :
+//=======================================================================
+
+void Message_Report::Clear (Message_Gravity theGravity)
+{
+  Standard_ASSERT_RETURN (theGravity >= 0 && theGravity < sizeof(myAlerts)/sizeof(myAlerts[0]), 
+                          "Requesting alerts for gravity not in valid range", );
+  myAlerts[theGravity].Clear();
+}
+
+//=======================================================================
+//function : Clear
+//purpose  :
+//=======================================================================
+
+void Message_Report::Clear (const Handle(Standard_Type)& theType)
+{
+  for (unsigned int i = 0; i < sizeof(myAlerts)/sizeof(myAlerts[0]); ++i)
+  {
+    for (Message_ListOfAlert::Iterator anIt (myAlerts[i]); anIt.More(); )
+    {
+      if (anIt.Value().IsNull() || anIt.Value()->IsInstance (theType))
+      {
+        myAlerts[i].Remove (anIt);
+      }
+      else
+      {
+        anIt.More();
+      }
+    }
+  }
+}
+
+//=======================================================================
+//function : Dump
+//purpose  :
+//=======================================================================
+
+void Message_Report::Dump (Standard_OStream& theOS)
+{
+  for (int iGravity = Message_Trace; iGravity <= Message_Fail; ++iGravity)
+  {
+    Dump (theOS, (Message_Gravity)iGravity);
+  }
+}
+
+//=======================================================================
+//function : Dump
+//purpose  :
+//=======================================================================
+
+void Message_Report::Dump (Standard_OStream& theOS, Message_Gravity theGravity)
+{
+  Standard_ASSERT_RETURN (theGravity >= 0 && theGravity < sizeof(myAlerts)/sizeof(myAlerts[0]), 
+                          "Requesting alerts for gravity not in valid range", );
+
+  // report each type of warning only once
+  NCollection_Map<Handle(Standard_Type)> aPassedAlerts;
+  for (Message_ListOfAlert::Iterator anIt (myAlerts[theGravity]); anIt.More(); anIt.Next())
+  {
+    if (aPassedAlerts.Add (anIt.Value()->DynamicType()))
+    {
+      Message_Msg aMsg (anIt.Value()->GetMessageKey());
+      theOS << aMsg.Original() << std::endl;
+    }
+  }
+}
+
+//=======================================================================
+//function : Dump
+//purpose  :
+//=======================================================================
+
+void Message_Report::SendMessages (const Handle(Message_Messenger)& theMessenger)
+{
+  for (int iGravity = Message_Trace; iGravity <= Message_Fail; ++iGravity)
+  {
+    SendMessages (theMessenger, (Message_Gravity)iGravity);
+  }
+}
+
+//=======================================================================
+//function : Dump
+//purpose  :
+//=======================================================================
+
+void Message_Report::SendMessages (const Handle(Message_Messenger)& theMessenger, Message_Gravity theGravity)
+{
+  Standard_ASSERT_RETURN (theGravity >= 0 && theGravity < sizeof(myAlerts)/sizeof(myAlerts[0]), 
+                          "Requesting alerts for gravity not in valid range", );
+
+  // report each type of warning only once
+  NCollection_Map<Handle(Standard_Type)> aPassedAlerts;
+  for (Message_ListOfAlert::Iterator anIt (myAlerts[theGravity]); anIt.More(); anIt.Next())
+  {
+    if (aPassedAlerts.Add (anIt.Value()->DynamicType()))
+    {
+      Message_Msg aMsg (anIt.Value()->GetMessageKey());
+      theMessenger->Send (aMsg, theGravity);
+    }
+  }
+}
+
+//=======================================================================
+//function : Merge
+//purpose  :
+//=======================================================================
+
+void Message_Report::Merge (const Handle(Message_Report)& theOther)
+{
+  for (int iGravity = Message_Trace; iGravity <= Message_Fail; ++iGravity)
+  {
+    Merge (theOther, (Message_Gravity)iGravity);
+  }
+}
+
+//=======================================================================
+//function : Merge
+//purpose  :
+//=======================================================================
+
+void Message_Report::Merge (const Handle(Message_Report)& theOther, Message_Gravity theGravity)
+{
+  for (Message_ListOfAlert::Iterator anIt (theOther->GetAlerts(theGravity)); anIt.More(); anIt.Next())
+  {
+    AddAlert (theGravity, anIt.Value());
+  }
+}
diff --git a/src/Message/Message_Report.hxx b/src/Message/Message_Report.hxx
new file mode 100644 (file)
index 0000000..8440ba8
--- /dev/null
@@ -0,0 +1,108 @@
+// Created on: 2017-06-26
+// Created by: Andrey Betenev
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Message_Report_HeaderFile
+#define _Message_Report_HeaderFile
+
+#include <Message_Gravity.hxx>
+#include <Message_ListOfAlert.hxx>
+#include <Standard_Mutex.hxx>
+
+class Message_Messenger;
+
+class Message_Report;
+DEFINE_STANDARD_HANDLE(Message_Report, MMgt_TShared)
+
+//! Container for alert messages, sorted according to their gravity.
+//! 
+//! For each gravity level, alerts are stored in simple list.
+//! If alert being added can be merged with another alert of the same
+//! type already in the list, it is merged and not added to the list.
+//! 
+//! This class is intended to be used as follows:
+//!
+//! - In the process of execution, algorithm fills report by alert objects
+//!   using methods AddAlert()
+//!
+//! - The result can be queried for presence of particular alert using 
+//!   methods HasAlert()
+//!
+//! - The reports produced by nested or sequentially executed algorithms
+//!   can be collected in one using method Merge()
+//!
+//! - The report can be shown to the user either as plain text with method 
+//!   Dump() or in more advanced way, by iterating over lists returned by GetAlerts()
+//!
+//! - Report can be cleared by methods Clear() (usually after reporting)
+
+class Message_Report : public Standard_Transient
+{
+public:
+
+  //! Empty constructor
+  Standard_EXPORT Message_Report ();
+  
+  //! Add alert with specified gravity.
+  //! This method is thread-safe, i.e. alerts can be added from parallel threads safely.
+  Standard_EXPORT void AddAlert (Message_Gravity theGravity, const Handle(Message_Alert)& theAlert);
+
+  //! Returns list of collected alerts with specified gravity
+  Standard_EXPORT const Message_ListOfAlert& GetAlerts (Message_Gravity theGravity) const;
+
+  //! Returns true if specific type of alert is recorded
+  Standard_EXPORT Standard_Boolean HasAlert (const Handle(Standard_Type)& theType);
+
+  //! Returns true if specific type of alert is recorded with specified gravity
+  Standard_EXPORT Standard_Boolean HasAlert (const Handle(Standard_Type)& theType, Message_Gravity theGravity);
+
+  //! Clears all collected alerts
+  Standard_EXPORT void Clear ();
+
+  //! Clears collected alerts with specified gravity
+  Standard_EXPORT void Clear (Message_Gravity theGravity);
+
+  //! Clears collected alerts with specified type
+  Standard_EXPORT void Clear (const Handle(Standard_Type)& theType);
+
+  //! Dumps all collected alerts to stream
+  Standard_EXPORT void Dump (Standard_OStream& theOS);
+
+  //! Dumps collected alerts with specified gravity to stream
+  Standard_EXPORT void Dump (Standard_OStream& theOS, Message_Gravity theGravity);
+
+  //! Sends all collected alerts to messenger
+  Standard_EXPORT void SendMessages (const Handle(Message_Messenger)& theMessenger);
+
+  //! Dumps collected alerts with specified gravity to messenger
+  Standard_EXPORT void SendMessages (const Handle(Message_Messenger)& theMessenger, Message_Gravity theGravity);
+
+  //! Merges data from theOther report into this
+  Standard_EXPORT void Merge (const Handle(Message_Report)& theOther);
+
+  //! Merges alerts with specified gravity from theOther report into this
+  Standard_EXPORT void Merge (const Handle(Message_Report)& theOther, Message_Gravity theGravity);
+
+  // OCCT RTTI
+  DEFINE_STANDARD_RTTIEXT(Message_Report,Standard_Transient)
+
+protected:
+  Standard_Mutex myMutex;
+
+  // store messages in a lists sorted by gravity;
+  // here we rely on knowledge that Message_Fail is the last element of the enum
+  Message_ListOfAlert myAlerts[Message_Fail + 1];
+};
+
+#endif // _Message_Report_HeaderFile
index 33bd5aa..ded27c5 100644 (file)
@@ -193,7 +193,8 @@ public:
   void RemoveFirst (void) 
   { PRemoveFirst (ListNode::delNode); }
 
-  //! Remove item
+  //! Remove item pointed by iterator theIter; 
+  //! theIter is then set to the next item
   void Remove (Iterator& theIter) 
   { 
     PRemove (theIter, ListNode::delNode); 
index efe20de..0faa795 100644 (file)
@@ -2814,7 +2814,7 @@ static Standard_Integer OCC25446 (Draw_Interpretor& theDI,
   aPF.SetArguments(aLS);
   //
   aPF.Perform();
-  iErr = aPF.ErrorStatus();
+  iErr = aPF.HasErrors();
   if (iErr) {
     theDI << "Intersection failed with error status: " << iErr << "\n";
     return 1;
@@ -2842,7 +2842,7 @@ static Standard_Integer OCC25446 (Draw_Interpretor& theDI,
     break;
   }
   //
-  iErr = pBuilder->ErrorStatus();
+  iErr = pBuilder->HasErrors();
   if (!pBuilder->IsDone()) {
     theDI << "BOP failed with error status: " << iErr << "\n";
     return 1;
index cfb467e..13892f6 100644 (file)
@@ -60,3 +60,5 @@ TopoDS_Vertex.hxx
 TopoDS_Vertex.lxx
 TopoDS_Wire.hxx
 TopoDS_Wire.lxx
+TopoDS_AlertWithShape.cxx
+TopoDS_AlertWithShape.hxx
diff --git a/src/TopoDS/TopoDS_AlertWithShape.cxx b/src/TopoDS/TopoDS_AlertWithShape.cxx
new file mode 100644 (file)
index 0000000..38a7638
--- /dev/null
@@ -0,0 +1,52 @@
+// Created on: 2017-06-27
+// Created by: Andrey Betenev
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <TopoDS_AlertWithShape.hxx>
+
+#include <Message_Msg.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(TopoDS_AlertWithShape,Message_Alert)
+
+//=======================================================================
+//function : TopoDS_AlertWithShape
+//purpose  : 
+//=======================================================================
+
+TopoDS_AlertWithShape::TopoDS_AlertWithShape (const TopoDS_Shape& theShape)
+{
+  myShape = theShape;
+}
+
+//=======================================================================
+//function : SupportsMerge
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean TopoDS_AlertWithShape::SupportsMerge () const
+{
+  return Standard_False;
+}
+  
+//=======================================================================
+//function : Merge
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean TopoDS_AlertWithShape::Merge (const Handle(Message_Alert)& /*theTarget*/)
+{
+  return Standard_False;
+//  Handle(TopoDS_AlertWithShape) aTarget = Handle(TopoDS_AlertWithShape)::DownCast (theTarget);
+//  return aTarget->GetShape() == myShape;
+}
diff --git a/src/TopoDS/TopoDS_AlertWithShape.hxx b/src/TopoDS/TopoDS_AlertWithShape.hxx
new file mode 100644 (file)
index 0000000..602e5f9
--- /dev/null
@@ -0,0 +1,54 @@
+// Created on: 2017-06-27
+// Created by: Andrey Betenev
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _TopoDS_AlertWithShape_HeaderFile
+#define _TopoDS_AlertWithShape_HeaderFile
+
+#include <Message_Alert.hxx>
+#include <TopoDS_Shape.hxx>
+
+//! Alert object storing TopoDS shape in its field
+class TopoDS_AlertWithShape : public Message_Alert 
+{
+public:
+  //! Constructor with shape argument
+  Standard_EXPORT TopoDS_AlertWithShape (const TopoDS_Shape& theShape);
+
+  //! Returns contained shape
+  const TopoDS_Shape& GetShape() const { return myShape; }
+  
+  //! Returns false.
+  virtual Standard_EXPORT Standard_Boolean SupportsMerge () const Standard_OVERRIDE;
+
+  //! Returns false.
+  virtual Standard_EXPORT Standard_Boolean Merge (const Handle(Message_Alert)& theTarget) Standard_OVERRIDE;
+
+  // OCCT RTTI
+  DEFINE_STANDARD_RTTIEXT(TopoDS_AlertWithShape, Message_Alert)
+
+private:
+  TopoDS_Shape myShape;
+};
+
+//! Helper macro allowing to define alert with shape argument in one line of code
+#define DEFINE_ALERT_WITH_SHAPE(Alert) \
+  class Alert : public TopoDS_AlertWithShape \
+  { \
+  public:\
+    Alert (const TopoDS_Shape& theShape) : TopoDS_AlertWithShape(theShape) {} \
+    DEFINE_STANDARD_RTTI_INLINE(Alert, TopoDS_AlertWithShape) \
+  };
+
+#endif // _TopoDS_AlertWithShape_HeaderFile
index 4c3130a..2a2db57 100644 (file)
@@ -1,10 +1,16 @@
-puts "TODO #22911 ALL: Error: The command cannot be built"
-
 restore [locate_data_file OCC100_sp.brep] a
 restore [locate_data_file OCC100_cyl.brep] b
 
-bop b a
-bopcut result
+bclearobjects
+bcleartools
+baddobjects a b
+bfillds
+bcbuild rx
+
+# use Cells Builder to perform CUT Shell from the Solid
+bcadd result b 1 a 0
+
+checknbshapes result -shell 2 -solid 2 -face 5
+checkprops result -s 1309.65 -v 1256.64
 
-checkprops result -s 0
-checkview -display result -2d -otherwise { b a } -s -path ${imagedir}/${test_image}.png
+checkview -display result -2d -path ${imagedir}/${test_image}.png
index b151d71..48f925b 100644 (file)
@@ -1,11 +1,16 @@
-puts "TODO #22911 ALL: Error: The command cannot be built"
-cpulimit 1500
-
 restore [locate_data_file OCC228.brep] sh
 explode sh
 
-bop sh_1 sh_2
-bopcut result
+bclearobjects
+bcleartools
+baddobjects sh_1 sh_2
+bfillds
+bcbuild rx
+
+# use Cells Builder to perform CUT Shell from the Solid
+bcadd result sh_1 1 sh_2 0
+
+checknbshapes result -solid 1 -shell 2 -face 220
+checkprops result -s 289170 -v 8.06062e+006
 
-checkprops result -s 0
-checkview -display result -2d -otherwise { sh_1 sh_2 } -s -path ${imagedir}/${test_image}.png
+checkview -display result -2d -path ${imagedir}/${test_image}.png
index f44cb65..4202ef0 100644 (file)
@@ -1,10 +1,16 @@
-puts "TODO #22911 ALL: Error: The command cannot be built"
-
 restore [locate_data_file BUC60928.brep] sh
 explode sh
 
-bop sh_1 sh_2
-bopcut result
+bclearobjects
+bcleartools
+baddobjects sh_1 sh_2
+bfillds
+bcbuild rx
+
+# use Cells Builder to perform CUT Shell from the Solid
+bcadd result sh_1 1 sh_2 0
+
+checknbshapes result -solid 3 -shell 3 -face 14
+checkprops result -s 190481 -v 1.23285e+006
 
-checkprops result -s 0
-checkview -display result -2d -otherwise { sh_1 sh_2 } -s -path ${imagedir}/${test_image}.png
+checkview -display result -2d -path ${imagedir}/${test_image}.png
index e086269..8dc1efd 100644 (file)
@@ -1,10 +1,16 @@
-puts "TODO #22911 ALL: Error: The command cannot be built"
-
 restore [locate_data_file BUC60931.brep] sh
 explode sh
 
-bop sh_2 sh_1
-bopcut result
+bclearobjects
+bcleartools
+baddobjects sh_1 sh_2
+bfillds
+bcbuild rx
+
+# use Cells Builder to perform CUT Shell from the Solid
+bcadd result sh_2 1 sh_1 0
+
+checknbshapes result -solid 2 -shell 2 -face 457
+checkprops result -s 1.53759e+006 -v 5.02658e+006
 
-checkprops result -s 0
-checkview -display result -2d -otherwise { sh_2 sh_1 } -s -path ${imagedir}/${test_image}.png
+checkview -display result -2d -path ${imagedir}/${test_image}.png
index f2664fe..6257614 100644 (file)
@@ -1,10 +1,18 @@
-puts "TODO #22911 ALL: Error: The command cannot be built"
-
 restore [locate_data_file OCC100_sp.brep] a
 restore [locate_data_file OCC100_cyl.brep] b
 
-bop a b
-bopfuse result
+bclearobjects
+bcleartools
+baddobjects a b
+bfillds
+bcbuild rx
+
+# Use Cells Builder algorithm to Fuse Shell to Solid
+bcadd result b 1 -m 1 -u
+bcadd result a 1 b 0
+bcmakecontainers result
+
+checknbshapes result -solid 1 -shell 2 -face 8
+checkprops result -s 3411.98 -v 13511.3
 
-checkprops result -s 0
-checkview -display result -2d -otherwise { a b } -s -path ${imagedir}/${test_image}.png
+checkview -display result -2d -path ${imagedir}/${test_image}.png
index d1a0399..d829d9e 100644 (file)
@@ -1,10 +1,18 @@
-puts "TODO #22911 ALL: Error: The command cannot be built"
-
 restore [locate_data_file OCC100_sp.brep] a
 restore [locate_data_file OCC100_cyl.brep] b
 
-bop b a
-bopfuse result
+bclearobjects
+bcleartools
+baddobjects b a
+bfillds
+bcbuild rx
+
+# Use Cells Builder algorithm to Fuse Shell to Solid
+bcadd result b 1 -m 1 -u
+bcadd result a 1 b 0
+bcmakecontainers result
+
+checknbshapes result -solid 1 -shell 2 -face 8
+checkprops result -s 3411.98 -v 13511.3
 
-checkprops result -s 0
-checkview -display result -2d -otherwise { b a } -s -path ${imagedir}/${test_image}.png
+checkview -display result -2d -path ${imagedir}/${test_image}.png
index dff0a5f..7f8092e 100644 (file)
@@ -1,11 +1,18 @@
-puts "TODO #22911 ALL: Error: The command cannot be built"
-cpulimit 1500
-
 restore [locate_data_file OCC228.brep] sh
 explode sh
 
-bop sh_1 sh_2
-bopfuse result
+bclearobjects
+bcleartools
+baddobjects sh_1 sh_2
+bfillds
+bcbuild rx
+
+# Use Cells Builder algorithm to Fuse Shell to Solid
+bcadd result sh_1 1 -m 1 -u
+bcadd result sh_2 1 sh_1 0
+bcmakecontainers result
+
+checknbshapes result -solid 1 -shell 2 -face 220
+checkprops result -s 289170 -v 8.06062e+006
 
-checkprops result -s 0
-checkview -display result -2d -otherwise { sh_1 sh_2 } -s -path ${imagedir}/${test_image}.png
+checkview -display result -2d -path ${imagedir}/${test_image}.png
index 8317fd7..75a369e 100644 (file)
@@ -1,11 +1,18 @@
-puts "TODO #22911 ALL: Error: The command cannot be built"
-cpulimit 1500
-
 restore [locate_data_file OCC228.brep] sh
 explode sh
 
-bop sh_2 sh_1
-bopfuse result
+bclearobjects
+bcleartools
+baddobjects sh_2 sh_1
+bfillds
+bcbuild rx
+
+# Use Cells Builder algorithm to Fuse Shell to Solid
+bcadd result sh_1 1 -m 1 -u
+bcadd result sh_2 1 sh_1 0
+bcmakecontainers result
+
+checknbshapes result -solid 1 -shell 2 -face 220
+checkprops result -s 289170 -v 8.06062e+006
 
-checkprops result -s 0
-checkview -display result -2d -otherwise { sh_2 sh_1 } -s -path ${imagedir}/${test_image}.png
+checkview -display result -2d -path ${imagedir}/${test_image}.png
index fc92c80..630dc29 100644 (file)
@@ -1,10 +1,18 @@
-puts "TODO #22911 ALL: Error: The command cannot be built"
-
 restore [locate_data_file BUC60928.brep] sh
 explode sh
 
-bop sh_1 sh_2
-bopfuse result
+bclearobjects
+bcleartools
+baddobjects sh_1 sh_2
+bfillds
+bcbuild rx
+
+# Use Cells Builder algorithm to Fuse Shell to Solid
+bcadd result sh_1 1 -m 1 -u
+bcadd result sh_2 1 sh_1 0
+bcmakecontainers result
+
+checknbshapes result -solid 1 -shell 2 -face 10
+checkprops result -s 487710 -v 1.37052e+007
 
-checkprops result -s 0
-checkview -display result -2d -otherwise { sh_1 sh_2 } -s -path ${imagedir}/${test_image}.png
+checkview -display result -2d -path ${imagedir}/${test_image}.png
index 006451f..35fde8e 100644 (file)
@@ -1,10 +1,18 @@
-puts "TODO #22911 ALL: Error: The command cannot be built"
-
 restore [locate_data_file BUC60928.brep] sh
 explode sh
 
-bop sh_2 sh_1
-bopfuse result
+bclearobjects
+bcleartools
+baddobjects sh_2 sh_1
+bfillds
+bcbuild rx
+
+# Use Cells Builder algorithm to Fuse Shell to Solid
+bcadd result sh_1 1 -m 1 -u
+bcadd result sh_2 1 sh_1 0
+bcmakecontainers result
+
+checknbshapes result -solid 1 -shell 2 -face 10
+checkprops result -s 487710 -v 1.37052e+007
 
-checkprops result -s 0
-checkview -display result -2d -otherwise { sh_2 sh_1 } -s -path ${imagedir}/${test_image}.png
+checkview -display result -2d -path ${imagedir}/${test_image}.png
index f2e2c24..bd6ac2e 100644 (file)
@@ -1,10 +1,18 @@
-puts "TODO #22911 ALL: Error: The command cannot be built"
-
 restore [locate_data_file BUC60931.brep] sh
 explode sh
 
-bop sh_1 sh_2
-bopfuse result
+bclearobjects
+bcleartools
+baddobjects sh_1 sh_2
+bfillds
+bcbuild rx
+
+# Use Cells Builder algorithm to Fuse Shell to Solid
+bcadd result sh_2 1 -m 1 -u
+bcadd result sh_1 1 sh_2 0
+bcmakecontainers result
+
+checknbshapes result -solid 1 -shell 8 -face 466
+checkprops result -s 1.72392e+006 -v 7.37003e+006
 
-checkprops result -s 0
-checkview -display result -2d -otherwise { sh_1 sh_2 } -s -path ${imagedir}/${test_image}.png
+checkview -display result -2d -path ${imagedir}/${test_image}.png
index 6e5b8d7..8584c79 100644 (file)
@@ -1,10 +1,18 @@
-puts "TODO #22911 ALL: Error: The command cannot be built"
-
 restore [locate_data_file BUC60931.brep] sh
 explode sh
 
-bop sh_2 sh_1
-bopfuse result
+bclearobjects
+bcleartools
+baddobjects sh_2 sh_1
+bfillds
+bcbuild rx
+
+# Use Cells Builder algorithm to Fuse Shell to Solid
+bcadd result sh_2 1 -m 1 -u
+bcadd result sh_1 1 sh_2 0
+bcmakecontainers result
+
+checknbshapes result -solid 1 -shell 8 -face 466
+checkprops result -s 1.72392e+006 -v 7.37003e+006
 
-checkprops result -s 0
-checkview -display result -2d -otherwise { sh_2 sh_1 } -s -path ${imagedir}/${test_image}.png
+checkview -display result -2d -path ${imagedir}/${test_image}.png
index 747af1c..797460c 100755 (executable)
@@ -1,6 +1,4 @@
-puts "TODO OCC12345 ALL: Tcl Exception: result is not a topological shape!!!"
-puts "TODO OCC12345 ALL: Error: The command cannot be built"
-puts "TODO OCC12345 ALL: TEST INCOMPLETE"
+puts "REQUIRED All: Boolean operation of the given type is not allowed on the given inputs"
 
 puts "========"
 puts "OCC726"
@@ -17,7 +15,3 @@ checkshape a_1
 checkshape a_2
 
 bcut result a_2 a_1
-
-checkprops result -s 10 
-checkshape result
-checkview -display result -2d -path ${imagedir}/${test_image}.png
index b0d094e..8953e20 100644 (file)
@@ -1,8 +1,3 @@
-puts "TODO OCC28786 ALL: Faulty shapes in variables faulty_1"
-#puts "TODO OCC28786 ALL: Error : The area of result shape is"
-#puts "TODO OCC28786 ALL: Error : The volume of result shape is"
-puts "TODO OCC28786 ALL: Error :  is WRONG because number of"
-
 puts "========"
 puts "0027448: BOPTools_AlgoTools::IsMicroEdge does not correspond to shape validity criteria"
 puts "Problem with Boolean CUT operation"
@@ -11,8 +6,6 @@ puts ""
 
 restore [locate_data_file bug27448_gdml_ZF6.brep] b
 explode b
-bcut result b_1 b_2
-checkshape result
-checknbshapes result -solid 1
-checkprops result -s 38.0808
-checkprops result -v 9.95429
+if {![regexp "Warning" [bcut result b_1 b_2]]} {
+  puts "Error: WarningStatus has not been set"
+}
diff --git a/tests/bugs/modalg_7/bug28786_1 b/tests/bugs/modalg_7/bug28786_1
new file mode 100644 (file)
index 0000000..7ae67be
--- /dev/null
@@ -0,0 +1,15 @@
+puts "REQUIRED All: Boolean operation of the given type is not allowed on the given inputs"
+
+puts "========"
+puts "OCC28786"
+puts "========"
+puts ""
+########################################
+# Refactoring of the Warning/Error reporting system of Boolean Operations Algorithm
+########################################
+
+restore [locate_data_file OCC100_sp.brep] a
+restore [locate_data_file OCC100_cyl.brep] b
+
+# incompatible shapes for fuse operation
+bfuse r a b
\ No newline at end of file
diff --git a/tests/bugs/modalg_7/bug28786_2 b/tests/bugs/modalg_7/bug28786_2
new file mode 100644 (file)
index 0000000..2ce3b1f
--- /dev/null
@@ -0,0 +1,29 @@
+puts "========"
+puts "OCC28786"
+puts "========"
+puts ""
+########################################
+# Refactoring of the Warning/Error reporting system of Boolean Operations Algorithm
+########################################
+
+plane p1 0 0 0 1 0 0
+mkface f1 p1 -10 10 -10 10
+plane p2 0 0 0 1 0 1
+mkface f2 p2 -10 10 -10 10
+compound f1 f2 a
+
+line l 0 0 0 0 1 0
+mkedge b l -11 11
+
+bclearobjects
+bcleartools
+baddobjects a
+baddtools b
+
+if {![regexp "Warning" [bfillds]]} {
+  puts "Error: WarningStatus has not been set"
+}
+
+bbuild result
+checkshape result
+checknbshapes result -face 4 -edge 15
diff --git a/tests/bugs/modalg_7/bug28786_3 b/tests/bugs/modalg_7/bug28786_3
new file mode 100644 (file)
index 0000000..2259c61
--- /dev/null
@@ -0,0 +1,32 @@
+puts "========"
+puts "OCC28786"
+puts "========"
+puts ""
+########################################
+# Refactoring of the Warning/Error reporting system of Boolean Operations Algorithm
+########################################
+
+vertex v 0 0 0
+vertex v1 10 0 0
+vertex v2 0 0 -3
+vertex v3 5 0 0
+edge e1 v v1
+edge e2 v2 v3
+compound e1 e2 a
+
+vertex v4 5 0 5
+vertex v5 5 0 -5
+edge b v4 v5
+
+bclearobjects
+bcleartools
+baddobjects a
+baddtools b
+
+if {![regexp "Warning" [bfillds]]} {
+  puts "Error: WarningStatus has not been set"
+}
+
+bbuild result
+checkshape result
+checknbshapes result -edge 5
diff --git a/tests/bugs/modalg_7/bug28786_4 b/tests/bugs/modalg_7/bug28786_4
new file mode 100644 (file)
index 0000000..6bff9f2
--- /dev/null
@@ -0,0 +1,27 @@
+puts "========"
+puts "OCC28786"
+puts "========"
+puts ""
+########################################
+# Refactoring of the Warning/Error reporting system of Boolean Operations Algorithm
+########################################
+
+vertex v 0 0 0
+vertex v1 1.e-5 0 0
+settolerance v1 1.e-5
+vertex v2 0 1.e-5 0
+edge a v v1
+edge b v v2
+
+bclearobjects
+bcleartools
+baddobjects a
+baddtools b
+
+if {![regexp "Warning" [bfillds]]} {
+  puts "Error: WarningStatus has not been set"
+}
+
+bbuild result
+checkshape result
+checknbshapes result -edge 2
diff --git a/tests/bugs/modalg_7/bug28786_5 b/tests/bugs/modalg_7/bug28786_5
new file mode 100644 (file)
index 0000000..cd23bfe
--- /dev/null
@@ -0,0 +1,30 @@
+puts "========"
+puts "OCC28786"
+puts "========"
+puts ""
+########################################
+# Refactoring of the Warning/Error reporting system of Boolean Operations Algorithm
+########################################
+
+vertex v 0 0 0
+vertex v1 10 0 0
+edge e1 v v1
+edge e2 v v1
+compound e1 e2 a
+
+vertex v3 -5 0 0
+vertex v4 15 0 0
+edge b v3 v4
+
+bclearobjects
+bcleartools
+baddobjects a
+baddtools b
+
+if {![regexp "Warning" [bfillds]]} {
+  puts "Error: WarningStatus has not been set"
+}
+
+bbuild result
+checkshape result
+checknbshapes result -edge 3