# 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)
\n To <b>Add Point on Edge</b> in the <b>Main Menu</b> select
<b>Repair - > Add Point on Edge</b>.
-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 <b>OCC Viewer</b> only.
The \b Result will be a \b GEOM_Object.
\image html repair8.png
\n\n
</li>
- <li>We can select a point that will be projected to the selected
- edge to find the location of the new vertex.
+ <li>We can select several points that will be projected to the selected
+ edge to find the location of new vertices.
<p>
- <b>TUI Command:</b> <em>geompy.DivideEdgeByPoint(Shape, Edge, Point)</em>
+ <b>TUI Command:</b> <em>geompy.DivideEdgeByPoint(Shape, Edge, Points)</em>
<ul>
<li> \em Shape is a shape which contains an edge to be divided</li>
<li>\em Edge is an edge to be divided (or it's ID, if it is = -1,
then \em Shape should be an edge itself).</li>
- <li> \em Point is a point to project to \a Edge. </li>
+ <li> \em Points is a list of points to project to \a Edge. </li>
</ul>
- \b Arguments: Name + 1 Edge + 1 Point.
+ \b Arguments: Name + 1 Edge + 1 or more Points.
\image html divedgebypoint.png
SI_ALL // all interferences
};
-
/*!
* \brief Object creation parameters
*
struct Parameter
{
string name;
- //any value;
string value;
};
typedef sequence<Parameter> Parameters;
Parameters params;
};
+ /*!
+ * \brief Reporting on shape healing
+ */
+ struct ModifInfo
+ {
+ string name; // what changed
+ long count; // how many times
+ };
+ typedef sequence<ModifInfo> ModifStatistics;
+
typedef sequence<string> string_array;
typedef sequence<short> short_array;
* \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);
/*!
* 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.
*/
/*!
* 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.
*/
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.
/*!
* \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);
*/
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:
#include <TCollection_AsciiString.hxx>
#include <TCollection_ExtendedString.hxx>
+#include <cstdlib>
+
#include <Standard_Failure.hxx>
#include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
#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
*/
//=============================================================================
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);
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
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<void*> ( address );
+}
+
IMPLEMENT_STANDARD_HANDLE (GEOM_Function, Standard_Transient);
IMPLEMENT_STANDARD_RTTIEXT(GEOM_Function, Standard_Transient );
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();
//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);
TDF_Label _label;
bool _isDone;
+ bool _isCallBackData;
};
#endif
</message>
<message>
<source>DEVIDE_EDGE_BY_PROJ_POINT</source>
- <translation>Point to project</translation>
+ <translation>Points to project</translation>
</message>
<message>
<source>ERROR_SHAPE_TYPE</source>
</message>
<message>
<source>GEOM_DIVIDE_EDGE_TITLE</source>
- <translation>Addition of point</translation>
+ <translation>Addition of points</translation>
</message>
<message>
<source>GEOM_DX</source>
<source>GEOM_NO_SHAPES_SELECTED</source>
<translation>There are no shapes that meet filtering parameters</translation>
</message>
+ <message>
+ <source>GEOM_HEALING_STATS_TITLE</source>
+ <translation>What is done</translation>
+ </message>
+ <message>
+ <source>GEOM_HEALING_STATS_COL_1</source>
+ <translation>Count</translation>
+ </message>
+ <message>
+ <source>GEOM_HEALING_STATS_COL_2</source>
+ <translation>Modication</translation>
+ </message>
</context>
<context>
<name>GeometryGUI</name>
${PROJECT_SOURCE_DIR}/src/SKETCHER
${PROJECT_SOURCE_DIR}/src/ARCHIMEDE
${PROJECT_SOURCE_DIR}/src/XAO
+ ${PROJECT_SOURCE_DIR}/src/ShHealOper
${CMAKE_CURRENT_SOURCE_DIR}
)
if (!aHealer.isDone())
raiseNotDoneExeption( ShHealOper_NotError );
+ SaveStatistics( aHealer );
+
return Standard_True;
}
//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))
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;
}
else
raiseNotDoneExeption( aHealer.GetErrorStatus() );
+ SaveStatistics( aHealer );
+
return aResult;
}
else
raiseNotDoneExeption( aHealer.GetErrorStatus() );
+ SaveStatistics( aHealer );
+
return aResult;
}
else
raiseNotDoneExeption( aHealer.GetErrorStatus() );
+ SaveStatistics( aHealer );
+
return aResult;
}
else
raiseNotDoneExeption( aHealer.GetErrorStatus() );
+ SaveStatistics( aHealer );
+
return aResult;
}
{
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;
else
raiseNotDoneExeption( aHealer.GetErrorStatus() );
+ SaveStatistics( aHealer );
+
return aResult;
}
else
raiseNotDoneExeption( aHealer.GetErrorStatus() );
+ SaveStatistics( aHealer );
+
return aResult;
}
// 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);
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 );
+ }
}
//=======================================================================
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";
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);
#include <Standard_CString.hxx>
#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 );
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;
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
#include <TColStd_HArray1OfInteger.hxx>
#include <TColStd_HArray1OfExtendedString.hxx>
#include "TColStd_HSequenceOfTransient.hxx"
+#include <ShHealOper_ModifStats.hxx>
class GEOMImpl_IHealing
{
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) {}
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;
};
#endif
#include <Standard_Version.hxx>
-#include <Standard_Stream.hxx>
#include <GEOMImpl_IHealingOperations.hxx>
#include <GEOM_PythonDump.hxx>
#include <GEOMImpl_IVector.hxx>
#include <GEOMImpl_VectorDriver.hxx>
#include <GEOMImpl_CopyDriver.hxx>
+#include <ShHealOper_ModifStats.hxx>
+#include <ShHealOper_ShapeProcess.hxx>
#include <Basics_OCCTVersion.hxx>
#include <Utils_ExceptHandlers.hxx>
#include <BRep_Builder.hxx>
-#include <ShHealOper_ShapeProcess.hxx>
#include <ShapeAnalysis_FreeBounds.hxx>
#include <TColStd_HArray1OfExtendedString.hxx>
#include <TColStd_HSequenceOfTransient.hxx>
#include <TCollection_AsciiString.hxx>
-#include <TDF_Tool.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_SequenceOfShape.hxx>
#include <TopoDS_Compound.hxx>
GEOMImpl_IHealingOperations::GEOMImpl_IHealingOperations (GEOM_Engine* theEngine, int theDocID)
: GEOM_IOperations(theEngine, theDocID)
{
+ myModifStats = new ShHealOper_ModifStats;
MESSAGE("GEOMImpl_IHealingOperations::GEOMImpl_IHealingOperations");
}
//=============================================================================
GEOMImpl_IHealingOperations::~GEOMImpl_IHealingOperations()
{
+ delete myModifStats;
MESSAGE("GEOMImpl_IHealingOperations::~GEOMImpl_IHealingOperations");
}
HI.SetParameters( theParams );
HI.SetValues( theValues );
}
+ HI.SetStatistics( myModifStats );
//Compute the translation
try {
GEOMImpl_IHealing HI (aFunction);
HI.SetFaces(theFaces);
HI.SetOriginal(aLastFunction);
+ HI.SetStatistics( myModifStats );
//Compute the translation
try {
HI.SetWires( theWires );
HI.SetIsCommonVertex( isCommonVertex );
HI.SetOriginal( aLastFunction );
+ HI.SetStatistics( myModifStats );
//Compute the translation
try {
GEOMImpl_IHealing HI(aFunction);
HI.SetWires( theWires );
HI.SetOriginal( aLastFunction );
+ HI.SetStatistics( myModifStats );
//Compute the translation
try {
GEOMImpl_IHealing HI(aFunction);
HI.SetWires( theWires );
HI.SetOriginal( aLastFunction );
+ HI.SetStatistics( myModifStats );
//Compute the translation
try {
HI.SetTolerance( theTolerance );
HI.SetOriginal( theObjects.front()->GetLastFunction() ); objects->Remove(1);
HI.SetShapes( objects );
+ HI.SetStatistics( myModifStats );
//Compute the result
try {
GEOMImpl_IHealing HI (aFunction);
HI.SetOriginal( theSolids.front()->GetLastFunction() ); objects->Remove(1);
HI.SetShapes( objects );
+ HI.SetStatistics( myModifStats );
//Compute the result
try {
HI.SetDevideEdgeValue( theValue );
HI.SetIsByParameter( isByParameter );
HI.SetOriginal( aLastFunction );
+ HI.SetStatistics( myModifStats );
//Compute the translation
try {
*/
//=============================================================================
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 );
// 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 {
//Make a Python command
GEOM::TPythonDump(aFunction)
<< aNewObject << " = geompy.DivideEdgeByPoint(" << theObject
- << ", " << theIndex << ", " << thePoint << ")";
+ << ", " << theIndex << ", " << thePoints << ")";
SetErrorCode(OK);
return aNewObject;
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;
// prepare "data container" class IVector
GEOMImpl_IVector aVI (aFunction);
aVI.SetCurve(aLastFunction);
+
+ myModifStats->Clear();
+ myModifStats->AddModif( "Vector reversed" );
}
else {
//Add the function
// prepare "data container" class IHealing
GEOMImpl_IHealing HI (aFunction);
HI.SetOriginal(aLastFunction);
+ HI.SetStatistics( myModifStats );
}
//Compute the translation
// prepare "data container" class IVector
GEOMImpl_IVector aVI (aFunction);
aVI.SetCurve(aLastFunction);
+
+ myModifStats->Clear();
+ myModifStats->AddModif( "Vector reversed" );
}
else {
//Add the function
// prepare "data container" class IHealing
GEOMImpl_IHealing aHI (aFunction);
aHI.SetOriginal(aLastFunction);
+ aHI.SetStatistics( myModifStats );
}
// Compute the result
GEOMImpl_IHealing HI (aFunction);
HI.SetOriginal(aLastFunction);
HI.SetTolerance(theTolerance);
+ HI.SetStatistics( myModifStats );
// Compute
try {
#include <list>
+class ShHealOper_ModifStats;
+
class GEOMImpl_IHealingOperations : public GEOM_IOperations {
public:
Standard_EXPORT GEOMImpl_IHealingOperations(GEOM_Engine* theEngine, int theDocID);
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<Handle(GEOM_Object)>& thePoint );
Standard_EXPORT Handle(GEOM_Object) FuseCollinearEdgesWithinWire
(Handle(GEOM_Object) theWire,
Standard_EXPORT Handle(GEOM_Object) LimitTolerance( Handle(GEOM_Object) theObject,
double theTolerance );
+ const ShHealOper_ModifStats* GetStatistics() { return myModifStats; }
+
+private:
+
+ ShHealOper_ModifStats* myModifStats;
};
#endif
}
}
- char *aSeparator = "\n\t";
+ const char *aSeparator = "\n\t";
Standard_Integer i;
std::list <std::list <double> >::const_iterator anIt = myCoords.begin();
${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}
#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 <utilities.h>
+#include <OpUtil.hxx>
+#include <Utils_ExceptHandlers.hxx>
#include <Basics_Utils.hxx>
#include <TColStd_HSequenceOfTransient.hxx>
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;
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();
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();
+}
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);
::GEOMImpl_IHealingOperations* GetOperations() { return (::GEOMImpl_IHealingOperations*)GetImpl(); }
+ GEOM::ModifStatistics* GetStatistics();
+
private:
Handle(TColStd_HArray1OfInteger) Convert( const GEOM::short_array& );
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.
#
# @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.
# 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
return new RepairGUI( parent );
}
}
+
+//=====================================================================================
+// Statistics dialog
+//=====================================================================================
+
+#include <QDialog>
+#include <QHBoxLayout>
+#include <QHeaderView>
+#include <QPushButton>
+#include <QString>
+#include <QStringList>
+#include <QTableWidget>
+#include <QTableWidget>
+#include <QTableWidgetItem>
+#include <QVBoxLayout>
+
+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();
+}
#include <GEOMGUI.h>
+#include <SALOMEconfig.h>
+#include CORBA_CLIENT_HEADER(GEOM_Gen)
+
//=================================================================================
// class : RepairGUI
// purpose :
~RepairGUI();
bool OnGUIEvent( int, SUIT_Desktop* );
-};
+ static void ShowStatistics( GEOM::GEOM_IHealingOperations_var anOper, QWidget* parent );
+};
#endif // REPAIRGUI_H
//
#include "RepairGUI_ChangeOrientationDlg.h"
-#include <DlgRef.h>
-#include <GeometryGUI.h>
-#include <GEOMBase.h>
+#include "DlgRef.h"
+#include "GeometryGUI.h"
+#include "GEOMBase.h"
+#include "RepairGUI.h"
-#include <SalomeApp_Application.h>
#include <LightApp_SelectionMgr.h>
-#include <SUIT_Session.h>
#include <SUIT_ResourceMgr.h>
+#include <SUIT_Session.h>
+#include <SalomeApp_Application.h>
+#include <TopAbs.hxx>
-#include <GEOMImpl_Types.hxx>
+#include "GEOMImpl_Types.hxx"
-#include <TopAbs.hxx>
//=================================================================================
// class : RepairGUI_ChangeOrientationDlg()
}
if ( !anObj->_is_nil() )
+ {
+ if ( !IsPreview() )
+ RepairGUI::ShowStatistics( anOper, this );
objects.push_back( anObj._retn() );
+ }
return true;
}
//
#include "RepairGUI_CloseContourDlg.h"
-#include <DlgRef.h>
-#include <GeometryGUI.h>
-#include <GEOMBase.h>
+#include "DlgRef.h"
+#include "GeometryGUI.h"
+#include "GEOMBase.h"
+#include "RepairGUI.h"
#include <SUIT_Session.h>
#include <SUIT_ResourceMgr.h>
bool aResult = !anObj->_is_nil();
if (aResult)
+ {
+ if ( !IsPreview() )
+ RepairGUI::ShowStatistics( anOper, this );
objects.push_back(anObj._retn());
-
+ }
return aResult;
}
//
#include "RepairGUI_DivideEdgeDlg.h"
-#include <DlgRef.h>
-#include <GeometryGUI.h>
-#include <GEOMBase.h>
-#include <SalomeApp_DoubleSpinBox.h>
+#include "DlgRef.h"
+#include "GeometryGUI.h"
+#include "GEOMBase.h"
+#include "RepairGUI.h"
+#include <SalomeApp_DoubleSpinBox.h>
#include <SalomeApp_Application.h>
#include <LightApp_SelectionMgr.h>
#include <SUIT_Session.h>
myEditCurrentArgument = GroupPoints->LineEdit1;
myObject = GEOM::GEOM_Object::_nil();
- myPoint.nullify();
+ myPoints.clear();
myIndex = -1;
myProjectionOK = false;
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);
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 )
{
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;
}
{
myObject = GEOM::GEOM_Object::_nil();
myIndex = -1;
+ myProjectionOK = false;
}
else //if ( myEditCurrentArgument == GroupPoints->LineEdit2 )
{
- myPoint.nullify();
+ myPoints.clear();
myProjectionOK = false;
}
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 ) )
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;
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();
}
}
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;
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 )
{
aParameters << "";
anObj->SetParameters(aParameters.join(":").toLatin1().constData());
}
+ if ( !IsPreview() )
+ RepairGUI::ShowStatistics( anOper, this );
objects.push_back( anObj._retn() );
}
//=================================================================================
void RepairGUI_DivideEdgeDlg::addSubshapesToStudy()
{
- GEOMBase::PublishSubObject( myPoint.get() );
+ for ( int i = 0; i < myPoints.count(); ++i )
+ GEOMBase::PublishSubObject( myPoints[i].get() );
}
private:
GEOM::GEOM_Object_var myObject;
- GEOM::GeomObjPtr myPoint;
+ QList<GEOM::GeomObjPtr> myPoints;
bool myProjectionOK;
DlgRef_2SelExt* GroupPoints;
#include "RepairGUI_LimitToleranceDlg.h"
-#include <DlgRef.h>
-#include <GeometryGUI.h>
-#include <GEOMBase.h>
-#include <SalomeApp_DoubleSpinBox.h>
+#include "DlgRef.h"
+#include "GeometryGUI.h"
+#include "GEOMBase.h"
+#include "RepairGUI.h"
+#include <SalomeApp_DoubleSpinBox.h>
#include <SalomeApp_Application.h>
#include <LightApp_SelectionMgr.h>
#include <SalomeApp_Study.h>
QStringList aParameters;
aParameters << myTolEdt->text();
anObj->SetParameters(aParameters.join(":").toLatin1().constData());
+ if ( !IsPreview() )
+ RepairGUI::ShowStatistics( anOper, this );
objects.push_back(anObj._retn());
}
//
#include "RepairGUI_RemoveHolesDlg.h"
-#include <DlgRef.h>
-#include <GeometryGUI.h>
-#include <GEOMBase.h>
+#include "DlgRef.h"
+#include "GeometryGUI.h"
+#include "GEOMBase.h"
+#include "RepairGUI.h"
#include <SUIT_Session.h>
#include <SUIT_ResourceMgr.h>
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;
//
#include "RepairGUI_RemoveIntWiresDlg.h"
-#include <DlgRef.h>
-#include <GeometryGUI.h>
-#include <GEOMBase.h>
+#include "DlgRef.h"
+#include "GeometryGUI.h"
+#include "GEOMBase.h"
+#include "RepairGUI.h"
#include <SUIT_Session.h>
#include <SUIT_ResourceMgr.h>
bool aResult = !anObj->_is_nil();
if (aResult)
+ {
+ if ( !IsPreview() )
+ RepairGUI::ShowStatistics( anOper, this );
objects.push_back(anObj._retn());
-
+ }
return aResult;
}
#include "RepairGUI_ShapeProcessDlg.h"
-#include <DlgRef.h>
-#include <GeometryGUI.h>
-#include <GEOMBase.h>
-#include <GEOMImpl_Types.hxx>
+#include "DlgRef.h"
+#include "GeometryGUI.h"
+#include "GEOMBase.h"
+#include "GEOMImpl_Types.hxx"
+#include "RepairGUI.h"
#include <SalomeApp_Application.h>
#include <SalomeApp_DoubleSpinBox.h>
aParameters << getTexts( aParams );
anObj->SetParameters(aParameters.join(":").toLatin1().constData());
+
+ RepairGUI::ShowStatistics( anOper, this );
}
objects.push_back( anObj._retn() );
}
#include "RepairGUI_SuppressFacesDlg.h"
-#include <DlgRef.h>
-#include <GeometryGUI.h>
-#include <GEOMBase.h>
+#include "DlgRef.h"
+#include "GeometryGUI.h"
+#include "GEOMBase.h"
+#include "RepairGUI.h"
#include <SUIT_Session.h>
#include <SUIT_ResourceMgr.h>
bool aResult = !anObj->_is_nil();
if (aResult)
+ {
+ if ( !IsPreview() )
+ RepairGUI::ShowStatistics( anOper, this );
objects.push_back(anObj._retn());
-
+ }
return aResult;
}
ShHealOper_SplitCurve3d.hxx
ShHealOper_ChangeOrientation.hxx
ShHealOper_Tool.hxx
+ ShHealOper_ModifStats.hxx
)
# --- sources ---
while (itr.More()) {
B.Add(myResultShape,itr.Value().Reversed());
itr.Next();
+ myStatistics.AddModif("Face reversed");
}
}
else if (myInitShape.ShapeType() == TopAbs_FACE)
while (itr.More()) {
B.Add(myResultShape,itr.Value());
itr.Next();
+ myStatistics.AddModif("Wire reversed");
}
myResultShape.Reverse();
}
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);
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;
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;
}
}
//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);
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;
{
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;
}
myErrorStatus = ShHealOper_ErrorExecution;
}
if(isDone)
+ {
myResultShape = myContext->Apply(myInitShape);
+ myStatistics.AddModif("Vertex added on edge", theValues->Length() );
+ }
return isDone;
}
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;
}
--- /dev/null
+// 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 <string>
+#include <set>
+
+/*!
+ * \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
}
}
}
+ if ( isremove )
+ myStatistics.AddModif( "Wire removed" );
+
return isremove;
}
//=======================================================================
#include <TopoDS_Iterator.hxx>
#include <TColStd_IndexedDataMapOfTransientTransient.hxx>
#include <TNaming_CopyShape.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
+#include <ShapeExtend_MsgRegistrator.hxx>
+#include <ShapeExtend_DataMapOfShapeListOfMsg.hxx>
+#include <ShapeExtend_DataMapIteratorOfDataMapOfShapeListOfMsg.hxx>
+#include <Message_ListOfMsg.hxx>
+#include <Message_ListIteratorOfListOfMsg.hxx>
+#include <Message_Msg.hxx>
//=======================================================================
//function : 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 );
}
//=======================================================================
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;
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)
//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 += ".";
//=======================================================================
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;
}
#include <ShapeProcessAPI_ApplySequence.hxx>
#include <ShapeProcess_ShapeContext.hxx>
+#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 ----------
myErrorStatus =ShHealOper_NotError;
myInitShape = theShape;
myContext->Apply(myInitShape);
+ myStatistics.Clear();
}
#ifndef ShHealOper_Tool_HeaderFile
#define ShHealOper_Tool_HeaderFile
-#include <MMgt_TShared.hxx>
#include <ShapeBuild_ReShape.hxx>
#include <TopoDS_Shape.hxx>
+#include "ShHealOper_ModifStats.hxx"
+
/// Class ShHealOper_Tool
//
//enumeration for definition of the status of the error if operation failed
}
//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;
{
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