From: eap Date: Wed, 10 Dec 2014 16:07:28 +0000 (+0300) Subject: 22752: [EDF] Provide explicit feedback on what has been done by Shape Processing... X-Git-Tag: V7_6_0a1~60^2~20 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=ed87a1f7c81ec39992aff1f463d73dc81e5791e0;p=modules%2Fgeom.git 22752: [EDF] Provide explicit feedback on what has been done by Shape Processing operation + 22757: [EDF] Vertex on Edge --- allow projecting several points at once --- diff --git a/doc/salome/examples/repairing_operations_ex10.py b/doc/salome/examples/repairing_operations_ex10.py index c2dbc160f..6b8e4280e 100644 --- a/doc/salome/examples/repairing_operations_ex10.py +++ b/doc/salome/examples/repairing_operations_ex10.py @@ -33,10 +33,11 @@ for point in edge_points: # Variant 2: using DivideEdgeByPoint() box = geompy.MakeBox(0,0,0, 10,10,10, theName="box") -p = geompy.MakeVertex( 3, -2, 1, theName="point to project" ) -edge = geompy.GetEdgeNearPoint( box, p, theName="edge to split") +p1 = geompy.MakeVertex( 3, -2, 1, theName="point 1 to project" ) +p2 = geompy.MakeVertex( 7, -2, 1, theName="point 2 to project" ) +edge = geompy.GetEdgeNearPoint( box, p1, theName="edge to split") -div = geompy.DivideEdgeByPoint( box, edge, p, theName="box (edge divided)") +div = geompy.DivideEdgeByPoint( box, edge, [p1, p2], theName="box (edge divided)") salome.sg.updateObjBrowser(1) diff --git a/doc/salome/gui/GEOM/images/divedgebypoint.png b/doc/salome/gui/GEOM/images/divedgebypoint.png index cb80833cd..4258a1657 100644 Binary files a/doc/salome/gui/GEOM/images/divedgebypoint.png and b/doc/salome/gui/GEOM/images/divedgebypoint.png differ diff --git a/doc/salome/gui/GEOM/images/repair8.png b/doc/salome/gui/GEOM/images/repair8.png index 5c30a9760..c15f31345 100644 Binary files a/doc/salome/gui/GEOM/images/repair8.png and b/doc/salome/gui/GEOM/images/repair8.png differ diff --git a/doc/salome/gui/GEOM/input/add_point_on_edge_operation.doc b/doc/salome/gui/GEOM/input/add_point_on_edge_operation.doc index 587f1b968..187cefbcd 100644 --- a/doc/salome/gui/GEOM/input/add_point_on_edge_operation.doc +++ b/doc/salome/gui/GEOM/input/add_point_on_edge_operation.doc @@ -5,7 +5,7 @@ \n To Add Point on Edge in the Main Menu select Repair - > Add Point on Edge. -This operation splits an edge in two new edges. +This operation splits an edge in two or more new edges. This operation is available in OCC Viewer only. The \b Result will be a \b GEOM_Object. @@ -41,17 +41,17 @@ The \b Result will be a \b GEOM_Object. \image html repair8.png \n\n -
  • We can select a point that will be projected to the selected - edge to find the location of the new vertex. +
  • We can select several points that will be projected to the selected + edge to find the location of new vertices.

    - TUI Command: geompy.DivideEdgeByPoint(Shape, Edge, Point) + TUI Command: geompy.DivideEdgeByPoint(Shape, Edge, Points)

    - \b Arguments: Name + 1 Edge + 1 Point. + \b Arguments: Name + 1 Edge + 1 or more Points. \image html divedgebypoint.png diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index 0880b9fd6..dc9cf2f92 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -205,7 +205,6 @@ module GEOM SI_ALL // all interferences }; - /*! * \brief Object creation parameters * @@ -214,7 +213,6 @@ module GEOM struct Parameter { string name; - //any value; string value; }; typedef sequence Parameters; @@ -225,6 +223,16 @@ module GEOM Parameters params; }; + /*! + * \brief Reporting on shape healing + */ + struct ModifInfo + { + string name; // what changed + long count; // how many times + }; + typedef sequence ModifStatistics; + typedef sequence string_array; typedef sequence short_array; @@ -2042,7 +2050,7 @@ module GEOM * \param theEdges List of edges for gluing. * \return New GEOM_Object containing copies of theShapes without some edges. */ - GEOM_Object MakeGlueEdgesByList (in ListOfGO theShape, + GEOM_Object MakeGlueEdgesByList (in ListOfGO theShapes, in double theTolerance, in ListOfGO theEdges); @@ -3785,7 +3793,7 @@ module GEOM /*! * Sewing of the given object. - * \param theObject Shape to be processed. + * \param theObjects Shapes to be processed. * \param theTolerance Required tolerance value. * \return New GEOM_Object, containing processed shape. */ @@ -3793,7 +3801,7 @@ module GEOM /*! * Sewing of the given object. Allows non-manifold sewing. - * \param theObject Shape to be processed. + * \param theObjects Shapes to be processed. * \param theTolerance Required tolerance value. * \return New GEOM_Object, containing processed shape. */ @@ -3822,17 +3830,17 @@ module GEOM in double theValue, in boolean isByParameter); /*! - * \brief Addition of a point to a given edge of \a theObject by projecting - * another point to the given edge. + * \brief Addition of points to a given edge of \a theObject by projecting + * other points to the given edge. * \param theObject Shape to be processed. * \param theEdgeIndex Index of edge to be divided within theObject's shape, * if -1, then theObject itself is the edge. - * \param thePoint Point to project to theEdgeIndex-th edge. + * \param thePoints Points to project to theEdgeIndex-th edge. * \return New GEOM_Object, containing the processed shape. */ GEOM_Object DivideEdgeByPoint (in GEOM_Object theObject, in short theEdgeIndex, - in GEOM_Object thePoint); + in ListOfGO thePoints); /*! * \brief Suppress the vertices in the wire in case if adjacent edges are C1 continuous. @@ -3846,13 +3854,13 @@ module GEOM /*! * \brief Get a list of wires (wrapped in GEOM_Object-s), - * that constitute a free boundary of the given shape. - * \param theObject Shapes to get free boundary of. + * that constitute a free boundary of the given shapes. + * \param theObjects Shapes to get free boundary of. * \param theClosedWires Output. Closed wires on the free boundary of the given shape. * \param theOpenWires Output. Open wires on the free boundary of the given shape. * \return FALSE, if an error(s) occured during the method execution. */ - boolean GetFreeBoundary (in ListOfGO theObjects, + boolean GetFreeBoundary (in ListOfGO theObjects, out ListOfGO theClosedWires, out ListOfGO theOpenWires); @@ -3872,6 +3880,12 @@ module GEOM */ GEOM_Object LimitTolerance (in GEOM_Object theObject, in double theTolerance); + + /*! + * \brief Return information on what has been done by the last called healing method. + * \return ModifStatistics, information container. + */ + ModifStatistics GetStatistics(); }; // # GEOM_IInsertOperations: diff --git a/src/GEOM/GEOM_Function.cxx b/src/GEOM/GEOM_Function.cxx index 458e0a0bc..e96a3a52c 100644 --- a/src/GEOM/GEOM_Function.cxx +++ b/src/GEOM/GEOM_Function.cxx @@ -62,6 +62,8 @@ #include #include +#include + #include #include // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC @@ -76,6 +78,7 @@ #define HISTORY_LABEL 4 #define SUBSHAPES_LABEL 5 // 0020756: GetGroups #define NAMING_LABEL 6 // 0020750: Naming during STEP import +#define CALLBACK_LABEL 1 // TDataStd_Comment #ifdef KEEP_ORIENTATION_0021251 #define ORIENTATION_LABEL 7 // 0021251: TNaming_NamedShape doesn't store orientation @@ -124,7 +127,7 @@ Handle(GEOM_Function) GEOM_Function::GetFunction(const TDF_Label& theEntry) */ //============================================================================= GEOM_Function::GEOM_Function(const TDF_Label& theEntry, const Standard_GUID& theGUID, int theType) -: _label(theEntry) + : _label(theEntry), _isCallBackData(false) { TFunction_Function::Set(theEntry, theGUID); TDataStd_Integer::Set(theEntry, theType); @@ -139,6 +142,21 @@ GEOM_Function::GEOM_Function(const TDF_Label& theEntry, const Standard_GUID& the aRoot->Append(aNode); } +//================================================================================ +/*! + * \brief + * + * + */ +//================================================================================ + +GEOM_Function::~GEOM_Function() +{ + if ( _isCallBackData ) { + _label.FindChild( CALLBACK_LABEL ).ForgetAttribute( TDataStd_Comment::GetID() ); + } +} + //================================================================================ /*! * \brief Retuns true if this function is the last one in the study @@ -928,5 +946,45 @@ TDF_Label GEOM_Function::GetNamingEntry (const Standard_Boolean create) return _label.FindChild(NAMING_LABEL, create); } +//================================================================================ +/*! + * Save a pointer to a data holder intended to pass temporary data Driver -> Operation. + * This method should be called by Operation to set the data holder. + * An instance of GEOM_Function that sets the data holder will remove the + * corresponding OCAF attribute at it's destruction + */ +//================================================================================ + +void GEOM_Function::SetCallBackData( void* data ) +{ + std::ostringstream strm; + strm << (long long) data; + TCollection_ExtendedString string( strm.str().c_str() ); + + TDF_Label aChild = _label.FindChild(CALLBACK_LABEL); + TDataStd_Comment::Set(aChild, string); + + _isCallBackData = true; // I will remove TDataStd_Comment at destruction +} + +//================================================================================ +/*! + * Returns a pointer to a data holder intended to pass data Driver -> Operation. + * This method should be called by Driver to get the data holder to fill it in. + * Returns NULL if the Operation have not set the data holder. + */ +//================================================================================ + +void* GEOM_Function::GetCallBackData() +{ + Handle(TDataStd_Comment) aComment; + TDF_Label aChild = _label.FindChild( CALLBACK_LABEL ); + if(!aChild.FindAttribute(TDataStd_Comment::GetID(), aComment)) return NULL; + TCollection_AsciiString string( aComment->Get() ); + + long long address = atoll( string.ToCString() ); + return reinterpret_cast ( address ); +} + IMPLEMENT_STANDARD_HANDLE (GEOM_Function, Standard_Transient); IMPLEMENT_STANDARD_RTTIEXT(GEOM_Function, Standard_Transient ); diff --git a/src/GEOM/GEOM_Function.hxx b/src/GEOM/GEOM_Function.hxx index 688324dae..3d2a4ec96 100644 --- a/src/GEOM/GEOM_Function.hxx +++ b/src/GEOM/GEOM_Function.hxx @@ -56,7 +56,7 @@ public: Standard_EXPORT GEOM_Function(const TDF_Label& theEntry, const Standard_GUID& theGUID, int theType); - Standard_EXPORT ~GEOM_Function() {} + Standard_EXPORT ~GEOM_Function(); Standard_EXPORT TDF_Label GetOwnerEntry(); @@ -152,6 +152,17 @@ public: //Returns a list of references to other function arguments at position thePosition Standard_EXPORT Handle(TColStd_HSequenceOfTransient) GetReferenceList (int thePosition); + // Save a pointer to a data holder intended to pass data Driver -> Operation. + // This method should be called by Operation to set the data holder. + // An instance of GEOM_Function that sets the data holder will remove the + // corresponding OCAF attribute at it's destruction + Standard_EXPORT void SetCallBackData( void* data ); + + // Returns a pointer to a data holder intended to pass data Driver -> Operation. + // This method should be called by Driver to get the data holder to fill it in. + // Returns NULL if the Operation have not set the data holder. + Standard_EXPORT void* GetCallBackData(); + //Sets a TopoDS_Shape argument at position thePosition //void SetShape(int thePosition, const TopoDS_Shape& theShape); @@ -190,6 +201,7 @@ public: TDF_Label _label; bool _isDone; + bool _isCallBackData; }; #endif diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index b5e65a385..31679839b 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -44,7 +44,7 @@ Do you still want to delete these objects? DEVIDE_EDGE_BY_PROJ_POINT - Point to project + Points to project ERROR_SHAPE_TYPE @@ -569,7 +569,7 @@ Please, select face, shell or solid and try again GEOM_DIVIDE_EDGE_TITLE - Addition of point + Addition of points GEOM_DX @@ -5232,6 +5232,18 @@ shells and solids on the other hand. GEOM_NO_SHAPES_SELECTED There are no shapes that meet filtering parameters + + GEOM_HEALING_STATS_TITLE + What is done + + + GEOM_HEALING_STATS_COL_1 + Count + + + GEOM_HEALING_STATS_COL_2 + Modication + GeometryGUI diff --git a/src/GEOMImpl/CMakeLists.txt b/src/GEOMImpl/CMakeLists.txt index 3822d2912..42b467403 100755 --- a/src/GEOMImpl/CMakeLists.txt +++ b/src/GEOMImpl/CMakeLists.txt @@ -33,6 +33,7 @@ INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/src/SKETCHER ${PROJECT_SOURCE_DIR}/src/ARCHIMEDE ${PROJECT_SOURCE_DIR}/src/XAO + ${PROJECT_SOURCE_DIR}/src/ShHealOper ${CMAKE_CURRENT_SOURCE_DIR} ) diff --git a/src/GEOMImpl/GEOMImpl_HealingDriver.cxx b/src/GEOMImpl/GEOMImpl_HealingDriver.cxx index 48bca4095..51154eb63 100644 --- a/src/GEOMImpl/GEOMImpl_HealingDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_HealingDriver.cxx @@ -216,6 +216,8 @@ Standard_Boolean GEOMImpl_HealingDriver::ShapeProcess (GEOMImpl_IHealing* theHI, if (!aHealer.isDone()) raiseNotDoneExeption( ShHealOper_NotError ); + SaveStatistics( aHealer ); + return Standard_True; } @@ -223,9 +225,9 @@ Standard_Boolean GEOMImpl_HealingDriver::ShapeProcess (GEOMImpl_IHealing* theHI, //function : SupressFaces //purpose : //======================================================================= -void SuppressFacesRec (const TopTools_SequenceOfShape& theShapesFaces, - const TopoDS_Shape& theOriginalShape, - TopoDS_Shape& theOutShape) +void GEOMImpl_HealingDriver::SuppressFacesRec (const TopTools_SequenceOfShape& theShapesFaces, + const TopoDS_Shape& theOriginalShape, + TopoDS_Shape& theOutShape) const { if ((theOriginalShape.ShapeType() != TopAbs_COMPOUND && theOriginalShape.ShapeType() != TopAbs_COMPSOLID)) @@ -307,6 +309,21 @@ Standard_Boolean GEOMImpl_HealingDriver::SuppressFaces (GEOMImpl_IHealing* theHI theOutShape = GEOMImpl_GlueDriver::GlueFaces(aSh, Precision::Confusion(), Standard_True); } } + // count removed faces + TopTools_IndexedMapOfShape faces; + TopExp::MapShapes(theOriginalShape, TopAbs_FACE, faces); + int nbBefore = faces.Extent(); + faces.Clear(); + TopExp::MapShapes(theOutShape, TopAbs_FACE, faces); + int nbAfter = faces.Extent(); + + if ( nbAfter < nbBefore ) + { + ShHealOper_Tool tool; + ShHealOper_ModifStats& stats = tool.GetStatistics(); + stats.AddModif( "Face removed", nbBefore - nbAfter ); + SaveStatistics( tool ); + } return Standard_True; } @@ -347,6 +364,8 @@ Standard_Boolean GEOMImpl_HealingDriver::CloseContour (GEOMImpl_IHealing* theHI, else raiseNotDoneExeption( aHealer.GetErrorStatus() ); + SaveStatistics( aHealer ); + return aResult; } @@ -383,6 +402,8 @@ Standard_Boolean GEOMImpl_HealingDriver::RemoveIntWires (GEOMImpl_IHealing* theH else raiseNotDoneExeption( aHealer.GetErrorStatus() ); + SaveStatistics( aHealer ); + return aResult; } @@ -419,6 +440,8 @@ Standard_Boolean GEOMImpl_HealingDriver::RemoveHoles (GEOMImpl_IHealing* theHI, else raiseNotDoneExeption( aHealer.GetErrorStatus() ); + SaveStatistics( aHealer ); + return aResult; } @@ -464,6 +487,8 @@ Standard_Boolean GEOMImpl_HealingDriver::Sew (GEOMImpl_IHealing* theHI, else raiseNotDoneExeption( aHealer.GetErrorStatus() ); + SaveStatistics( aHealer ); + return aResult; } @@ -546,12 +571,21 @@ Standard_Boolean GEOMImpl_HealingDriver::AddPointOnEdge (GEOMImpl_IHealing* the { Handle(TColStd_HSequenceOfTransient) funs = theHI->GetShapes(); if ( !funs.IsNull() && funs->Length() > 0 ) { - Handle(GEOM_Function) fun = Handle(GEOM_Function)::DownCast( funs->Value(1) ); - if ( !fun.IsNull() ) - pointToProject = fun->GetValue(); + TopoDS_Compound vCompound; + BRep_Builder builder; + builder.MakeCompound( vCompound ); + pointToProject = vCompound; + for ( int ind = 1; ind <= funs->Length(); ind++) + { + Handle(GEOM_Function) vFun = Handle(GEOM_Function)::DownCast(funs->Value(ind)); + TopoDS_Shape vertex = vFun->GetValue(); + if ( vertex.IsNull() ) + Standard_NullObject::Raise("Null vertex given"); + builder.Add( vCompound, vertex ); + } } } - + ShHealOper_EdgeDivide aHealer (theOriginalShape); Standard_Boolean aResult = Standard_False; @@ -579,6 +613,8 @@ Standard_Boolean GEOMImpl_HealingDriver::AddPointOnEdge (GEOMImpl_IHealing* the else raiseNotDoneExeption( aHealer.GetErrorStatus() ); + SaveStatistics( aHealer ); + return aResult; } @@ -600,6 +636,8 @@ Standard_Boolean GEOMImpl_HealingDriver::ChangeOrientation (GEOMImpl_IHealing* t else raiseNotDoneExeption( aHealer.GetErrorStatus() ); + SaveStatistics( aHealer ); + return aResult; } @@ -617,9 +655,10 @@ void GEOMImpl_HealingDriver::LimitTolerance (GEOMImpl_IHealing* theHI, // 1. Make a copy to prevent the original shape changes. TopoDS_Shape aShapeCopy; - TColStd_IndexedDataMapOfTransientTransient aMapTShapes; - TNaming_CopyShape::CopyTool(theOriginalShape, aMapTShapes, aShapeCopy); - + { + TColStd_IndexedDataMapOfTransientTransient aMapTShapes; + TNaming_CopyShape::CopyTool(theOriginalShape, aMapTShapes, aShapeCopy); + } // 2. Limit tolerance. ShapeFix_ShapeTolerance aSFT; aSFT.LimitTolerance(aShapeCopy, aTol, aTol, TopAbs_SHAPE); @@ -632,6 +671,68 @@ void GEOMImpl_HealingDriver::LimitTolerance (GEOMImpl_IHealing* theHI, BRepCheck_Analyzer ana (theOutShape, Standard_True); if (!ana.IsValid()) StdFail_NotDone::Raise("Non valid shape result"); + + // 4. Collect statistics + { + ShHealOper_Tool tool; + ShHealOper_ModifStats& stats = tool.GetStatistics(); + + int nb[3] = { 0,0,0 }; + TopTools_IndexedMapOfShape aShapes; + TopExp::MapShapes( theOutShape, TopAbs_VERTEX, aShapes); + for ( int i = 1; i <= aShapes.Extent(); ++i ) + { + const TopoDS_Vertex& v = TopoDS::Vertex( aShapes( i )); + double tol = BRep_Tool::Tolerance( v ); + if ( tol < aTol ) nb[0]++; + else if ( tol > aTol ) nb[2]++; + else nb[1]++; + } + if ( nb[0] > 0 ) + stats.AddModif( "Tolerance of vertex decreased for shape validity", nb[0] ); + if ( nb[1] > 0 ) + stats.AddModif( "Tolerance of vertex limited as requested", nb[1] ); + if ( nb[2] > 0 ) + stats.AddModif( "Tolerance of vertex increased for shape validity", nb[2] ); + + nb[0] = nb[1] = nb[2] = 0; + aShapes.Clear(); + TopExp::MapShapes( theOutShape, TopAbs_EDGE, aShapes); + for ( int i = 1; i <= aShapes.Extent(); ++i ) + { + const TopoDS_Edge& e = TopoDS::Edge( aShapes( i )); + double tol = BRep_Tool::Tolerance( e ); + if ( tol < aTol ) nb[0]++; + else if ( tol > aTol ) nb[2]++; + else nb[1]++; + } + if ( nb[0] > 0 ) + stats.AddModif( "Tolerance of edge decreased for shape validity", nb[0] ); + if ( nb[1] > 0 ) + stats.AddModif( "Tolerance of edge limited as requested", nb[1] ); + if ( nb[2] > 0 ) + stats.AddModif( "Tolerance of edge increased for shape validity", nb[2] ); + + nb[0] = nb[1] = nb[2] = 0; + aShapes.Clear(); + TopExp::MapShapes( theOutShape, TopAbs_FACE, aShapes); + for ( int i = 1; i <= aShapes.Extent(); ++i ) + { + const TopoDS_Face& f = TopoDS::Face( aShapes( i )); + double tol = BRep_Tool::Tolerance( f ); + if ( tol < aTol ) nb[0]++; + else if ( tol > aTol ) nb[2]++; + else nb[1]++; + } + if ( nb[0] > 0 ) + stats.AddModif( "Tolerance of face decreased for shape validity", nb[0] ); + if ( nb[1] > 0 ) + stats.AddModif( "Tolerance of face limited as requested", nb[1] ); + if ( nb[2] > 0 ) + stats.AddModif( "Tolerance of face increased for shape validity", nb[2] ); + + SaveStatistics( tool ); + } } //======================================================================= @@ -971,7 +1072,7 @@ GetCreationInformation(std::string& theOperationName, AddParam( theParams, "Edge", "#" ) << aCI.GetIndex() << " of " << aCI.GetOriginal(); else AddParam( theParams, "Edge", aCI.GetOriginal() ); - AddParam( theParams, "Point", aCI.GetShapes() ); + AddParam( theParams, "Points", aCI.GetShapes() ); break; case CHANGE_ORIENTATION: theOperationName = "CHANGE_ORIENTATION"; @@ -997,6 +1098,33 @@ GetCreationInformation(std::string& theOperationName, return true; } + +//================================================================================ +/*! + * \brief Pass a record of what is done to the operation + */ +//================================================================================ + +void GEOMImpl_HealingDriver::SaveStatistics( const ShHealOper_Tool& healer, bool add ) const +{ + if ( healer.GetStatistics().GetData().empty() ) + return; + + if (Label().IsNull()) return; + + Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label()); + if (aFunction.IsNull()) return; + + GEOMImpl_IHealing HI (aFunction); + ShHealOper_ModifStats * stats = HI.GetStatistics(); + if ( !stats ) return; + + if ( add ) + stats->Add( healer.GetStatistics() ); + else + *stats = healer.GetStatistics(); +} + IMPLEMENT_STANDARD_HANDLE (GEOMImpl_HealingDriver,GEOM_BaseDriver); IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_HealingDriver,GEOM_BaseDriver); diff --git a/src/GEOMImpl/GEOMImpl_HealingDriver.hxx b/src/GEOMImpl/GEOMImpl_HealingDriver.hxx index 5784acd14..f738be6f4 100644 --- a/src/GEOMImpl/GEOMImpl_HealingDriver.hxx +++ b/src/GEOMImpl/GEOMImpl_HealingDriver.hxx @@ -61,10 +61,12 @@ #include #endif -class GEOMImpl_IHealing; +#include "GEOM_BaseDriver.hxx" +class GEOMImpl_IHealing; +class ShHealOper_Tool; +class TopTools_SequenceOfShape; -#include "GEOM_BaseDriver.hxx" DEFINE_STANDARD_HANDLE( GEOMImpl_HealingDriver, GEOM_BaseDriver ); @@ -99,6 +101,9 @@ DEFINE_STANDARD_RTTI( GEOMImpl_HealingDriver ) private: Standard_Boolean ShapeProcess ( GEOMImpl_IHealing*, const TopoDS_Shape&, TopoDS_Shape& ) const; Standard_Boolean SuppressFaces ( GEOMImpl_IHealing*, const TopoDS_Shape&, TopoDS_Shape& ) const; + void SuppressFacesRec (const TopTools_SequenceOfShape& theShapesFaces, + const TopoDS_Shape& theOriginalShape, + TopoDS_Shape& theOutShape) const; Standard_Boolean CloseContour ( GEOMImpl_IHealing*, const TopoDS_Shape&, TopoDS_Shape& ) const; Standard_Boolean RemoveIntWires( GEOMImpl_IHealing*, const TopoDS_Shape&, TopoDS_Shape& ) const; Standard_Boolean RemoveHoles ( GEOMImpl_IHealing*, const TopoDS_Shape&, TopoDS_Shape& ) const; @@ -108,6 +113,7 @@ private: Standard_Boolean ChangeOrientation( GEOMImpl_IHealing*, const TopoDS_Shape&, TopoDS_Shape& ) const; void LimitTolerance( GEOMImpl_IHealing*, const TopoDS_Shape&, TopoDS_Shape& ) const; + void SaveStatistics( const ShHealOper_Tool& healer, bool add=false ) const; }; #endif diff --git a/src/GEOMImpl/GEOMImpl_IHealing.hxx b/src/GEOMImpl/GEOMImpl_IHealing.hxx index d21962155..06e354db2 100755 --- a/src/GEOMImpl/GEOMImpl_IHealing.hxx +++ b/src/GEOMImpl/GEOMImpl_IHealing.hxx @@ -25,6 +25,7 @@ #include #include #include "TColStd_HSequenceOfTransient.hxx" +#include class GEOMImpl_IHealing { @@ -41,7 +42,8 @@ public: ARG_DEV_EDGE_VALUE = 8, ARG_IS_BY_PARAMETER = 9, ARG_SUBSHAPE_INDEX = 10, - ARG_LIST_SHAPES = 11 + ARG_LIST_SHAPES = 11, + ARG_STATISTICS = 4 }; GEOMImpl_IHealing(Handle(GEOM_Function) theFunction): _func(theFunction) {} @@ -91,6 +93,17 @@ public: funs->Prepend( GetOriginal() ); return funs; } + + void SetStatistics( ShHealOper_ModifStats * ms ) + { + if ( ms ) ms->Clear(); + _func->SetCallBackData( (void*) ms ); + } + ShHealOper_ModifStats * GetStatistics() + { + return (ShHealOper_ModifStats*) _func->GetCallBackData(); + } + private: Handle(GEOM_Function) _func; }; diff --git a/src/GEOMImpl/GEOMImpl_IHealingOperations.cxx b/src/GEOMImpl/GEOMImpl_IHealingOperations.cxx index 3a2b13305..3b8ab1147 100644 --- a/src/GEOMImpl/GEOMImpl_IHealingOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IHealingOperations.cxx @@ -25,7 +25,6 @@ #endif #include -#include #include #include @@ -35,6 +34,8 @@ #include #include #include +#include +#include #include @@ -43,12 +44,10 @@ #include #include -#include #include #include #include #include -#include #include #include #include @@ -64,6 +63,7 @@ GEOMImpl_IHealingOperations::GEOMImpl_IHealingOperations (GEOM_Engine* theEngine, int theDocID) : GEOM_IOperations(theEngine, theDocID) { + myModifStats = new ShHealOper_ModifStats; MESSAGE("GEOMImpl_IHealingOperations::GEOMImpl_IHealingOperations"); } @@ -74,6 +74,7 @@ GEOMImpl_IHealingOperations::GEOMImpl_IHealingOperations (GEOM_Engine* theEngine //============================================================================= GEOMImpl_IHealingOperations::~GEOMImpl_IHealingOperations() { + delete myModifStats; MESSAGE("GEOMImpl_IHealingOperations::~GEOMImpl_IHealingOperations"); } @@ -134,6 +135,7 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::ShapeProcess (Handle(GEOM_Objec HI.SetParameters( theParams ); HI.SetValues( theValues ); } + HI.SetStatistics( myModifStats ); //Compute the translation try { @@ -341,6 +343,7 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::SuppressFaces GEOMImpl_IHealing HI (aFunction); HI.SetFaces(theFaces); HI.SetOriginal(aLastFunction); + HI.SetStatistics( myModifStats ); //Compute the translation try { @@ -409,6 +412,7 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::CloseContour HI.SetWires( theWires ); HI.SetIsCommonVertex( isCommonVertex ); HI.SetOriginal( aLastFunction ); + HI.SetStatistics( myModifStats ); //Compute the translation try { @@ -476,6 +480,7 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::RemoveIntWires GEOMImpl_IHealing HI(aFunction); HI.SetWires( theWires ); HI.SetOriginal( aLastFunction ); + HI.SetStatistics( myModifStats ); //Compute the translation try { @@ -542,6 +547,7 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::FillHoles (Handle(GEOM_Object) GEOMImpl_IHealing HI(aFunction); HI.SetWires( theWires ); HI.SetOriginal( aLastFunction ); + HI.SetStatistics( myModifStats ); //Compute the translation try { @@ -616,6 +622,7 @@ GEOMImpl_IHealingOperations::Sew (std::list& theObjects, HI.SetTolerance( theTolerance ); HI.SetOriginal( theObjects.front()->GetLastFunction() ); objects->Remove(1); HI.SetShapes( objects ); + HI.SetStatistics( myModifStats ); //Compute the result try { @@ -682,6 +689,7 @@ GEOMImpl_IHealingOperations::RemoveInternalFaces (std::list< Handle(GEOM_Object) GEOMImpl_IHealing HI (aFunction); HI.SetOriginal( theSolids.front()->GetLastFunction() ); objects->Remove(1); HI.SetShapes( objects ); + HI.SetStatistics( myModifStats ); //Compute the result try { @@ -741,6 +749,7 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::DivideEdge (Handle(GEOM_Object) HI.SetDevideEdgeValue( theValue ); HI.SetIsByParameter( isByParameter ); HI.SetOriginal( aLastFunction ); + HI.SetStatistics( myModifStats ); //Compute the translation try { @@ -770,21 +779,26 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::DivideEdge (Handle(GEOM_Object) */ //============================================================================= Handle(GEOM_Object) -GEOMImpl_IHealingOperations::DivideEdgeByPoint (Handle(GEOM_Object) theObject, - int theIndex, - Handle(GEOM_Object) thePoint) +GEOMImpl_IHealingOperations::DivideEdgeByPoint (Handle(GEOM_Object) theObject, + int theIndex, + std::list< Handle(GEOM_Object)> & thePoints) { // set error code, check parameters SetErrorCode(KO); - if (theObject.IsNull() || thePoint.IsNull()) + if (theObject.IsNull() || thePoints.empty() ) return NULL; Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction(); - Handle(GEOM_Function) aPointFunc = thePoint->GetLastFunction(); - if (aLastFunction.IsNull() || aPointFunc.IsNull()) + if (aLastFunction.IsNull() ) return NULL; //There is no function which creates an object to be processed + Handle(TColStd_HSequenceOfTransient) aPointFunc = GEOM_Object::GetLastFunctions( thePoints ); + if ( aPointFunc.IsNull() || aPointFunc->IsEmpty() ) { + SetErrorCode("NULL argument points"); + return NULL; + } + // Add a new object Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY ); @@ -798,12 +812,11 @@ GEOMImpl_IHealingOperations::DivideEdgeByPoint (Handle(GEOM_Object) theObject, // prepare "data container" class IHealing GEOMImpl_IHealing HI(aFunction); - HI.SetIndex( theIndex ); - HI.SetOriginal( aLastFunction ); + HI.SetIndex ( theIndex ); + HI.SetOriginal ( aLastFunction ); + HI.SetShapes ( aPointFunc ); - Handle(TColStd_HSequenceOfTransient) funSeq = new TColStd_HSequenceOfTransient; - funSeq->Append( aPointFunc ); - HI.SetShapes( funSeq ); + HI.SetStatistics( myModifStats ); //Compute the translation try { @@ -822,7 +835,7 @@ GEOMImpl_IHealingOperations::DivideEdgeByPoint (Handle(GEOM_Object) theObject, //Make a Python command GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.DivideEdgeByPoint(" << theObject - << ", " << theIndex << ", " << thePoint << ")"; + << ", " << theIndex << ", " << thePoints << ")"; SetErrorCode(OK); return aNewObject; @@ -853,6 +866,7 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::FuseCollinearEdgesWithinWire if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL; GEOMImpl_IHealing aCI (aFunction); + aCI.SetStatistics( myModifStats ); Handle(GEOM_Function) aRefShape = theWire->GetLastFunction(); if (aRefShape.IsNull()) return NULL; @@ -1039,6 +1053,9 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::ChangeOrientation (Handle(GEOM_ // prepare "data container" class IVector GEOMImpl_IVector aVI (aFunction); aVI.SetCurve(aLastFunction); + + myModifStats->Clear(); + myModifStats->AddModif( "Vector reversed" ); } else { //Add the function @@ -1051,6 +1068,7 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::ChangeOrientation (Handle(GEOM_ // prepare "data container" class IHealing GEOMImpl_IHealing HI (aFunction); HI.SetOriginal(aLastFunction); + HI.SetStatistics( myModifStats ); } //Compute the translation @@ -1106,6 +1124,9 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::ChangeOrientationCopy (Handle(G // prepare "data container" class IVector GEOMImpl_IVector aVI (aFunction); aVI.SetCurve(aLastFunction); + + myModifStats->Clear(); + myModifStats->AddModif( "Vector reversed" ); } else { //Add the function @@ -1118,6 +1139,7 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::ChangeOrientationCopy (Handle(G // prepare "data container" class IHealing GEOMImpl_IHealing aHI (aFunction); aHI.SetOriginal(aLastFunction); + aHI.SetStatistics( myModifStats ); } // Compute the result @@ -1176,6 +1198,7 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::LimitTolerance (Handle(GEOM_Obj GEOMImpl_IHealing HI (aFunction); HI.SetOriginal(aLastFunction); HI.SetTolerance(theTolerance); + HI.SetStatistics( myModifStats ); // Compute try { diff --git a/src/GEOMImpl/GEOMImpl_IHealingOperations.hxx b/src/GEOMImpl/GEOMImpl_IHealingOperations.hxx index e2af51e10..df2952a9a 100644 --- a/src/GEOMImpl/GEOMImpl_IHealingOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IHealingOperations.hxx @@ -32,6 +32,8 @@ #include +class ShHealOper_ModifStats; + class GEOMImpl_IHealingOperations : public GEOM_IOperations { public: Standard_EXPORT GEOMImpl_IHealingOperations(GEOM_Engine* theEngine, int theDocID); @@ -81,9 +83,9 @@ class GEOMImpl_IHealingOperations : public GEOM_IOperations { double theValue, bool isByParameter ); - Standard_EXPORT Handle(GEOM_Object) DivideEdgeByPoint( Handle(GEOM_Object) theObject, - int theIndex, - Handle(GEOM_Object) thePoint ); + Standard_EXPORT Handle(GEOM_Object) DivideEdgeByPoint( Handle(GEOM_Object) theObject, + int theIndex, + std::list& thePoint ); Standard_EXPORT Handle(GEOM_Object) FuseCollinearEdgesWithinWire (Handle(GEOM_Object) theWire, @@ -102,6 +104,11 @@ class GEOMImpl_IHealingOperations : public GEOM_IOperations { Standard_EXPORT Handle(GEOM_Object) LimitTolerance( Handle(GEOM_Object) theObject, double theTolerance ); + const ShHealOper_ModifStats* GetStatistics() { return myModifStats; } + +private: + + ShHealOper_ModifStats* myModifStats; }; #endif diff --git a/src/GEOMImpl/GEOMImpl_PolylineDumper.cxx b/src/GEOMImpl/GEOMImpl_PolylineDumper.cxx index 05fb9a61a..ba66b5f99 100644 --- a/src/GEOMImpl/GEOMImpl_PolylineDumper.cxx +++ b/src/GEOMImpl/GEOMImpl_PolylineDumper.cxx @@ -152,7 +152,7 @@ void GEOMImpl_PolylineDumper::init() } } - char *aSeparator = "\n\t"; + const char *aSeparator = "\n\t"; Standard_Integer i; std::list >::const_iterator anIt = myCoords.begin(); diff --git a/src/GEOM_I/CMakeLists.txt b/src/GEOM_I/CMakeLists.txt index d916ffe60..24b3731a5 100755 --- a/src/GEOM_I/CMakeLists.txt +++ b/src/GEOM_I/CMakeLists.txt @@ -29,6 +29,7 @@ INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/src/GEOM ${PROJECT_SOURCE_DIR}/src/GEOMAlgo ${PROJECT_SOURCE_DIR}/src/GEOMUtils + ${PROJECT_SOURCE_DIR}/src/ShHealOper ${PROJECT_BINARY_DIR}/idl ${CMAKE_CURRENT_SOURCE_DIR} ${PROJECT_BINARY_DIR} diff --git a/src/GEOM_I/GEOM_IHealingOperations_i.cc b/src/GEOM_I/GEOM_IHealingOperations_i.cc index cd04c7626..53707cac8 100644 --- a/src/GEOM_I/GEOM_IHealingOperations_i.cc +++ b/src/GEOM_I/GEOM_IHealingOperations_i.cc @@ -27,10 +27,11 @@ #include "GEOM_IHealingOperations_i.hh" #include "GEOM_Engine.hxx" #include "GEOM_Object.hxx" +#include "ShHealOper_ModifStats.hxx" -#include "utilities.h" -#include "OpUtil.hxx" -#include "Utils_ExceptHandlers.hxx" +#include +#include +#include #include #include @@ -439,7 +440,7 @@ GEOM::GEOM_Object_ptr GEOM_IHealingOperations_i::DivideEdge (GEOM::GEOM_Object_p GEOM::GEOM_Object_ptr GEOM_IHealingOperations_i::DivideEdgeByPoint (GEOM::GEOM_Object_ptr theObject, CORBA::Short theIndex, - GEOM::GEOM_Object_ptr thePoint) + const GEOM::ListOfGO& thePoints) { GEOM::GEOM_Object_var aGEOMObject; @@ -451,14 +452,14 @@ GEOM_IHealingOperations_i::DivideEdgeByPoint (GEOM::GEOM_Object_ptr theObject, if (anObject.IsNull()) return aGEOMObject._retn(); - // Get the point - Handle(GEOM_Object) aPoint = GetObjectImpl(thePoint); - if (aPoint.IsNull()) + // Get the points + std::list< Handle(GEOM_Object) > aPoints; + if (! GetListOfObjectsImpl( thePoints, aPoints )) return aGEOMObject._retn(); // Perform Handle(GEOM_Object) aNewObject = - GetOperations()->DivideEdgeByPoint( anObject, theIndex, aPoint ); + GetOperations()->DivideEdgeByPoint( anObject, theIndex, aPoints ); if (!GetOperations()->IsDone() || aNewObject.IsNull()) return aGEOMObject._retn(); @@ -635,3 +636,26 @@ GEOM::GEOM_Object_ptr GEOM_IHealingOperations_i::LimitTolerance (GEOM::GEOM_Obje return GetObject(aNewObject); } + +//================================================================================ +/*! + * \brief Return information on what has been done by the last called healing method + */ +//================================================================================ + +GEOM::ModifStatistics* GEOM_IHealingOperations_i::GetStatistics() +{ + const ShHealOper_ModifStats& stats = * GetOperations()->GetStatistics(); + const std::set< ShHealOper_ModifStats::Datum >& modifs = stats.GetData(); + std::set< ShHealOper_ModifStats::Datum >::const_iterator modif = modifs.begin(); + + GEOM::ModifStatistics_var statsVar = new GEOM::ModifStatistics(); + statsVar->length( modifs.size() ); + for ( int i = 0; modif != modifs.end(); ++modif, ++i ) + { + statsVar[ i ].name = modif->myModif.c_str(); + statsVar[ i ].count = modif->myCount; + } + + return statsVar._retn(); +} diff --git a/src/GEOM_I/GEOM_IHealingOperations_i.hh b/src/GEOM_I/GEOM_IHealingOperations_i.hh index 4d851973d..c1da1d006 100644 --- a/src/GEOM_I/GEOM_IHealingOperations_i.hh +++ b/src/GEOM_I/GEOM_IHealingOperations_i.hh @@ -84,7 +84,7 @@ class GEOM_I_EXPORT GEOM_IHealingOperations_i : GEOM::GEOM_Object_ptr DivideEdgeByPoint (GEOM::GEOM_Object_ptr theObject, CORBA::Short theIndex, - GEOM::GEOM_Object_ptr thePoint); + const GEOM::ListOfGO& thePoints); GEOM::GEOM_Object_ptr FuseCollinearEdgesWithinWire (GEOM::GEOM_Object_ptr theWire, const GEOM::ListOfGO& theVertices); @@ -101,6 +101,8 @@ class GEOM_I_EXPORT GEOM_IHealingOperations_i : ::GEOMImpl_IHealingOperations* GetOperations() { return (::GEOMImpl_IHealingOperations*)GetImpl(); } + GEOM::ModifStatistics* GetStatistics(); + private: Handle(TColStd_HArray1OfInteger) Convert( const GEOM::short_array& ); diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index 07535cdf9..32d7ca47e 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -6830,12 +6830,12 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): self._autoPublish(anObj, theName, "divideEdge") return anObj - ## Addition of a point to a given edge of \a theObject by projecting - # another point to the given edge. + ## Addition of points to a given edge of \a theObject by projecting + # other points to the given edge. # @param theObject Shape to be processed. # @param theEdgeIndex Index of edge to be divided within theObject's shape, # if -1, then theObject itself is the edge. - # @param thePoint Point to project to theEdgeIndex-th edge. + # @param thePoints List of points to project to theEdgeIndex-th edge. # @param theName Object name; when specified, this parameter is used # for result publication in the study. Otherwise, if automatic # publication is switched on, default value is used for result name. @@ -6844,16 +6844,16 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # # @ref tui_add_point_on_edge "Example" @ManageTransactions("HealOp") - def DivideEdgeByPoint(self, theObject, theEdgeIndex, thePoint, theName=None): + def DivideEdgeByPoint(self, theObject, theEdgeIndex, thePoints, theName=None): """ - Addition of a point to a given edge of \a theObject by projecting - another point to the given edge. + Addition of points to a given edge of \a theObject by projecting + other points to the given edge. Parameters: theObject Shape to be processed. theEdgeIndex The edge or its index to be divided within theObject's shape, if -1, then theObject itself is the edge. - thePoint Point to project to theEdgeIndex-th edge. + thePoints List of points to project to theEdgeIndex-th edge. theName Object name; when specified, this parameter is used for result publication in the study. Otherwise, if automatic publication is switched on, default value is used for result name. @@ -6864,7 +6864,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # Example: see GEOM_TestHealing.py if isinstance( theEdgeIndex, GEOM._objref_GEOM_Object ): theEdgeIndex = self.GetSubShapeID( theObject, theEdgeIndex ) - anObj = self.HealOp.DivideEdgeByPoint(theObject, theEdgeIndex, thePoint) + anObj = self.HealOp.DivideEdgeByPoint(theObject, theEdgeIndex, ToList( thePoints )) RaiseIfFailed("DivideEdgeByPoint", self.HealOp) self._autoPublish(anObj, theName, "divideEdge") return anObj diff --git a/src/RepairGUI/RepairGUI.cxx b/src/RepairGUI/RepairGUI.cxx index cb0608260..b65327e91 100644 --- a/src/RepairGUI/RepairGUI.cxx +++ b/src/RepairGUI/RepairGUI.cxx @@ -121,3 +121,98 @@ extern "C" return new RepairGUI( parent ); } } + +//===================================================================================== +// Statistics dialog +//===================================================================================== + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace +{ + class StatsDlg : public QDialog + { + public: + StatsDlg( GEOM::ModifStatistics_var stats, QWidget* parent ); + }; + + StatsDlg::StatsDlg( GEOM::ModifStatistics_var stats, QWidget* parent ): QDialog( parent ) + { + setModal( false ); + setAttribute( Qt::WA_DeleteOnClose, true ); + setWindowTitle( tr( "GEOM_HEALING_STATS_TITLE" ) ); + setMinimumWidth( 500 ); + + const int nbRows = stats->length(); + const int nbCols = 2; + QTableWidget* table = new QTableWidget( nbRows, nbCols, this ); + table->setEditTriggers( QAbstractItemView::NoEditTriggers ); + table->horizontalHeader()->setResizeMode( 1, QHeaderView::Interactive ); + table->horizontalHeader()->setStretchLastSection( true ); + + QStringList headers; + headers << tr( "GEOM_HEALING_STATS_COL_1" ); + headers << tr( "GEOM_HEALING_STATS_COL_2" ); + table->setHorizontalHeaderLabels( headers ); + + // buttons + + QPushButton* okBtn = new QPushButton( tr( "GEOM_BUT_OK" ), this ); + okBtn->setAutoDefault( true ); + okBtn->setDefault( true ); + okBtn->setFocus(); + // QPushButton* helpBtn = new QPushButton( tr( "GEOM_BUT_HELP" ), this ); + // helpBtn->setAutoDefault( true ); + + QHBoxLayout* btnLayout = new QHBoxLayout; + btnLayout->setMargin( 9 ); + btnLayout->setSpacing( 6 ); + + btnLayout->addWidget( okBtn ); + btnLayout->addStretch( 10 ); + // btnLayout->addWidget( helpBtn ); + + QVBoxLayout* aLay = new QVBoxLayout( this ); + aLay->setMargin( 9 ); + aLay->setSpacing( 6 ); + aLay->addWidget( table ); + aLay->addLayout( btnLayout ); + + // fill the table + for ( int row = 0; row < nbRows; ++row ) + { + table->setItem( row, 0, new QTableWidgetItem( QString::number( stats[ row ].count ))); + table->setItem( row, 1, new QTableWidgetItem( tr( stats[ row ].name.in() ))); + } + + connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() )); + //connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() )); + + } +} + +//================================================================================ +/*! + * \brief Show a dialog providing info on what is done by healing + */ +//================================================================================ + +void RepairGUI::ShowStatistics( GEOM::GEOM_IHealingOperations_var anOper, QWidget* parent ) +{ + GEOM::ModifStatistics_var stats = anOper->GetStatistics(); + + if ( ! &stats.in() || stats->length() == 0 ) + return; + + StatsDlg* dlg = new StatsDlg( stats, parent ); + dlg->exec(); +} diff --git a/src/RepairGUI/RepairGUI.h b/src/RepairGUI/RepairGUI.h index df1eb9c45..26fa5fbbf 100644 --- a/src/RepairGUI/RepairGUI.h +++ b/src/RepairGUI/RepairGUI.h @@ -29,6 +29,9 @@ #include +#include +#include CORBA_CLIENT_HEADER(GEOM_Gen) + //================================================================================= // class : RepairGUI // purpose : @@ -40,6 +43,7 @@ public: ~RepairGUI(); bool OnGUIEvent( int, SUIT_Desktop* ); -}; + static void ShowStatistics( GEOM::GEOM_IHealingOperations_var anOper, QWidget* parent ); +}; #endif // REPAIRGUI_H diff --git a/src/RepairGUI/RepairGUI_ChangeOrientationDlg.cxx b/src/RepairGUI/RepairGUI_ChangeOrientationDlg.cxx index 3d395463b..3d5bbcba9 100644 --- a/src/RepairGUI/RepairGUI_ChangeOrientationDlg.cxx +++ b/src/RepairGUI/RepairGUI_ChangeOrientationDlg.cxx @@ -26,18 +26,19 @@ // #include "RepairGUI_ChangeOrientationDlg.h" -#include -#include -#include +#include "DlgRef.h" +#include "GeometryGUI.h" +#include "GEOMBase.h" +#include "RepairGUI.h" -#include #include -#include #include +#include +#include +#include -#include +#include "GEOMImpl_Types.hxx" -#include //================================================================================= // class : RepairGUI_ChangeOrientationDlg() @@ -280,7 +281,11 @@ bool RepairGUI_ChangeOrientationDlg::execute( ObjectList& objects ) } if ( !anObj->_is_nil() ) + { + if ( !IsPreview() ) + RepairGUI::ShowStatistics( anOper, this ); objects.push_back( anObj._retn() ); + } return true; } diff --git a/src/RepairGUI/RepairGUI_CloseContourDlg.cxx b/src/RepairGUI/RepairGUI_CloseContourDlg.cxx index f57ad4868..77e29a211 100644 --- a/src/RepairGUI/RepairGUI_CloseContourDlg.cxx +++ b/src/RepairGUI/RepairGUI_CloseContourDlg.cxx @@ -26,9 +26,10 @@ // #include "RepairGUI_CloseContourDlg.h" -#include -#include -#include +#include "DlgRef.h" +#include "GeometryGUI.h" +#include "GEOMBase.h" +#include "RepairGUI.h" #include #include @@ -325,8 +326,11 @@ bool RepairGUI_CloseContourDlg::execute (ObjectList& objects) bool aResult = !anObj->_is_nil(); if (aResult) + { + if ( !IsPreview() ) + RepairGUI::ShowStatistics( anOper, this ); objects.push_back(anObj._retn()); - + } return aResult; } diff --git a/src/RepairGUI/RepairGUI_DivideEdgeDlg.cxx b/src/RepairGUI/RepairGUI_DivideEdgeDlg.cxx index 62715108b..ad77079ef 100644 --- a/src/RepairGUI/RepairGUI_DivideEdgeDlg.cxx +++ b/src/RepairGUI/RepairGUI_DivideEdgeDlg.cxx @@ -26,11 +26,12 @@ // #include "RepairGUI_DivideEdgeDlg.h" -#include -#include -#include -#include +#include "DlgRef.h" +#include "GeometryGUI.h" +#include "GEOMBase.h" +#include "RepairGUI.h" +#include #include #include #include @@ -161,7 +162,7 @@ void RepairGUI_DivideEdgeDlg::Init() myEditCurrentArgument = GroupPoints->LineEdit1; myObject = GEOM::GEOM_Object::_nil(); - myPoint.nullify(); + myPoints.clear(); myIndex = -1; myProjectionOK = false; @@ -231,11 +232,8 @@ void RepairGUI_DivideEdgeDlg::displayPreview() BRepBuilderAPI_MakeVertex mkVertex (aPnt); aShape = mkVertex.Shape(); } - else if ( getConstructorId() == BY_POINT_PROJ && myPoint ) + else if ( getConstructorId() == BY_POINT_PROJ && !myPoints.empty() ) { - TopoDS_Shape aPoints; - GEOMBase::GetShape( myPoint.get(), aPoints, TopAbs_SHAPE ); - BRep_Builder builder; TopoDS_Compound compoundOfVV; builder.MakeCompound(compoundOfVV); @@ -245,11 +243,13 @@ void RepairGUI_DivideEdgeDlg::displayPreview() aProjector.Init( aCurve, aFP, aLP ); TopTools_MapOfShape vMap; - TopExp_Explorer vertex( aPoints, TopAbs_VERTEX ); - for ( ; vertex.More(); vertex.Next() ) + for ( int i = 0; i < myPoints.count(); ++i ) { - if ( !vMap.Add( vertex.Current() )) continue; - gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( vertex.Current() )); + TopoDS_Shape aPoint; + GEOMBase::GetShape( myPoints[i].get(), aPoint, TopAbs_VERTEX ); + if ( !vMap.Add( aPoint )) continue; + + gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( aPoint )); aProjector.Perform( p ); if ( aProjector.NbPoints() > 0 ) { @@ -296,13 +296,14 @@ bool RepairGUI_DivideEdgeDlg::ClickOnApply() initName(); - myEditCurrentArgument->setText( "" ); + GroupPoints->LineEdit1->setText( "" ); + GroupPoints->LineEdit2->setText( "" ); myObject = GEOM::GEOM_Object::_nil(); - myPoint.nullify(); + myPoints.clear(); myIndex = -1; myProjectionOK = false; - ConstructorsClicked(getConstructorId()); + GroupPoints->PushButton1->click(); return true; } @@ -322,10 +323,11 @@ void RepairGUI_DivideEdgeDlg::SelectionIntoArgument() { myObject = GEOM::GEOM_Object::_nil(); myIndex = -1; + myProjectionOK = false; } else //if ( myEditCurrentArgument == GroupPoints->LineEdit2 ) { - myPoint.nullify(); + myPoints.clear(); myProjectionOK = false; } @@ -333,7 +335,7 @@ void RepairGUI_DivideEdgeDlg::SelectionIntoArgument() SALOME_ListIO aSelList; aSelMgr->selectedObjects(aSelList); - if ( aSelList.Extent() == 1 ) { + if ( toSelectObject && aSelList.Extent() == 1 ) { Handle(SALOME_InteractiveObject) anIO = aSelList.First(); GEOM::GEOM_Object_var aSelectedObj = GEOMBase::ConvertIOinGEOMObject( anIO ); if ( !CORBA::is_nil( aSelectedObj ) ) @@ -343,7 +345,7 @@ void RepairGUI_DivideEdgeDlg::SelectionIntoArgument() if ( GEOMBase::GetShape( aSelectedObj, aShape, TopAbs_SHAPE ) ) { const int aType = aShape.ShapeType(); - if ( aType <= TopAbs_EDGE || !toSelectObject ) // edge, wire, face, shell, solid, compound + if ( aType <= TopAbs_EDGE ) // edge, wire, face, shell, solid, compound { GEOM::short_array anIndexes; @@ -354,34 +356,35 @@ void RepairGUI_DivideEdgeDlg::SelectionIntoArgument() if ( !aMap.IsEmpty() ) // sub-shape selection { - if ( toSelectObject ) { - myIndex = aMap( 1 ); - myObject = aSelectedObj; - myEditCurrentArgument->setText( aName += QString( ":edge_%1" ).arg( myIndex ) ); - } - else if (( myPoint = getSelected( TopAbs_VERTEX ))) - { - myEditCurrentArgument->setText( aName += QString( ":vertex_%1" ).arg( aMap( 1 ))); - } + myIndex = aMap( 1 ); + myObject = aSelectedObj; + myEditCurrentArgument->setText( aName += QString( ":edge_%1" ).arg( myIndex ) ); } - else if ( aType == TopAbs_EDGE && toSelectObject ) // single shape selection + else if ( aType == TopAbs_EDGE ) // single shape selection { myIndex = -1; myObject = aSelectedObj; - myEditCurrentArgument->setText( aName ); - } - else if ( aType == TopAbs_VERTEX && !toSelectObject ) // single shape selection - { - myPoint = aSelectedObj; - myEditCurrentArgument->setText( aName ); + myEditCurrentArgument->setText( GEOMBase::GetName( myObject ) ); } else // face, shell, solid or compound was selected, and NOT its sub-shape. { + myIndex = -1; + myObject = GEOM::GEOM_Object::_nil(); } } } } } + if ( !toSelectObject ) + { + myPoints = getSelected( TopAbs_VERTEX, -1, /*strict=*/true ); + if ( myPoints.empty() ) + myEditCurrentArgument->setText( "" ); + else if ( myPoints.count() == 1 ) + myEditCurrentArgument->setText( GEOMBase::GetName( myPoints[0].get() )); + else + myEditCurrentArgument->setText( QObject::tr( "%1_vertices" ).arg( myPoints.count() )); + } displayPreview(); } @@ -487,7 +490,7 @@ bool RepairGUI_DivideEdgeDlg::isValid( QString& msg ) } else if ( getConstructorId() == BY_POINT_PROJ ) { - if (( ok = myPoint ) && !( ok = myProjectionOK )) + if (( ok = myPoints.count() ) && !( ok = myProjectionOK )) msg = tr("DEVIDE_EDGE_BAD_PROJ_MSG"); } return !myObject->_is_nil() && ok; @@ -502,10 +505,17 @@ bool RepairGUI_DivideEdgeDlg::execute( ObjectList& objects ) GEOM::GEOM_IHealingOperations_var anOper = GEOM::GEOM_IHealingOperations::_narrow( getOperation() ); GEOM::GEOM_Object_var anObj; if ( getConstructorId() == BY_PARAM ) + { anObj = anOper->DivideEdge( myObject, myIndex, myValEdt->value(), getIsByParameter() ); + } else - anObj = anOper->DivideEdgeByPoint( myObject, myIndex, myPoint.get() ); - + { + GEOM::ListOfGO_var objList = new GEOM::ListOfGO; + objList->length( myPoints.count() ); + for ( int i = 0; i < myPoints.count(); ++i ) + objList[i] = myPoints[i].copy(); + anObj = anOper->DivideEdgeByPoint( myObject, myIndex, objList ); + } bool aResult = !anObj->_is_nil(); if ( aResult ) { @@ -517,6 +527,8 @@ bool RepairGUI_DivideEdgeDlg::execute( ObjectList& objects ) aParameters << ""; anObj->SetParameters(aParameters.join(":").toLatin1().constData()); } + if ( !IsPreview() ) + RepairGUI::ShowStatistics( anOper, this ); objects.push_back( anObj._retn() ); } @@ -552,5 +564,6 @@ void RepairGUI_DivideEdgeDlg::initSelection() //================================================================================= void RepairGUI_DivideEdgeDlg::addSubshapesToStudy() { - GEOMBase::PublishSubObject( myPoint.get() ); + for ( int i = 0; i < myPoints.count(); ++i ) + GEOMBase::PublishSubObject( myPoints[i].get() ); } diff --git a/src/RepairGUI/RepairGUI_DivideEdgeDlg.h b/src/RepairGUI/RepairGUI_DivideEdgeDlg.h index 129c9895c..88cf5229d 100644 --- a/src/RepairGUI/RepairGUI_DivideEdgeDlg.h +++ b/src/RepairGUI/RepairGUI_DivideEdgeDlg.h @@ -62,7 +62,7 @@ private: private: GEOM::GEOM_Object_var myObject; - GEOM::GeomObjPtr myPoint; + QList myPoints; bool myProjectionOK; DlgRef_2SelExt* GroupPoints; diff --git a/src/RepairGUI/RepairGUI_LimitToleranceDlg.cxx b/src/RepairGUI/RepairGUI_LimitToleranceDlg.cxx index 69b37b9f6..0b447d106 100644 --- a/src/RepairGUI/RepairGUI_LimitToleranceDlg.cxx +++ b/src/RepairGUI/RepairGUI_LimitToleranceDlg.cxx @@ -23,11 +23,12 @@ #include "RepairGUI_LimitToleranceDlg.h" -#include -#include -#include -#include +#include "DlgRef.h" +#include "GeometryGUI.h" +#include "GEOMBase.h" +#include "RepairGUI.h" +#include #include #include #include @@ -303,6 +304,8 @@ bool RepairGUI_LimitToleranceDlg::execute(ObjectList& objects) QStringList aParameters; aParameters << myTolEdt->text(); anObj->SetParameters(aParameters.join(":").toLatin1().constData()); + if ( !IsPreview() ) + RepairGUI::ShowStatistics( anOper, this ); objects.push_back(anObj._retn()); } diff --git a/src/RepairGUI/RepairGUI_RemoveHolesDlg.cxx b/src/RepairGUI/RepairGUI_RemoveHolesDlg.cxx index 56b5aa004..92a3b0c76 100644 --- a/src/RepairGUI/RepairGUI_RemoveHolesDlg.cxx +++ b/src/RepairGUI/RepairGUI_RemoveHolesDlg.cxx @@ -26,9 +26,10 @@ // #include "RepairGUI_RemoveHolesDlg.h" -#include -#include -#include +#include "DlgRef.h" +#include "GeometryGUI.h" +#include "GEOMBase.h" +#include "RepairGUI.h" #include #include @@ -353,7 +354,11 @@ bool RepairGUI_RemoveHolesDlg::execute (ObjectList& objects) GEOM::GEOM_Object_var anObj = anOper->FillHoles(myObject, myWiresInd); aResult = !anObj->_is_nil(); if (aResult) + { + if ( !IsPreview() ) + RepairGUI::ShowStatistics( anOper, this ); objects.push_back(anObj._retn()); + } } return aResult; diff --git a/src/RepairGUI/RepairGUI_RemoveIntWiresDlg.cxx b/src/RepairGUI/RepairGUI_RemoveIntWiresDlg.cxx index 927656c57..a60e6ed72 100644 --- a/src/RepairGUI/RepairGUI_RemoveIntWiresDlg.cxx +++ b/src/RepairGUI/RepairGUI_RemoveIntWiresDlg.cxx @@ -26,9 +26,10 @@ // #include "RepairGUI_RemoveIntWiresDlg.h" -#include -#include -#include +#include "DlgRef.h" +#include "GeometryGUI.h" +#include "GEOMBase.h" +#include "RepairGUI.h" #include #include @@ -312,8 +313,11 @@ bool RepairGUI_RemoveIntWiresDlg::execute (ObjectList& objects) bool aResult = !anObj->_is_nil(); if (aResult) + { + if ( !IsPreview() ) + RepairGUI::ShowStatistics( anOper, this ); objects.push_back(anObj._retn()); - + } return aResult; } diff --git a/src/RepairGUI/RepairGUI_ShapeProcessDlg.cxx b/src/RepairGUI/RepairGUI_ShapeProcessDlg.cxx index 926f1eb80..e05f008d3 100755 --- a/src/RepairGUI/RepairGUI_ShapeProcessDlg.cxx +++ b/src/RepairGUI/RepairGUI_ShapeProcessDlg.cxx @@ -26,10 +26,11 @@ #include "RepairGUI_ShapeProcessDlg.h" -#include -#include -#include -#include +#include "DlgRef.h" +#include "GeometryGUI.h" +#include "GEOMBase.h" +#include "GEOMImpl_Types.hxx" +#include "RepairGUI.h" #include #include @@ -652,6 +653,8 @@ bool RepairGUI_ShapeProcessDlg::execute( ObjectList& objects ) aParameters << getTexts( aParams ); anObj->SetParameters(aParameters.join(":").toLatin1().constData()); + + RepairGUI::ShowStatistics( anOper, this ); } objects.push_back( anObj._retn() ); } diff --git a/src/RepairGUI/RepairGUI_SuppressFacesDlg.cxx b/src/RepairGUI/RepairGUI_SuppressFacesDlg.cxx index 43a0f629e..d7c297168 100644 --- a/src/RepairGUI/RepairGUI_SuppressFacesDlg.cxx +++ b/src/RepairGUI/RepairGUI_SuppressFacesDlg.cxx @@ -24,9 +24,10 @@ #include "RepairGUI_SuppressFacesDlg.h" -#include -#include -#include +#include "DlgRef.h" +#include "GeometryGUI.h" +#include "GEOMBase.h" +#include "RepairGUI.h" #include #include @@ -376,8 +377,11 @@ bool RepairGUI_SuppressFacesDlg::execute (ObjectList& objects) bool aResult = !anObj->_is_nil(); if (aResult) + { + if ( !IsPreview() ) + RepairGUI::ShowStatistics( anOper, this ); objects.push_back(anObj._retn()); - + } return aResult; } diff --git a/src/ShHealOper/CMakeLists.txt b/src/ShHealOper/CMakeLists.txt index 8d2d3a2ba..9def66279 100755 --- a/src/ShHealOper/CMakeLists.txt +++ b/src/ShHealOper/CMakeLists.txt @@ -52,6 +52,7 @@ SET(ShHealOper_HEADERS ShHealOper_SplitCurve3d.hxx ShHealOper_ChangeOrientation.hxx ShHealOper_Tool.hxx + ShHealOper_ModifStats.hxx ) # --- sources --- diff --git a/src/ShHealOper/ShHealOper_ChangeOrientation.cxx b/src/ShHealOper/ShHealOper_ChangeOrientation.cxx index e48ba58d5..04112efa7 100644 --- a/src/ShHealOper/ShHealOper_ChangeOrientation.cxx +++ b/src/ShHealOper/ShHealOper_ChangeOrientation.cxx @@ -73,6 +73,7 @@ Standard_Boolean ShHealOper_ChangeOrientation::Perform() while (itr.More()) { B.Add(myResultShape,itr.Value().Reversed()); itr.Next(); + myStatistics.AddModif("Face reversed"); } } else if (myInitShape.ShapeType() == TopAbs_FACE) @@ -82,6 +83,7 @@ Standard_Boolean ShHealOper_ChangeOrientation::Perform() while (itr.More()) { B.Add(myResultShape,itr.Value()); itr.Next(); + myStatistics.AddModif("Wire reversed"); } myResultShape.Reverse(); } @@ -105,12 +107,14 @@ Standard_Boolean ShHealOper_ChangeOrientation::Perform() if ( myInitShape.ShapeType() == TopAbs_EDGE ) { myResultShape = reversedEdges.First(); + myStatistics.AddModif("Edge reversed"); } else { BRepBuilderAPI_MakeWire wire; wire.Add( reversedEdges ); myResultShape = wire; + myStatistics.AddModif("Wire reversed"); } // myResultShape = myInitShape.EmptyCopied(); // TopoDS_Iterator itr (myInitShape); @@ -132,6 +136,13 @@ Standard_Boolean ShHealOper_ChangeOrientation::Perform() myResultShape.Orientation(TopAbs_REVERSED); else myResultShape.Orientation(TopAbs_FORWARD); + + switch( myResultShape.ShapeType() ) { + case TopAbs_SOLID : myStatistics.AddModif("Solid reversed"); break; + case TopAbs_COMPSOLID: myStatistics.AddModif("Compsolid reversed"); break; + case TopAbs_COMPOUND : myStatistics.AddModif("Compound reversed"); break; + default:; + } } return true; diff --git a/src/ShHealOper/ShHealOper_CloseContour.cxx b/src/ShHealOper/ShHealOper_CloseContour.cxx index 67c69b50e..0e9dfaa45 100644 --- a/src/ShHealOper/ShHealOper_CloseContour.cxx +++ b/src/ShHealOper/ShHealOper_CloseContour.cxx @@ -252,10 +252,14 @@ Standard_Boolean ShHealOper_CloseContour::fixGaps(const Handle(ShapeExtend_WireD Standard_Integer ind1 = (ind2 >1 ? ind2 -1 : theWire->NbEdges()); TopoDS_Edge aE1= theWire->Edge(ind1); TopoDS_Edge aE2= theWire->Edge(ind2); - if(!myModeVertex) + if(!myModeVertex) { buildEdge(aE1,aE2,theCommonFaces); - else + myStatistics.AddModif("An edge added to close a wire"); + } + else { myMaxTolerance = RealLast(); + myStatistics.AddModif("Tolerance of vertex increased to close a wire"); + } if(ind2 == ind1) break; } } @@ -268,8 +272,9 @@ Standard_Boolean ShHealOper_CloseContour::fixGaps(const Handle(ShapeExtend_WireD //function : checkOneFace //purpose : //======================================================================= -Standard_Boolean ShHealOper_CloseContour::checkOneFace(const Handle(ShapeExtend_WireData)& theSewd, - TopTools_SequenceOfShape& theCommonFaces) const +Standard_Boolean +ShHealOper_CloseContour::checkOneFace(const Handle(ShapeExtend_WireData)& theSewd, + TopTools_SequenceOfShape& theCommonFaces) const { TopTools_IndexedMapOfShape amapfaces; TopoDS_Edge aEdge1 = theSewd->Edge(1); diff --git a/src/ShHealOper/ShHealOper_EdgeDivide.cxx b/src/ShHealOper/ShHealOper_EdgeDivide.cxx index 99de5efe5..d188ab144 100644 --- a/src/ShHealOper/ShHealOper_EdgeDivide.cxx +++ b/src/ShHealOper/ShHealOper_EdgeDivide.cxx @@ -142,6 +142,7 @@ Standard_Boolean ShHealOper_EdgeDivide::Perform(const TopoDS_Shape& theEdge, TopTools_MapOfShape vMap; TopExp_Explorer vertex( thePoints, TopAbs_VERTEX ); + std::set< double > params; // to exclude equal params for ( ; vertex.More(); vertex.Next() ) { if ( !vMap.Add( vertex.Current() )) continue; @@ -151,9 +152,24 @@ Standard_Boolean ShHealOper_EdgeDivide::Perform(const TopoDS_Shape& theEdge, { double u = double( aProjector.LowerDistanceParameter() ); double param = ( u - aFirst ) / ( aLast - aFirst ); - aSeqValues->Append( param ); + params.insert( param ); } } + // remove too close params + params.insert( 0 ); + params.insert( 1 ); + std::set< double >::iterator p2 = params.begin(), p1 = p2++; + while ( p2 != params.end() ) + { + if ( Abs( *p2 - *p1 ) < 1e-3 ) // compare normalized params + params.erase( p1 ); + p1 = p2++; + } + p1 = params.begin(); ++p1; // skip aFirst + p2 = params.end(); --p2; // skip aLast + for ( ; p1 != p2; ++p1 ) + aSeqValues->Append( *p1 ); + myDone = build(aSeqValues); return myDone; } @@ -219,7 +235,10 @@ Standard_Boolean ShHealOper_EdgeDivide::build(const Handle(TColStd_HSequenceOfRe myErrorStatus = ShHealOper_ErrorExecution; } if(isDone) + { myResultShape = myContext->Apply(myInitShape); + myStatistics.AddModif("Vertex added on edge", theValues->Length() ); + } return isDone; } diff --git a/src/ShHealOper/ShHealOper_FillHoles.cxx b/src/ShHealOper/ShHealOper_FillHoles.cxx index 114326a8b..82f78cc27 100644 --- a/src/ShHealOper/ShHealOper_FillHoles.cxx +++ b/src/ShHealOper/ShHealOper_FillHoles.cxx @@ -186,7 +186,10 @@ Standard_Boolean ShHealOper_FillHoles::Fill(const TopTools_SequenceOfShape& theF myDone = (addFace(aSurf,aWire,aCurves2d,aOrders,aSenses) || myDone); } if(myDone) + { myResultShape = myContext->Apply(myResultShape); + myStatistics.AddModif( "Face created to fill hole" , aSeqWires->Length() ); + } return myDone; } diff --git a/src/ShHealOper/ShHealOper_ModifStats.hxx b/src/ShHealOper/ShHealOper_ModifStats.hxx new file mode 100644 index 000000000..ad043b8a7 --- /dev/null +++ b/src/ShHealOper/ShHealOper_ModifStats.hxx @@ -0,0 +1,78 @@ +// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : ShHealOper_ModifStats.hxx +// Created : Mon Dec 1 15:29:48 2014 + +#ifndef __ShHealOper_ModifStats_HXX__ +#define __ShHealOper_ModifStats_HXX__ + +#include +#include + +/*! + * \brief Structure describing modifications done in a shape + */ +class Standard_EXPORT ShHealOper_ModifStats +{ + public: + + struct Standard_EXPORT Datum + { + std::string myModif; // what is done + mutable int myCount; // how many times (in how many sub-shapes) + + Datum( const std::string& txt, int cnt=0 ): myModif( txt ), myCount(cnt) {} + bool operator< ( const Datum& o ) const { return myModif < o.myModif; } + }; + + // record a modification + void AddModif( const std::string& modifText, int nb=1 ) + { + std::set< Datum >::iterator d = myData.insert( Datum( modifText )).first; + d->myCount += nb; + } + + // add data from another ShHealOper_ModifStats + void Add( const ShHealOper_ModifStats& stats ) + { + if ( myData.empty() ) myData = stats.myData; + else { + std::set< Datum >::const_iterator d = stats.myData.begin(); + for ( ; d != stats.myData.end(); ++d ) + AddModif( d->myModif, d->myCount ); + } + } + + // return all recorder modifications + const std::set< Datum >& GetData() const { return myData; } + + // clear all statistics + void Clear() { myData.clear(); } + + protected: + + std::set< Datum > myData; + +}; + +#endif diff --git a/src/ShHealOper/ShHealOper_RemoveInternalWires.cxx b/src/ShHealOper/ShHealOper_RemoveInternalWires.cxx index 698cedaf9..f50da898d 100644 --- a/src/ShHealOper/ShHealOper_RemoveInternalWires.cxx +++ b/src/ShHealOper/ShHealOper_RemoveInternalWires.cxx @@ -137,6 +137,9 @@ Standard_Boolean ShHealOper_RemoveInternalWires::removeWire(const TopoDS_Face& t } } } + if ( isremove ) + myStatistics.AddModif( "Wire removed" ); + return isremove; } //======================================================================= diff --git a/src/ShHealOper/ShHealOper_ShapeProcess.cxx b/src/ShHealOper/ShHealOper_ShapeProcess.cxx index fa516e924..d991e1f7e 100644 --- a/src/ShHealOper/ShHealOper_ShapeProcess.cxx +++ b/src/ShHealOper/ShHealOper_ShapeProcess.cxx @@ -39,6 +39,13 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include //======================================================================= //function : ShHealOper_ShapeProcess() @@ -52,8 +59,10 @@ ShHealOper_ShapeProcess::ShHealOper_ShapeProcess ( ) : //myResource = new Resource_Manager("ShHealing"); myPrefix = "ShapeProcess"; mySaveHistoryMode = Standard_False; - myLevel = TopAbs_FACE; + myLevel = TopAbs_EDGE; myDone = Standard_False; + myOperations.Context()->SetDetalisation ( TopAbs_EDGE ); + myOperations.Context()->SetTraceLevel( 3 ); } //======================================================================= @@ -63,23 +72,22 @@ ShHealOper_ShapeProcess::ShHealOper_ShapeProcess ( ) : ShHealOper_ShapeProcess::ShHealOper_ShapeProcess (const TCollection_AsciiString& theNameResource, const TCollection_AsciiString& thePrefix ) : - myOperations(theNameResource.ToCString(),thePrefix.ToCString()) + myOperations(theNameResource.ToCString(),thePrefix.ToCString()) { //myResource = new Resource_Manager(theNameResource); myPrefix = thePrefix; mySaveHistoryMode = Standard_False; - myLevel = TopAbs_FACE; + myLevel = TopAbs_EDGE; myDone = Standard_False; } //======================================================================= //function : Perform -//purpose : +//purpose : //======================================================================= -void ShHealOper_ShapeProcess::Perform(const TopoDS_Shape& theOldShape, - TopoDS_Shape& theNewShape) +void ShHealOper_ShapeProcess::Perform(const TopoDS_Shape& theOldShape, + TopoDS_Shape& theNewShape) { - myMapModifications.Clear(); //ShapeProcessAPI_ApplySequence aOperations(myResource,myPrefix.ToCString()); //myDone = Standard_False; @@ -99,12 +107,50 @@ void ShHealOper_ShapeProcess::Perform(const TopoDS_Shape& theOldShape, myDone = !anOldShape.IsSame(theNewShape); if(!myDone) { Standard_Real aendTol =aSatol.Tolerance(theNewShape,0); - myDone = (fabs(ainitTol - aendTol) > Precision::Confusion()); + myDone = (fabs(ainitTol - aendTol) > Precision::Confusion()); + if ( myDone ) { + if ( ainitTol > aendTol ) + myStatistics.AddModif( "Tolerance fixed (decreased)" ); + else + myStatistics.AddModif( "Tolerance fixed (increased)" ); + } } + + // fill myStatistics with messages + Handle(ShapeExtend_MsgRegistrator) msg = myOperations.Context()->Messages(); + const ShapeExtend_DataMapOfShapeListOfMsg& shape2msg = msg->MapShape(); + ShapeExtend_DataMapIteratorOfDataMapOfShapeListOfMsg s2msg( shape2msg ); + for ( ; s2msg.More(); s2msg.Next() ) + { + const Message_ListOfMsg & msgList = s2msg.Value(); + Message_ListIteratorOfListOfMsg mIt( msgList ); + for ( ; mIt.More(); mIt.Next() ) + { + Message_Msg& m = mIt.Value(); + TCollection_AsciiString txt = m.Get(); + myStatistics.AddModif( txt.ToCString() ); + } + } + +// for (TopTools_DataMapIteratorOfDataMapOfShapeShape It (myOperations.Context()->Map()); It.More(); It.Next()) { +// TopoDS_Shape keyshape = It.Key(), valueshape = It.Value(); +// /* if (keyshape.ShapeType() == TopAbs_SHELL) { +// if (valueshape.IsNull()) SN++; +// else SS++; +// } +// else if (keyshape.ShapeType() == TopAbs_FACE)*/ { +// if (valueshape.IsNull()) cout << "Removed" << endl; +// else { +// TopAbs::Print( keyshape.ShapeType(), cout ) << " -> "; +// TopAbs::Print( valueshape.ShapeType(), cout ) << " IsSame()=" << keyshape.IsSame(valueshape) << endl; +// } +// } +// } + } //======================================================================= //function : SetOperators -//purpose : +//purpose : //======================================================================= void ShHealOper_ShapeProcess::SetOperators(const TColStd_SequenceOfAsciiString& theSeqOperators) @@ -127,8 +173,8 @@ void ShHealOper_ShapeProcess::SetOperators(const TColStd_SequenceOfAsciiString& //purpose : //======================================================================= -void ShHealOper_ShapeProcess::SetParameter(const TCollection_AsciiString& theNameParam, - const TCollection_AsciiString& theVal) +void ShHealOper_ShapeProcess::SetParameter(const TCollection_AsciiString& theNameParam, + const TCollection_AsciiString& theVal) { TCollection_AsciiString anameParam(myPrefix); anameParam += "."; @@ -171,14 +217,14 @@ Standard_Boolean ShHealOper_ShapeProcess::GetOperators(TColStd_SequenceOfAsciiSt //======================================================================= Standard_Boolean ShHealOper_ShapeProcess::GetParameter(const TCollection_AsciiString& theNameParam, - TCollection_AsciiString& theVal) + TCollection_AsciiString& theVal) { TCollection_AsciiString namePar(myPrefix); namePar += "."; namePar += theNameParam; if(!myOperations.Context()->ResourceManager()->Find(namePar.ToCString())) return Standard_False; - + theVal = myOperations.Context()->ResourceManager()->Value(namePar.ToCString()); return Standard_True; } diff --git a/src/ShHealOper/ShHealOper_ShapeProcess.hxx b/src/ShHealOper/ShHealOper_ShapeProcess.hxx index f83f6e10e..67616a5fd 100644 --- a/src/ShHealOper/ShHealOper_ShapeProcess.hxx +++ b/src/ShHealOper/ShHealOper_ShapeProcess.hxx @@ -35,10 +35,12 @@ #include #include +#include "ShHealOper_Tool.hxx" + /// Class ShHealOper_ShapeProcess //Class for performing Shape healing operations on the shape. -class ShHealOper_ShapeProcess +class ShHealOper_ShapeProcess : public ShHealOper_Tool { public: // ---------- PUBLIC METHODS ---------- diff --git a/src/ShHealOper/ShHealOper_Tool.cxx b/src/ShHealOper/ShHealOper_Tool.cxx index 6fb613346..35a7924d4 100644 --- a/src/ShHealOper/ShHealOper_Tool.cxx +++ b/src/ShHealOper/ShHealOper_Tool.cxx @@ -59,4 +59,5 @@ void ShHealOper_Tool::Init(const TopoDS_Shape& theShape) myErrorStatus =ShHealOper_NotError; myInitShape = theShape; myContext->Apply(myInitShape); + myStatistics.Clear(); } diff --git a/src/ShHealOper/ShHealOper_Tool.hxx b/src/ShHealOper/ShHealOper_Tool.hxx index a8bec37bd..a06c5885a 100644 --- a/src/ShHealOper/ShHealOper_Tool.hxx +++ b/src/ShHealOper/ShHealOper_Tool.hxx @@ -27,10 +27,11 @@ #ifndef ShHealOper_Tool_HeaderFile #define ShHealOper_Tool_HeaderFile -#include #include #include +#include "ShHealOper_ModifStats.hxx" + /// Class ShHealOper_Tool // //enumeration for definition of the status of the error if operation failed @@ -69,12 +70,12 @@ class ShHealOper_Tool } //Returns modified shape obtained after operation from initial shape. - inline Standard_Boolean IsDone() const + inline Standard_Boolean IsDone() const { return myDone; } //Returns status of the operation. - + inline void SetContext(Handle(ShapeBuild_ReShape)& theContext) { myContext = theContext; @@ -91,17 +92,31 @@ class ShHealOper_Tool { return myErrorStatus; } - protected: + + ShHealOper_ModifStats& GetStatistics() + { + return myStatistics; + } + + const ShHealOper_ModifStats& GetStatistics() const + { + return myStatistics; + } + // Returns statistics of what is done + +protected: // ---------- PROTECTED FIELDS ---------- Handle(ShapeBuild_ReShape) myContext; - TopoDS_Shape myInitShape; - TopoDS_Shape myResultShape; - Standard_Boolean myDone; - ShHealOper_Error myErrorStatus; - public: -// Declaration of CASCADE RTTI -//DEFINE_STANDARD_RTTI (ShHealOper_Tool) + TopoDS_Shape myInitShape; + TopoDS_Shape myResultShape; + Standard_Boolean myDone; + ShHealOper_Error myErrorStatus; + ShHealOper_ModifStats myStatistics; + +public: + // Declaration of CASCADE RTTI + //DEFINE_STANDARD_RTTI (ShHealOper_Tool) }; // Definition of HANDLE object using Standard_DefineHandle.hxx