From a2f76b15f163c9ff1317b5eec1353bc59326d519 Mon Sep 17 00:00:00 2001 From: rkv Date: Tue, 23 Aug 2016 15:52:11 +0300 Subject: [PATCH] 0027567: VIS - possible memory leaks due to use of plain pointers: Fix also the VIS guide. Add the test v3d/ivtk/bug27567. Add a draw command "ivtkremove". 0027734: Configuration - TKIVtkDraw build fails with TBB: Remove unnecessary define statement (windows specific). Small correction of test case for issue CR27567 --- dox/user_guides/vis/vis.md | 2 +- src/Draw/Draw_Interpretor.cxx | 16 +-- src/DrawResources/TestCommands.tcl | 53 +++++++ src/IVtkDraw/IVtkDraw.cxx | 99 ++++++++++++- ...IVtkDraw_HighlightAndSelectionPipeline.cxx | 27 ++-- src/IVtkDraw/IVtkDraw_Interactor.cxx | 5 +- src/IVtkOCC/IVtkOCC_SelectableObject.cxx | 7 + src/IVtkOCC/IVtkOCC_SelectableObject.hxx | 10 +- src/IVtkOCC/IVtkOCC_ShapeMesher.cxx | 21 ++- src/IVtkOCC/IVtkOCC_ShapePickerAlgo.cxx | 24 +++- src/IVtkOCC/IVtkOCC_ShapePickerAlgo.hxx | 4 + src/IVtkOCC/IVtkOCC_ViewerSelector.cxx | 12 +- src/IVtkOCC/IVtkOCC_ViewerSelector.hxx | 2 + src/IVtkTools/IVtkTools.cxx | 5 +- src/IVtkTools/IVtkTools.hxx | 3 +- src/IVtkTools/IVtkTools_DisplayModeFilter.hxx | 3 +- src/IVtkTools/IVtkTools_ShapeDataSource.cxx | 132 +++++++++--------- src/IVtkTools/IVtkTools_ShapeDataSource.hxx | 5 +- src/IVtkTools/IVtkTools_ShapeObject.cxx | 39 +++--- src/IVtkTools/IVtkTools_ShapeObject.hxx | 10 +- src/IVtkTools/IVtkTools_ShapePicker.cxx | 55 ++++++-- src/IVtkTools/IVtkTools_ShapePicker.hxx | 29 ++-- src/IVtkTools/IVtkTools_SubPolyDataFilter.cxx | 42 +++--- src/IVtkTools/IVtkTools_SubPolyDataFilter.hxx | 3 +- src/IVtkVTK/IVtkVTK_ShapeData.cxx | 7 +- src/IVtkVTK/IVtkVTK_ShapeData.hxx | 5 +- src/IVtkVTK/IVtkVTK_View.cxx | 10 +- src/IVtkVTK/IVtkVTK_View.hxx | 3 +- tests/bugs/begin | 53 ------- tests/v3d/ivtk/bug27567 | 66 +++++++++ 30 files changed, 492 insertions(+), 260 deletions(-) create mode 100644 tests/v3d/ivtk/bug27567 diff --git a/dox/user_guides/vis/vis.md b/dox/user_guides/vis/vis.md index e8d2b44ee3..4b73cf063a 100644 --- a/dox/user_guides/vis/vis.md +++ b/dox/user_guides/vis/vis.md @@ -121,7 +121,7 @@ IVtkTools::InitShapeMapper(Mapper); It is possible to get an instance of *vtkLookupTable class* with a default OCCT color scheme by means of the following method: ~~~~ -vtkLookupTable* Table = IVtkTools::InitLookupTable(); +vtkSmartPointer Table = IVtkTools::InitLookupTable(); ~~~~ @subsubsection occt_vis_3_2_2 Custom color scheme diff --git a/src/Draw/Draw_Interpretor.cxx b/src/Draw/Draw_Interpretor.cxx index 68fb8f9e79..0b696b661d 100644 --- a/src/Draw/Draw_Interpretor.cxx +++ b/src/Draw/Draw_Interpretor.cxx @@ -473,11 +473,7 @@ void Draw_Interpretor::AppendElement(const Standard_CString s) Standard_Integer Draw_Interpretor::Eval(const Standard_CString line) { - Standard_PCharacter pLine; - // - pLine=(Standard_PCharacter)line; - // - return Tcl_Eval(myInterp,pLine); + return Tcl_Eval(myInterp,line); } @@ -489,10 +485,7 @@ Standard_Integer Draw_Interpretor::Eval(const Standard_CString line) Standard_Integer Draw_Interpretor::RecordAndEval(const Standard_CString line, const Standard_Integer flags) { - Standard_PCharacter pLine; - // - pLine=(Standard_PCharacter)line; - return Tcl_RecordAndEval(myInterp,pLine,flags); + return Tcl_RecordAndEval(myInterp,line,flags); } //======================================================================= @@ -502,10 +495,7 @@ Standard_Integer Draw_Interpretor::RecordAndEval(const Standard_CString line, Standard_Integer Draw_Interpretor::EvalFile(const Standard_CString fname) { - Standard_PCharacter pfname; - // - pfname=(Standard_PCharacter)fname; - return Tcl_EvalFile(myInterp,pfname); + return Tcl_EvalFile(myInterp,fname); } //======================================================================= diff --git a/src/DrawResources/TestCommands.tcl b/src/DrawResources/TestCommands.tcl index d41ecc3920..2528db63f1 100644 --- a/src/DrawResources/TestCommands.tcl +++ b/src/DrawResources/TestCommands.tcl @@ -2489,3 +2489,56 @@ proc _checkpoint {coord_x coord_y rd_ch gr_ch bl_ch} { } return $mistake } + +# Procedure to check if sequence of values in listval follows linear trend +# adding the same delta on each step. +# +# The function does statistical estimation of the mean variation of the +# values of the sequence, and dispersion, and returns true only if both +# dispersion and deviation of the mean from expected delta are within +# specified tolerance. +# +# If mean variation differs from expected delta on more than two dispersions, +# the check fails and procedure raises error with specified message. +# +# Otherwise the procedure returns false meaning that more iterations are needed. +# Note that false is returned in any case if length of listval is less than 3. +# +# See example of use to check memory leaks in bugs/caf/bug23489 +# +proc checktrend {listval delta tolerance message} { + set nbval [llength $listval] + if { $nbval < 3} { + return 0 + } + + # calculate mean value + set mean 0. + set prev [lindex $listval 0] + foreach val [lrange $listval 1 end] { + set mean [expr $mean + ($val - $prev)] + set prev $val + } + set mean [expr $mean / ($nbval - 1)] + + # calculate dispersion + set sigma 0. + set prev [lindex $listval 0] + foreach val [lrange $listval 1 end] { + set d [expr ($val - $prev) - $mean] + set sigma [expr $sigma + $d * $d] + set prev $val + } + set sigma [expr sqrt ($sigma / ($nbval - 2))] + + puts "Checking trend: nb = $nbval, mean delta = $mean, sigma = $sigma" + + # check if deviation is definitely too big + if { abs ($mean - $delta) > $tolerance + 2. * $sigma } { + puts "Checking trend failed: mean delta per step = $mean, sigma = $sigma, expected delta = $delta" + error "$message" + } + + # check if deviation is clearly within a range + return [expr abs ($mean - $delta) <= $sigma && $sigma <= $tolerance] +} diff --git a/src/IVtkDraw/IVtkDraw.cxx b/src/IVtkDraw/IVtkDraw.cxx index 42ea5007ff..042626a299 100644 --- a/src/IVtkDraw/IVtkDraw.cxx +++ b/src/IVtkDraw/IVtkDraw.cxx @@ -51,7 +51,6 @@ #endif #ifdef _WIN32 -#define _WIN32_WINNT 0x0400 // for TrackMouseEvent support requires Win95 with IE 3.0 or greater. #include #include #include @@ -451,7 +450,7 @@ static Standard_Integer VtkDisplay (Draw_Interpretor& theDI, TCollection_AsciiString aName; TopoDS_Shape anOldShape, aNewShape; - vtkSmartPointer aRenderer = GetRenderer(); + vtkSmartPointer& aRenderer = GetRenderer(); for (Standard_Integer anIndex = 1; anIndex < theArgNum; ++anIndex) { // Get name of shape @@ -494,12 +493,13 @@ static Standard_Integer VtkDisplay (Draw_Interpretor& theDI, { if (aNewShape.IsNull()) continue; // Create actor from DRAW shape - vtkActor* anActor = CreateActor (GenerateId(), aNewShape); + Standard_Integer anId = GenerateId(); + vtkSmartPointer anActor = CreateActor (anId, aNewShape); // Update maps GetMapOfShapes().Bind (aNewShape, aName); GetMapOfActors().Bind (anActor, aName); // Display actor - PipelineByActorName (aName)->AddToRenderer (aRenderer); + GetPipeline(anId)->AddToRenderer(aRenderer); // Compute selection for displayed actors GetPicker()->SetSelectionMode (SM_Shape, Standard_True); @@ -559,6 +559,89 @@ static Standard_Integer VtkErase (Draw_Interpretor& theDI, return 0; } +//================================================================ +// Function : VtkRemove +// Purpose : Remove the actor from memory. +//================================================================ +static Standard_Integer VtkRemove(Draw_Interpretor& theDI, + Standard_Integer theArgNum, + const char** theArgs) +{ + // Check viewer + if (!GetInteractor()->IsEnabled()) + { + theDI << theArgs[0] << " error : call ivtkinit before\n"; + return 1; // TCL_ERROR + } + + vtkSmartPointer aRenderer = GetRenderer(); + + // Remove all objects + if (theArgNum == 1) + { + // Remove all actors from the renderer + DoubleMapOfActorsAndNames::Iterator anIterator(GetMapOfActors()); + while (anIterator.More()) + { + vtkSmartPointer aSrc = + IVtkTools_ShapeObject::GetShapeSource(anIterator.Key1()); + if (aSrc.GetPointer() != NULL && !(aSrc->GetShape().IsNull())) + { + GetPicker()->RemoveSelectableObject(aSrc->GetShape()); + } + else + { + aRenderer->RemoveActor(anIterator.Key1()); + } + anIterator.Next(); + } + // Remove all pipelines from the renderer + for (ShapePipelineMap::Iterator anIt(*GetPipelines()); anIt.More(); anIt.Next()) + { + anIt.Value()->RemoveFromRenderer(aRenderer); + } + // Clear maps and remove all TopoDS_Shapes, actors and pipelines + GetMapOfShapes().Clear(); + GetMapOfActors().Clear(); + GetPipelines()->Clear(); + } + // Remove named objects + else + { + TCollection_AsciiString aName; + for (Standard_Integer anIndex = 1; anIndex < theArgNum; ++anIndex) + { + aName = theArgs[anIndex]; + if (GetMapOfActors().IsBound2(aName)) + { + // Remove the actor and its pipeline (if found) from the renderer + vtkSmartPointer anActor = GetMapOfActors().Find2(aName); + vtkSmartPointer aSrc = + IVtkTools_ShapeObject::GetShapeSource(anActor); + if (aSrc.GetPointer() != NULL && !(aSrc->GetShape().IsNull())) + { + IVtk_IdType aShapeID = aSrc->GetShape()->GetId(); + GetPicker()->RemoveSelectableObject(aSrc->GetShape()); + GetPipeline(aSrc->GetShape()->GetId())->RemoveFromRenderer(aRenderer); + GetPipelines()->UnBind(aShapeID); // Remove a pipepline + } + else + { + aRenderer->RemoveActor(anActor); + } + // Remove the TopoDS_Shape and the actor + GetMapOfShapes().UnBind2(aName); // Remove a TopoDS shape + GetMapOfActors().UnBind2(aName); // Remove an actor + } + } + } + + // Redraw window + aRenderer->ResetCamera(); + GetInteractor()->GetRenderWindow()->Render(); + return 0; +} + //================================================================ // Function : VtkSetDisplayMode // Purpose : @@ -841,7 +924,7 @@ static Standard_Integer VtkSelect (Draw_Interpretor& theDI, return 1; // TCL_ERROR } - Standard_Integer anY = GetInteractor()->GetRenderWindow()->GetSize()[1] - atoi (theArgs[1]) - 1; + Standard_Integer anY = GetInteractor()->GetRenderWindow()->GetSize()[1] - atoi (theArgs[2]) - 1; GetInteractor()->MoveTo (atoi (theArgs[1]), anY); GetInteractor()->OnSelection(); return 0; @@ -1097,6 +1180,12 @@ void IVtkDraw::Commands (Draw_Interpretor& theCommands) "\n\t\t: Removes from renderer named objects or all objects.", __FILE__, VtkErase, group); + theCommands.Add("ivtkremove", + "ivtkremove usage:\n" + "ivtkremove [name1 name2 ...]" + "\n\t\t: Removes from renderer and from memory named objects or all objects.", + __FILE__, VtkRemove, group); + theCommands.Add("ivtksetdispmode", "ivtksetdispmode usage:\n" "ivtksetdispmode [name] mode (0,1)" diff --git a/src/IVtkDraw/IVtkDraw_HighlightAndSelectionPipeline.cxx b/src/IVtkDraw/IVtkDraw_HighlightAndSelectionPipeline.cxx index e6a05975c7..098e94d46a 100644 --- a/src/IVtkDraw/IVtkDraw_HighlightAndSelectionPipeline.cxx +++ b/src/IVtkDraw/IVtkDraw_HighlightAndSelectionPipeline.cxx @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -66,8 +67,8 @@ IVtkDraw_HighlightAndSelectionPipeline::IVtkDraw_HighlightAndSelectionPipeline ( aDMFilter->SetDisplayMode (DM_Wireframe); myMapper = vtkSmartPointer::New(); - myMapper->AddInputConnection (aDMFilter->GetOutputPort()); - myActor->SetMapper (myMapper); + myMapper->AddInputConnection(aDMFilter->GetOutputPort()); + myActor->SetMapper(myMapper); IVtkTools_ShapeObject::SetShapeSource (aDataSource, myActor); myMapper->ScalarVisibilityOn(); @@ -86,7 +87,7 @@ IVtkDraw_HighlightAndSelectionPipeline::IVtkDraw_HighlightAndSelectionPipeline ( // No highligthing exists initially aSUBFilterH->SetInputConnection (aDataSource->GetOutputPort() ); - aDMFilterH->SetInputConnection (aSUBFilterH->GetOutputPort() ); + aDMFilterH->SetInputConnection(aSUBFilterH->GetOutputPort()); myHiliMapper = vtkSmartPointer::New(); myHiliMapper->SetInputConnection (aDMFilterH->GetOutputPort() ); @@ -115,7 +116,7 @@ IVtkDraw_HighlightAndSelectionPipeline::IVtkDraw_HighlightAndSelectionPipeline ( // No highligthing exists initially aSUBFilterS->SetInputConnection (aDataSource->GetOutputPort() ); - aDMFilterS->SetInputConnection (aSUBFilterS->GetOutputPort() ); + aDMFilterS->SetInputConnection(aSUBFilterS->GetOutputPort()); mySelMapper = vtkSmartPointer::New(); mySelMapper->SetInputConnection (aDMFilterS->GetOutputPort() ); @@ -154,6 +155,14 @@ void IVtkDraw_HighlightAndSelectionPipeline::RemoveFromRenderer (vtkRenderer* th theRenderer->RemoveActor (myActor); theRenderer->RemoveActor (myHiliActor); theRenderer->RemoveActor (mySelActor); + + vtkSmartPointer aWin = theRenderer->GetRenderWindow(); + if (aWin != NULL) + { + myActor->ReleaseGraphicsResources(aWin); + myHiliActor->ReleaseGraphicsResources(aWin); + mySelActor->ReleaseGraphicsResources(aWin); + } } //=========================================================== @@ -184,7 +193,7 @@ void IVtkDraw_HighlightAndSelectionPipeline::ClearSelectionFilters() //=========================================================== IVtkTools_DisplayModeFilter* IVtkDraw_HighlightAndSelectionPipeline::GetDisplayModeFilter() { - return IVtkTools_DisplayModeFilter::SafeDownCast (myFilterMap.Find(Filter_DM_Shape) ); + return IVtkTools_DisplayModeFilter::SafeDownCast(myFilterMap.Find(Filter_DM_Shape)); } //=========================================================== @@ -193,7 +202,7 @@ IVtkTools_DisplayModeFilter* IVtkDraw_HighlightAndSelectionPipeline::GetDisplayM //=========================================================== IVtkTools_SubPolyDataFilter* IVtkDraw_HighlightAndSelectionPipeline::GetHighlightFilter() { - return IVtkTools_SubPolyDataFilter::SafeDownCast (myFilterMap.Find (Filter_SUB_Hili) ); + return IVtkTools_SubPolyDataFilter::SafeDownCast(myFilterMap.Find(Filter_SUB_Hili)); } //=========================================================== @@ -202,7 +211,7 @@ IVtkTools_SubPolyDataFilter* IVtkDraw_HighlightAndSelectionPipeline::GetHighligh //=========================================================== IVtkTools_SubPolyDataFilter* IVtkDraw_HighlightAndSelectionPipeline::GetSelectionFilter() { - return IVtkTools_SubPolyDataFilter::SafeDownCast (myFilterMap.Find (Filter_SUB_Sel) ); + return IVtkTools_SubPolyDataFilter::SafeDownCast(myFilterMap.Find(Filter_SUB_Sel)); } //=========================================================== @@ -211,7 +220,7 @@ IVtkTools_SubPolyDataFilter* IVtkDraw_HighlightAndSelectionPipeline::GetSelectio //=========================================================== IVtkTools_DisplayModeFilter* IVtkDraw_HighlightAndSelectionPipeline::GetHighlightDMFilter() { - return IVtkTools_DisplayModeFilter::SafeDownCast (myFilterMap.Find (Filter_DM_Hili) ); + return IVtkTools_DisplayModeFilter::SafeDownCast(myFilterMap.Find(Filter_DM_Hili)); } //=========================================================== @@ -220,7 +229,7 @@ IVtkTools_DisplayModeFilter* IVtkDraw_HighlightAndSelectionPipeline::GetHighligh //=========================================================== IVtkTools_DisplayModeFilter* IVtkDraw_HighlightAndSelectionPipeline::GetSelectionDMFilter() { - return IVtkTools_DisplayModeFilter::SafeDownCast (myFilterMap.Find(Filter_DM_Sel)); + return IVtkTools_DisplayModeFilter::SafeDownCast(myFilterMap.Find(Filter_DM_Sel)); } //=========================================================== diff --git a/src/IVtkDraw/IVtkDraw_Interactor.cxx b/src/IVtkDraw/IVtkDraw_Interactor.cxx index 7c2c84b0e7..8a11eeec7c 100644 --- a/src/IVtkDraw/IVtkDraw_Interactor.cxx +++ b/src/IVtkDraw/IVtkDraw_Interactor.cxx @@ -14,7 +14,6 @@ // commercial license or contractual agreement. #ifdef _WIN32 -#define _WIN32_WINNT 0x0400 // for trackmouseevent support requires Win95 with IE 3.0 or greater. #include #include #include @@ -225,7 +224,7 @@ void IVtkDraw_Interactor::MoveTo (Standard_Integer theX, Standard_Integer theY) { // Processing highlighting mySelector->Pick (theX, theY, 0.0); - vtkActorCollection* anActorCollection = mySelector->GetPickedActors(); + vtkSmartPointer anActorCollection = mySelector->GetPickedActors(); if (anActorCollection) { @@ -290,7 +289,7 @@ void IVtkDraw_Interactor::MoveTo (Standard_Integer theX, Standard_Integer theY) void IVtkDraw_Interactor::OnSelection() { // Processing selection - vtkActorCollection* anActorCollection = mySelector->GetPickedActors(); + vtkSmartPointer anActorCollection = mySelector->GetPickedActors(); if (anActorCollection) { diff --git a/src/IVtkOCC/IVtkOCC_SelectableObject.cxx b/src/IVtkOCC/IVtkOCC_SelectableObject.cxx index 43fb63e867..8e0d54aa69 100644 --- a/src/IVtkOCC/IVtkOCC_SelectableObject.cxx +++ b/src/IVtkOCC/IVtkOCC_SelectableObject.cxx @@ -56,6 +56,13 @@ IVtkOCC_SelectableObject::IVtkOCC_SelectableObject() myShape (0) { } +//============================================================================ +// Method: Destructor +// Purpose: +//============================================================================ +IVtkOCC_SelectableObject::~IVtkOCC_SelectableObject() +{ } + //============================================================================ // Method: SetShape // Purpose: Sets the selectable shape diff --git a/src/IVtkOCC/IVtkOCC_SelectableObject.hxx b/src/IVtkOCC/IVtkOCC_SelectableObject.hxx index 727ec81d7d..faece512ce 100644 --- a/src/IVtkOCC/IVtkOCC_SelectableObject.hxx +++ b/src/IVtkOCC/IVtkOCC_SelectableObject.hxx @@ -22,6 +22,8 @@ #include #include +class IVtkOCC_SelectableObject; +DEFINE_STANDARD_HANDLE(IVtkOCC_SelectableObject, SelectMgr_SelectableObject) // ----------------------------------------------------------------------------- //! @class IVtkOCC_SelectableObject //! @brief Class with selection primitives used by OCCT selection algorithm. @@ -29,6 +31,8 @@ class IVtkOCC_SelectableObject : public SelectMgr_SelectableObject { public: + typedef Handle(IVtkOCC_SelectableObject) Handle; + //! Constructs a selectable object initialized by the given shape //! @param [in] theShape Selectable shape IVtkOCC_SelectableObject (const IVtkOCC_Shape::Handle& theShape); @@ -37,9 +41,11 @@ public: //! setShape() should be called later. IVtkOCC_SelectableObject(); + virtual ~IVtkOCC_SelectableObject(); + //! Sets the selectable shape //! @param [in] theShape Selectable shape - void SetShape (const IVtkOCC_Shape::Handle& theShape); + Standard_EXPORT void SetShape (const IVtkOCC_Shape::Handle& theShape); const IVtkOCC_Shape::Handle& GetShape() const { return myShape; }; @@ -64,6 +70,4 @@ private: Handle(Prs3d_Drawer) myOCCTDrawer; }; -DEFINE_STANDARD_HANDLE( IVtkOCC_SelectableObject, SelectMgr_SelectableObject ) - #endif // __IVTKOCC_SELECTABLEOBJECT_H__ diff --git a/src/IVtkOCC/IVtkOCC_ShapeMesher.cxx b/src/IVtkOCC/IVtkOCC_ShapeMesher.cxx index 2adc977964..241c92c456 100644 --- a/src/IVtkOCC/IVtkOCC_ShapeMesher.cxx +++ b/src/IVtkOCC/IVtkOCC_ShapeMesher.cxx @@ -13,7 +13,6 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#include #include #include #include @@ -107,7 +106,7 @@ Standard_Real IVtkOCC_ShapeMesher::GetDeflection() const //================================================================ void IVtkOCC_ShapeMesher::meshShape() { - TopoDS_Shape anOcctShape = GetShapeObj()->GetShape(); + const TopoDS_Shape& anOcctShape = GetShapeObj()->GetShape(); if (anOcctShape.IsNull()) { return; @@ -164,7 +163,7 @@ void IVtkOCC_ShapeMesher::addFreeVertices() { aType = MT_SharedVertex; } - TopoDS_Vertex aVertex = TopoDS::Vertex (aVertexMap.FindKey (anIt)); + const TopoDS_Vertex& aVertex = TopoDS::Vertex (aVertexMap.FindKey (anIt)); addVertex (aVertex, GetShapeObj()->GetSubShapeId (aVertex), aType); } } @@ -188,7 +187,7 @@ void IVtkOCC_ShapeMesher::addEdges() TopExp_Explorer anEdgeIter (GetShapeObj()->GetShape(), TopAbs_EDGE); for (; anEdgeIter.More(); anEdgeIter.Next()) { - TopoDS_Edge anOcctEdge = TopoDS::Edge (anEdgeIter.Current()); + const TopoDS_Edge& anOcctEdge = TopoDS::Edge (anEdgeIter.Current()); aNbFaces = anEdgesMap.FindFromKey (anOcctEdge).Extent(); if (aNbFaces == 0) { @@ -222,7 +221,7 @@ void IVtkOCC_ShapeMesher::addWireFrameFaces() TopExp_Explorer aFaceIter (GetShapeObj()->GetShape(), TopAbs_FACE); for (; aFaceIter.More(); aFaceIter.Next()) { - TopoDS_Face anOcctFace = TopoDS::Face (aFaceIter.Current()); + const TopoDS_Face& anOcctFace = TopoDS::Face (aFaceIter.Current()); try { OCC_CATCH_SIGNALS @@ -243,7 +242,7 @@ void IVtkOCC_ShapeMesher::addShadedFaces() TopExp_Explorer aFaceIter (GetShapeObj()->GetShape(), TopAbs_FACE); for (; aFaceIter.More(); aFaceIter.Next()) { - TopoDS_Face anOcctFace = TopoDS::Face (aFaceIter.Current()); + const TopoDS_Face& anOcctFace = TopoDS::Face (aFaceIter.Current()); addShadedFace (anOcctFace, GetShapeObj()->GetSubShapeId (anOcctFace)); } @@ -287,7 +286,7 @@ void IVtkOCC_ShapeMesher::processPolyline (Standard_Integer theNbNodes, return; } - IVtk_PointIdList *aPolyPointIds = new IVtk_PointIdList(); + IVtk_PointIdList aPolyPointIds; IVtk_PointId anId; for (Standard_Integer aJ = 0; aJ < theNbNodes; aJ++) @@ -302,12 +301,10 @@ void IVtkOCC_ShapeMesher::processPolyline (Standard_Integer theNbNodes, } anId = myShapeData->InsertCoordinate (point.X(), point.Y(), point.Z()); - aPolyPointIds->Append (anId); + aPolyPointIds.Append (anId); } - myShapeData->InsertLine (theOcctId, aPolyPointIds, theMeshType); - - delete aPolyPointIds; + myShapeData->InsertLine (theOcctId, &aPolyPointIds, theMeshType); } //================================================================ @@ -821,7 +818,7 @@ void IVtkOCC_ShapeMesher::addWFFace (const TopoDS_Face& theFace, TopExp_Explorer anEdgeIter (aFaceToMesh, TopAbs_EDGE ); for (; anEdgeIter.More(); anEdgeIter.Next()) { - TopoDS_Edge anOcctEdge = TopoDS::Edge (anEdgeIter.Current()); + const TopoDS_Edge& anOcctEdge = TopoDS::Edge (anEdgeIter.Current()); addEdge (anOcctEdge, theShapeId, myEdgesTypes (anOcctEdge)); } diff --git a/src/IVtkOCC/IVtkOCC_ShapePickerAlgo.cxx b/src/IVtkOCC/IVtkOCC_ShapePickerAlgo.cxx index b3c08bd681..dca1ebf01f 100644 --- a/src/IVtkOCC/IVtkOCC_ShapePickerAlgo.cxx +++ b/src/IVtkOCC/IVtkOCC_ShapePickerAlgo.cxx @@ -259,9 +259,7 @@ void IVtkOCC_ShapePickerAlgo::SubShapesPicked (const IVtk_IdType theId, IVtk_Sha { if (mySubShapesPicked.IsBound (theId)) { - // Need non-const this to call the map's operator[] - IVtkOCC_ShapePickerAlgo* that = const_cast< IVtkOCC_ShapePickerAlgo* >(this); - theShapeList = that->mySubShapesPicked (theId); + theShapeList = mySubShapesPicked (theId); } } @@ -354,3 +352,23 @@ bool IVtkOCC_ShapePickerAlgo::processPicked() return !myShapesPicked.IsEmpty(); } + +//============================================================================ +// Method: RemoveSelectableActor +// Purpose: Remove selectable object from the picker (from internal maps). +//============================================================================ +void IVtkOCC_ShapePickerAlgo::RemoveSelectableObject(const IVtk_IShape::Handle& theShape) +{ + clearPicked(); + // Get shape implementation from shape interface. + Handle(IVtkOCC_Shape) aShapeImpl = + Handle(IVtkOCC_Shape)::DownCast(theShape); + + // Get selectable object from the shape implementation. + Handle(IVtkOCC_SelectableObject) aSelObj = + Handle(IVtkOCC_SelectableObject)::DownCast(aShapeImpl->GetSelectableObject()); + + myViewerSelector->RemoveSelectableObject(aSelObj); + myViewerSelector->Clear(); + aShapeImpl->SetSelectableObject(NULL); +} \ No newline at end of file diff --git a/src/IVtkOCC/IVtkOCC_ShapePickerAlgo.hxx b/src/IVtkOCC/IVtkOCC_ShapePickerAlgo.hxx index 1092661ed1..fb452a4cc0 100644 --- a/src/IVtkOCC/IVtkOCC_ShapePickerAlgo.hxx +++ b/src/IVtkOCC/IVtkOCC_ShapePickerAlgo.hxx @@ -96,6 +96,10 @@ public: //! @name Obtain picking results Standard_EXPORT virtual void SubShapesPicked (const IVtk_IdType theId, IVtk_ShapeIdList& theShapeList) const Standard_OVERRIDE; + //! Remove selectable object from the picker (from internal maps). + //! @param [in] theShape the selectable shape + Standard_EXPORT virtual void RemoveSelectableObject(const IVtk_IShape::Handle& theShape); + public: DEFINE_STANDARD_RTTIEXT(IVtkOCC_ShapePickerAlgo,IVtk_IShapePickerAlgo) diff --git a/src/IVtkOCC/IVtkOCC_ViewerSelector.cxx b/src/IVtkOCC/IVtkOCC_ViewerSelector.cxx index 18f05c5c83..76f115910f 100644 --- a/src/IVtkOCC/IVtkOCC_ViewerSelector.cxx +++ b/src/IVtkOCC/IVtkOCC_ViewerSelector.cxx @@ -28,7 +28,17 @@ IMPLEMENT_STANDARD_RTTIEXT(IVtkOCC_ViewerSelector,SelectMgr_ViewerSelector) IVtkOCC_ViewerSelector::IVtkOCC_ViewerSelector() : SelectMgr_ViewerSelector(), myPixTol(2), -myToUpdateTol(Standard_True) {} +myToUpdateTol(Standard_True) +{ +} + +//============================================================================ +// Method: Destructor +// Purpose: +//============================================================================ +IVtkOCC_ViewerSelector::~IVtkOCC_ViewerSelector() +{ +} //============================================================================ // Method: Pick diff --git a/src/IVtkOCC/IVtkOCC_ViewerSelector.hxx b/src/IVtkOCC/IVtkOCC_ViewerSelector.hxx index dd44bce24b..58a4ef9bb4 100644 --- a/src/IVtkOCC/IVtkOCC_ViewerSelector.hxx +++ b/src/IVtkOCC/IVtkOCC_ViewerSelector.hxx @@ -31,6 +31,8 @@ class IVtkOCC_ViewerSelector : public SelectMgr_ViewerSelector public: IVtkOCC_ViewerSelector(); + virtual ~IVtkOCC_ViewerSelector(); + //! Implements point picking //! @param [in] theXPix, theYPix Display coordinates of the point //! @param [in] theView ICamera interface to update the projection parameters. diff --git a/src/IVtkTools/IVtkTools.cxx b/src/IVtkTools/IVtkTools.cxx index 5de6bbf887..8a93a3e91a 100644 --- a/src/IVtkTools/IVtkTools.cxx +++ b/src/IVtkTools/IVtkTools.cxx @@ -24,9 +24,10 @@ namespace IVtkTools // Method: InitLookupTable // Purpose: Returns vtkLookupTable instance initialized by standrad OCCT colors. //============================================================================ -vtkLookupTable* InitLookupTable() +vtkSmartPointer InitLookupTable() { - vtkLookupTable* aColorTable = vtkLookupTable::New(); + vtkSmartPointer aColorTable = + vtkSmartPointer::New(); // Set colors table for 3D shapes double aRange[2]; aRange[0] = MT_Undefined; diff --git a/src/IVtkTools/IVtkTools.hxx b/src/IVtkTools/IVtkTools.hxx index 2cd9648366..d814148fa9 100644 --- a/src/IVtkTools/IVtkTools.hxx +++ b/src/IVtkTools/IVtkTools.hxx @@ -17,6 +17,7 @@ #define IVtkTOOLS_H #include +#include #if defined(_WIN32) && !defined(HAVE_NO_DLL) #ifdef __IVtkTools_DLL @@ -38,7 +39,7 @@ namespace IVtkTools //! Returns vtkLookupTable instance initialized by standrad OCCT colors used //! in wireframe mode for different kinds of sub-shapes (free/boundary/shared //! edges, isolines,...) - Standard_EXPORT vtkLookupTable* InitLookupTable(); + Standard_EXPORT vtkSmartPointer InitLookupTable(); //! Set a color for given type of sub-shapes. //! @param [in,out] theColorTable vtkLookupTable to set the color. diff --git a/src/IVtkTools/IVtkTools_DisplayModeFilter.hxx b/src/IVtkTools/IVtkTools_DisplayModeFilter.hxx index b029eddbe6..1bb6e4a6a1 100644 --- a/src/IVtkTools/IVtkTools_DisplayModeFilter.hxx +++ b/src/IVtkTools/IVtkTools_DisplayModeFilter.hxx @@ -18,7 +18,6 @@ #include #include -#include #include //! @class IVtkTools_DisplayModeFilter @@ -47,7 +46,7 @@ protected: virtual int RequestData (vtkInformation *, vtkInformationVector **, vtkInformationVector *); IVtkTools_DisplayModeFilter(); - ~IVtkTools_DisplayModeFilter(); + virtual ~IVtkTools_DisplayModeFilter(); protected: //! Display mode defining mesh types to pass through this filter. diff --git a/src/IVtkTools/IVtkTools_ShapeDataSource.cxx b/src/IVtkTools/IVtkTools_ShapeDataSource.cxx index eba9873e4e..2d4f4c2f0d 100644 --- a/src/IVtkTools/IVtkTools_ShapeDataSource.cxx +++ b/src/IVtkTools/IVtkTools_ShapeDataSource.cxx @@ -14,20 +14,17 @@ // commercial license or contractual agreement. // VIS includes -#include #include +#include #include // VTK includes -#include +#include #include -#include #include #include -#include #include #include -#include #include #include @@ -42,7 +39,8 @@ IVtkTools_ShapeDataSource::IVtkTools_ShapeDataSource() myIsFastTransformMode (Standard_False), myIsTransformOnly (Standard_False) { - this->SetNumberOfInputPorts (0); + this->SetNumberOfInputPorts(0); + this->SetNumberOfOutputPorts(1); } //================================================================ @@ -85,73 +83,75 @@ IVtkOCC_Shape::Handle IVtkTools_ShapeDataSource::GetShape() // Function : RequestData // Purpose : //================================================================ -int IVtkTools_ShapeDataSource::RequestData (vtkInformation* theRequest, - vtkInformationVector** theInputVector, - vtkInformationVector* theOutputVector) +int IVtkTools_ShapeDataSource::RequestData(vtkInformation *vtkNotUsed(theRequest), + vtkInformationVector **vtkNotUsed(theInputVector), + vtkInformationVector *theOutputVector) { - vtkPolyData* aPolyData = vtkPolyData::GetData (theOutputVector); - aPolyData->Allocate(); - vtkPoints* aPts = vtkPoints::New(); - aPolyData->SetPoints (aPts); - aPts->Delete(); - - vtkSmartPointer aTransformedData; - TopoDS_Shape aShape = myOccShape->GetShape(); - TopLoc_Location aShapeLoc = aShape.Location(); - - if (myIsTransformOnly) + vtkSmartPointer aPolyData = vtkPolyData::GetData (theOutputVector); + if (aPolyData.GetPointer() != NULL) { - vtkPolyData* aPrevData = myPolyData->getVtkPolyData(); - if (!aShapeLoc.IsIdentity() ) + aPolyData->Allocate(); + vtkSmartPointer aPts = vtkSmartPointer::New(); + aPolyData->SetPoints (aPts); + + vtkSmartPointer aTransformedData; + TopoDS_Shape aShape = myOccShape->GetShape(); + TopLoc_Location aShapeLoc = aShape.Location(); + + if (myIsTransformOnly) { - aTransformedData = this->transform (aPrevData, aShapeLoc); + vtkSmartPointer aPrevData = myPolyData->getVtkPolyData(); + if ( !aShapeLoc.IsIdentity() ) + { + aTransformedData = this->transform (aPrevData, aShapeLoc); + } + else + { + aTransformedData = aPrevData; + } } else { - aTransformedData = aPrevData; - } - } - else - { - IVtkOCC_Shape::Handle aShapeWrapperCopy; - if (myIsFastTransformMode && !aShapeLoc.IsIdentity() ) - { - // Reset location before meshing - aShape.Location (TopLoc_Location() ); - aShapeWrapperCopy = new IVtkOCC_Shape (aShape); - aShapeWrapperCopy->SetId (myOccShape->GetId() ); - } - else - { - aShapeWrapperCopy = myOccShape; + IVtkOCC_Shape::Handle aShapeWrapperCopy; + if ( myIsFastTransformMode && !aShapeLoc.IsIdentity() ) + { + // Reset location before meshing + aShape.Location (TopLoc_Location()); + aShapeWrapperCopy = new IVtkOCC_Shape (aShape); + aShapeWrapperCopy->SetId (myOccShape->GetId()); + } + else + { + aShapeWrapperCopy = myOccShape; + } + + myPolyData = new IVtkVTK_ShapeData; + IVtkOCC_ShapeMesher::Handle aMesher = new IVtkOCC_ShapeMesher; + aMesher->Build (aShapeWrapperCopy, myPolyData); + vtkSmartPointer aMeshData = myPolyData->getVtkPolyData(); + + if ( myIsFastTransformMode && !aShapeLoc.IsIdentity() ) + { + aTransformedData = this->transform (aMeshData, aShapeLoc); + } + else + { + aTransformedData = aMeshData; + } } - myPolyData = new IVtkVTK_ShapeData; - IVtkOCC_ShapeMesher::Handle aMesher = new IVtkOCC_ShapeMesher; - aMesher->Build (aShapeWrapperCopy, myPolyData); - vtkPolyData* aMeshData = myPolyData->getVtkPolyData(); + aPolyData->CopyStructure (aTransformedData); // Copy points and cells + aPolyData->CopyAttributes (aTransformedData); // Copy data arrays (sub-shapes IDs) - if (myIsFastTransformMode && !aShapeLoc.IsIdentity() ) - { - aTransformedData = this->transform (aMeshData, aShapeLoc); - } - else - { - aTransformedData = aMeshData; - } + // We store the OccShape instance in a IVtkTools_ShapeObject + // wrapper in vtkInformation object of vtkDataObject, then pass it + // to the actors through pipelines, so selection logic can access + // OccShape easily given the actor instance. + IVtkTools_ShapeObject::SetShapeSource (this, aPolyData); + aPolyData->GetAttributes (vtkDataObject::CELL)->SetPedigreeIds (SubShapeIDs()); } - aPolyData->CopyStructure (aTransformedData); // Copy points and cells - aPolyData->CopyAttributes (aTransformedData); // Copy data arrays (sub-shapes IDs) - - // We store the OccShape instance in a IVtkTools_ShapeObject - // wrapper in vtkInformation object of vtkDataObject, then pass it - // to the actors through pipelines, so selection logic can access - // OccShape easily given the actor instance. - IVtkTools_ShapeObject::SetShapeSource (this, aPolyData); - aPolyData->GetAttributes (vtkDataObject::CELL)->SetPedigreeIds (SubShapeIDs() ); - - return Superclass::RequestData (theRequest, theInputVector, theOutputVector); + return 1; } //================================================================ @@ -160,8 +160,10 @@ int IVtkTools_ShapeDataSource::RequestData (vtkInformation* theRequest, //================================================================ vtkSmartPointer IVtkTools_ShapeDataSource::SubShapeIDs() { - vtkDataArray* arr = GetOutput()->GetCellData()->GetArray(IVtkVTK_ShapeData::ARRNAME_SUBSHAPE_IDS); - return vtkSmartPointer( vtkIdTypeArray::SafeDownCast(arr) ); + vtkSmartPointer arr = + GetOutput()->GetCellData()->GetArray(IVtkVTK_ShapeData::ARRNAME_SUBSHAPE_IDS); + return vtkSmartPointer( + vtkIdTypeArray::SafeDownCast(arr.GetPointer()) ); } //================================================================ @@ -210,7 +212,7 @@ vtkSmartPointer IVtkTools_ShapeDataSource::transform (vtkPolyData* aTrsfFilter->SetInputData (theSource); aTrsfFilter->Update(); - vtkPolyData* aTransformed = aTrsfFilter->GetOutput(); + vtkSmartPointer aTransformed = aTrsfFilter->GetOutput(); aResult->CopyStructure (aTransformed); // Copy points and cells aResult->CopyAttributes (aTransformed); // Copy data arrays (sub-shapes ids) diff --git a/src/IVtkTools/IVtkTools_ShapeDataSource.hxx b/src/IVtkTools/IVtkTools_ShapeDataSource.hxx index 6aa56688bb..a3a77f684d 100644 --- a/src/IVtkTools/IVtkTools_ShapeDataSource.hxx +++ b/src/IVtkTools/IVtkTools_ShapeDataSource.hxx @@ -19,10 +19,7 @@ #include #include #include -#include #include -#include -#include class vtkIdTypeArray; class vtkPolyData; @@ -91,7 +88,7 @@ protected: //! @name Internals protected: IVtkTools_ShapeDataSource(); - ~IVtkTools_ShapeDataSource(); + virtual ~IVtkTools_ShapeDataSource(); private: diff --git a/src/IVtkTools/IVtkTools_ShapeObject.cxx b/src/IVtkTools/IVtkTools_ShapeObject.cxx index c45148ee64..a0fdbc4235 100644 --- a/src/IVtkTools/IVtkTools_ShapeObject.cxx +++ b/src/IVtkTools/IVtkTools_ShapeObject.cxx @@ -16,12 +16,10 @@ #include #include #include -#include #include #include #include #include -#include #include IVtkTools_ShapeObject::KeyPtr IVtkTools_ShapeObject::myKey = 0; @@ -49,8 +47,9 @@ IVtkTools_ShapeObject::KeyPtr IVtkTools_ShapeObject::getKey() IVtkOCC_Shape::Handle IVtkTools_ShapeObject::GetOccShape (vtkActor* theActor) { IVtkOCC_Shape::Handle anOccShape; - IVtkTools_ShapeDataSource* aSrc = IVtkTools_ShapeObject::GetShapeSource (theActor); - if (aSrc) + vtkSmartPointer aSrc = + IVtkTools_ShapeObject::GetShapeSource (theActor); + if (aSrc.GetPointer() != NULL) { anOccShape = aSrc->GetShape(); } @@ -62,16 +61,18 @@ IVtkOCC_Shape::Handle IVtkTools_ShapeObject::GetOccShape (vtkActor* theActor) // Purpose: Static method to get OCC shape source from VTK actor's data from // information object by key. //============================================================================ -IVtkTools_ShapeDataSource* IVtkTools_ShapeObject::GetShapeSource (vtkActor* theActor) +vtkSmartPointer IVtkTools_ShapeObject +::GetShapeSource (vtkActor* theActor) { - IVtkTools_ShapeDataSource* anOccShapeSource = 0; - vtkInformation* anInfo = theActor->GetPropertyKeys(); - if (anInfo) + vtkSmartPointer anOccShapeSource; + vtkSmartPointer anInfo = theActor->GetPropertyKeys(); + if (anInfo.GetPointer() != NULL) { KeyPtr aKey = getKey(); if (aKey->Has(anInfo)) { - IVtkTools_ShapeObject* aShapeObj = (IVtkTools_ShapeObject*)(aKey->Get (anInfo)); + vtkSmartPointer aShapeObj = + IVtkTools_ShapeObject::SafeDownCast(aKey->Get (anInfo)); anOccShapeSource = aShapeObj->GetShapeSource(); } } @@ -88,14 +89,14 @@ void IVtkTools_ShapeObject::SetShapeSource (IVtkTools_ShapeDataSource* theDataSo { if (!theDataSet->GetInformation() ) { - theDataSet->SetInformation (vtkInformation::New()); + theDataSet->SetInformation (vtkSmartPointer::New()); } - vtkInformation* aDatasetInfo = theDataSet->GetInformation(); + vtkSmartPointer aDatasetInfo = theDataSet->GetInformation(); KeyPtr aKey = getKey(); - IVtkTools_ShapeObject* aShapeObj = IVtkTools_ShapeObject::New(); + vtkSmartPointer aShapeObj = + vtkSmartPointer::New(); aShapeObj->SetShapeSource (theDataSource); aKey->Set(aDatasetInfo, aShapeObj); - aShapeObj->Delete(); } //============================================================================ @@ -108,15 +109,15 @@ void IVtkTools_ShapeObject::SetShapeSource (IVtkTools_ShapeDataSource* theDataSo { if ( !theActor->GetPropertyKeys() ) { - theActor->SetPropertyKeys (vtkInformation::New()); + theActor->SetPropertyKeys (vtkSmartPointer::New()); } - vtkInformation* anInfo = theActor->GetPropertyKeys(); + vtkSmartPointer anInfo = theActor->GetPropertyKeys(); KeyPtr aKey = getKey(); - IVtkTools_ShapeObject* aShapeObj = IVtkTools_ShapeObject::New(); - aShapeObj->SetShapeSource (theDataSource); + vtkSmartPointer aShapeObj = + vtkSmartPointer::New(); + aShapeObj->SetShapeSource(theDataSource); aKey->Set (anInfo, aShapeObj); - aShapeObj->Delete(); } //! @class IVtkTools_ShapeObject @@ -150,7 +151,7 @@ void IVtkTools_ShapeObject::SetShapeSource (IVtkTools_ShapeDataSource* theDataSo // Method: GetShapeSource // Purpose: //============================================================================ -IVtkTools_ShapeDataSource* IVtkTools_ShapeObject::GetShapeSource () const +IVtkTools_ShapeDataSource* IVtkTools_ShapeObject::GetShapeSource() const { return myShapeSource; } diff --git a/src/IVtkTools/IVtkTools_ShapeObject.hxx b/src/IVtkTools/IVtkTools_ShapeObject.hxx index db46437ca6..936c1ad113 100644 --- a/src/IVtkTools/IVtkTools_ShapeObject.hxx +++ b/src/IVtkTools/IVtkTools_ShapeObject.hxx @@ -20,7 +20,7 @@ #include #include #include -#include +#include class vtkActor; class vtkDataSet; @@ -42,7 +42,7 @@ public: static IVtkTools_ShapeObject* New(); //! Get OCC shape source from VTK data from actor's information object by key. - static IVtkTools_ShapeDataSource* GetShapeSource (vtkActor* theActor); + static vtkSmartPointer GetShapeSource (vtkActor* theActor); //! Get OCC shape from VTK data from actor's information object by key. static IVtkOCC_Shape::Handle GetOccShape (vtkActor* theActor); @@ -66,18 +66,18 @@ public: void SetShapeSource (IVtkTools_ShapeDataSource* theDataSource); //! OCC shape source getter. - IVtkTools_ShapeDataSource* GetShapeSource () const; + IVtkTools_ShapeDataSource* GetShapeSource() const; protected: IVtkTools_ShapeObject(); - ~IVtkTools_ShapeObject(); + virtual ~IVtkTools_ShapeObject(); private: // not copyable IVtkTools_ShapeObject (const IVtkTools_ShapeObject&); IVtkTools_ShapeObject& operator= (const IVtkTools_ShapeObject&); private: // OCC - vtkSmartPointer myShapeSource; + vtkWeakPointer myShapeSource; static KeyPtr myKey; }; diff --git a/src/IVtkTools/IVtkTools_ShapePicker.cxx b/src/IVtkTools/IVtkTools_ShapePicker.cxx index 6091f63182..0d5b8e838d 100644 --- a/src/IVtkTools/IVtkTools_ShapePicker.cxx +++ b/src/IVtkTools/IVtkTools_ShapePicker.cxx @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -37,7 +36,7 @@ vtkStandardNewMacro(IVtkTools_ShapePicker) // Purpose: Constructs the picker with empty renderer and ready for point selection. //============================================================================ IVtkTools_ShapePicker::IVtkTools_ShapePicker() -: myRenderer (0), +: myRenderer (NULL), myIsRectSelection (false) { myOccPickerAlgo = new IVtkOCC_ShapePickerAlgo(); @@ -81,7 +80,8 @@ bool IVtkTools_ShapePicker::convertDisplayToWorld (vtkRenderer *theRenderer, theRenderer->SetDisplayPoint (theDisplayCoord[0], theDisplayCoord[1], theDisplayCoord[2]); theRenderer->DisplayToWorld(); - double* const aCoords = theRenderer->GetWorldPoint(); + double aCoords[4]; + theRenderer->GetWorldPoint(aCoords); if (aCoords[3] == 0.0) { return false; @@ -91,6 +91,7 @@ bool IVtkTools_ShapePicker::convertDisplayToWorld (vtkRenderer *theRenderer, { theWorldCoord[anI] = aCoords[anI] / aCoords[3]; } + return true; } @@ -144,7 +145,7 @@ int IVtkTools_ShapePicker::pick (double* thePos, // Emit StartPickEvent for observer callbacks (if any) InvokeEvent(vtkCommand::StartPickEvent, NULL); - vtkRenderer* aRenderer; + vtkSmartPointer aRenderer; if (theRenderer == NULL) { aRenderer = myRenderer; // by default use own renderer @@ -192,7 +193,7 @@ void IVtkTools_ShapePicker::doPickImpl (double* thePos, //============================================================================ void IVtkTools_ShapePicker::SetRenderer (vtkRenderer* theRenderer) { - if (theRenderer == myRenderer) + if (theRenderer == myRenderer.GetPointer()) { return; // In this case we should not do anything. @@ -273,12 +274,13 @@ void IVtkTools_ShapePicker::SetSelectionMode (vtkActor* theShapeA void IVtkTools_ShapePicker::SetSelectionMode (const IVtk_SelectionMode theMode, const bool theIsTurnOn) const { - if (myRenderer) + if (myRenderer.GetPointer() != NULL) { // Obtain all OccShapes displayed and activate the specified selection mode - vtkActorCollection *anActors = myRenderer->GetActors(); + vtkSmartPointer anActors = myRenderer->GetActors(); anActors->InitTraversal(); - while ( vtkActor* anActor = anActors->GetNextActor() ) + vtkSmartPointer anActor = anActors->GetNextActor(); + while ( anActor.GetPointer() != NULL ) { if (anActor->GetPickable() && anActor->GetVisibility()) { @@ -291,6 +293,7 @@ void IVtkTools_ShapePicker::SetSelectionMode (const IVtk_SelectionMode theMode, } } } + anActor = anActors->GetNextActor(); } } } @@ -315,6 +318,28 @@ IVtk_ShapeIdList IVtkTools_ShapePicker::GetPickedShapesIds (bool theIsAll) const return aRes; } +//============================================================================ +// Method: RemoveSelectableActor +// Purpose: Remove selectable object from the picker (from internal maps). +//============================================================================ +void IVtkTools_ShapePicker::RemoveSelectableObject(const IVtk_IShape::Handle& theShape) +{ + myOccPickerAlgo->RemoveSelectableObject(theShape); +} + +//============================================================================ +// Method: RemoveSelectableActor +// Purpose: Remove selectable object from the picker (from internal maps). +//============================================================================ +void IVtkTools_ShapePicker::RemoveSelectableActor(vtkActor* theShapeActor) +{ + IVtk_IShape::Handle aShape = IVtkTools_ShapeObject::GetOccShape(theShapeActor); + if (!aShape.IsNull()) + { + RemoveSelectableObject(aShape); + } +} + //============================================================================ // Method: GetPickedSubShapesIds // Purpose: Access to the list of sub-shapes ids picked. @@ -324,7 +349,7 @@ IVtk_ShapeIdList IVtkTools_ShapePicker::GetPickedSubShapesIds (const IVtk_IdType IVtk_ShapeIdList aRes; if (theIsAll) { - myOccPickerAlgo->SubShapesPicked (theId,aRes); + myOccPickerAlgo->SubShapesPicked (theId, aRes); } else { @@ -342,16 +367,17 @@ IVtk_ShapeIdList IVtkTools_ShapePicker::GetPickedSubShapesIds (const IVtk_IdType // Method: GetPickedActors // Purpose: Access to the list of actors picked. //============================================================================ -vtkActorCollection* IVtkTools_ShapePicker::GetPickedActors (bool theIsAll) const +vtkSmartPointer IVtkTools_ShapePicker::GetPickedActors (bool theIsAll) const { - vtkActorCollection* aRes = vtkActorCollection::New(); + vtkSmartPointer aRes = vtkSmartPointer::New(); IVtk_ShapeIdList anIds = GetPickedShapesIds (theIsAll); - if (myRenderer) + if (myRenderer.GetPointer() != NULL) { // Obtain all actors whose source shape ids are within selected ids. - vtkActorCollection *anActors = myRenderer->GetActors(); + vtkSmartPointer anActors = myRenderer->GetActors(); anActors->InitTraversal(); - while ( vtkActor* anActor = anActors->GetNextActor() ) + vtkSmartPointer anActor = anActors->GetNextActor(); + while ( anActor.GetPointer() != NULL ) { if (anActor->GetPickable() && anActor->GetVisibility()) { @@ -370,6 +396,7 @@ vtkActorCollection* IVtkTools_ShapePicker::GetPickedActors (bool theIsAll) const } } } + anActor = anActors->GetNextActor(); } } return aRes; diff --git a/src/IVtkTools/IVtkTools_ShapePicker.hxx b/src/IVtkTools/IVtkTools_ShapePicker.hxx index 67a69cd2c2..671fc726b5 100644 --- a/src/IVtkTools/IVtkTools_ShapePicker.hxx +++ b/src/IVtkTools/IVtkTools_ShapePicker.hxx @@ -20,6 +20,7 @@ #include #include #include +#include class vtkRenderer; class vtkActorCollection; @@ -79,9 +80,9 @@ public: const bool theIsTurnOn = true) const; //! Turn on/off a selection mode for a shape actor. - //! @param [in] shapeActor shape presentation actor to set a selection mode for - //! @param [in] mode selection mode to be activated - //! @param [in] turnOn Flag to turn on/off the selection mode + //! @param [in] theShapeActor shape presentation actor to set a selection mode for + //! @param [in] theMode selection mode to be activated + //! @param [in] theIsTurnOn Flag to turn on/off the selection mode void SetSelectionMode (vtkActor* theShapeActor, const IVtk_SelectionMode theMode, const bool theIsTurnOn = true) const; @@ -99,29 +100,37 @@ public: //! all OccShape objects found by the picking algorithm. e.g. all //! shapes under the mouse cursor. Otherwise, ID of the shape closest to the eye //! is returned. - //! @param [in] all Controls if all selected shapes or just the only + //! @param [in] theIsAll Get all selected shapes or just the only //! top one is returned, has no effect during area selection. //! @return List of top-level shape IDs IVtk_ShapeIdList GetPickedShapesIds (bool theIsAll = false) const; //! Access to the list of sub-shapes ids picked. - //! @param [in] id top-level shape ID - //! @param [in] all Controls if all selected sub-shapes or just the + //! @param [in] theId top-level shape ID + //! @param [in] theIsAll Get all selected sub-shapes or just the //! only top one is returned, has no effect during area selection. //! @return List of sub-shapes IDs IVtk_ShapeIdList GetPickedSubShapesIds (const IVtk_IdType theId, bool theIsAll = false) const; //! Access to the list of actors picked. - //! @param [in] all Controls if all selected actors or just the only + //! @param [in] theIsAll Get all selected actors or just the only //! top one is returned, has no effect during area selection. //! @return List of actors IDs - vtkActorCollection* GetPickedActors (bool theIsAll = false) const; + vtkSmartPointer GetPickedActors (bool theIsAll = false) const; + + //! Remove selectable object from the picker (from internal maps). + //! @param [in] theShape the selectable shape + void RemoveSelectableObject(const IVtk_IShape::Handle& theShape); + + //! Remove selectable object from the picker (from internal maps). + //! @param [in] theShapeActor the shape presentation actor to be removed from the picker + void RemoveSelectableActor(vtkActor* theShapeActor); protected: //! Constructs the picker with empty renderer and ready for point selection. IVtkTools_ShapePicker(); //! Destructor - ~IVtkTools_ShapePicker(); + virtual ~IVtkTools_ShapePicker(); //! Convert display coordinates to world coordinates static bool convertDisplayToWorld (vtkRenderer *theRenderer, @@ -143,7 +152,7 @@ private: // not copyable private: IVtkOCC_ShapePickerAlgo::Handle myOccPickerAlgo; //!< Picking algorithm implementation - vtkRenderer* myRenderer; //!< VTK renderer + vtkSmartPointer myRenderer; //!< VTK renderer bool myIsRectSelection;//!< Rectangle selection mode flag bool myIsPolySelection;//!< Polyline selection mode flag float myTolerance; //!< Selectoin tolerance diff --git a/src/IVtkTools/IVtkTools_SubPolyDataFilter.cxx b/src/IVtkTools/IVtkTools_SubPolyDataFilter.cxx index 1c75e6e0ec..36860ec23a 100644 --- a/src/IVtkTools/IVtkTools_SubPolyDataFilter.cxx +++ b/src/IVtkTools/IVtkTools_SubPolyDataFilter.cxx @@ -15,12 +15,12 @@ #include #include -#include +#include +#include +#include #include #include #include -#include -#include vtkStandardNewMacro(IVtkTools_SubPolyDataFilter) @@ -50,27 +50,29 @@ int IVtkTools_SubPolyDataFilter::RequestData (vtkInformation *vtkNotUsed(theRequ vtkInformationVector *theOutputVector) { // get the input and output - vtkInformation *anInInfo = theInputVector[0]->GetInformationObject(0); - vtkInformation *anOutInfo = theOutputVector->GetInformationObject(0); + vtkSmartPointer anInInfo = theInputVector[0]->GetInformationObject(0); + vtkSmartPointer anOutInfo = theOutputVector->GetInformationObject(0); - vtkPolyData *anInput = vtkPolyData::SafeDownCast( + vtkSmartPointer anInput = vtkPolyData::SafeDownCast( anInInfo->Get (vtkDataObject::DATA_OBJECT())); - vtkPolyData *anOutput = vtkPolyData::SafeDownCast( + vtkSmartPointer anOutput = vtkPolyData::SafeDownCast( anOutInfo->Get (vtkDataObject::DATA_OBJECT())); - vtkIdList *anIdList = vtkIdList::New(); // List of cell ids to be passed - anIdList->Allocate(myIdsSet.Extent()); // Allocate the list of ids - anInput->Modified(); if (myDoFiltering) { - vtkCellData* aCellData = anInput->GetCellData(); + vtkSmartPointer aCellData = anInput->GetCellData(); int aSize = 0; - vtkIdTypeArray* aDataArray = vtkIdTypeArray::SafeDownCast (aCellData->GetArray (myIdsArrayName)); + vtkSmartPointer aDataArray = + vtkIdTypeArray::SafeDownCast (aCellData->GetArray (myIdsArrayName)); - if(aDataArray != NULL) + // List of cell ids to be passed + vtkSmartPointer anIdList = vtkSmartPointer::New(); + anIdList->Allocate(myIdsSet.Extent()); // Allocate the list of ids + + if (aDataArray.GetPointer() != NULL) { aSize = aDataArray->GetNumberOfTuples(); anIdList->Allocate (aSize); // Allocate the list of ids @@ -95,14 +97,15 @@ int IVtkTools_SubPolyDataFilter::RequestData (vtkInformation *vtkNotUsed(theRequ anOutput->Allocate(anInput, anIdList->GetNumberOfIds()); // Allocate output cells // Pass data arrays. // Create new arrays for output data - vtkCellData *const anInData = anInput->GetCellData(); - vtkCellData *const anOutData = anOutput->GetCellData(); - vtkDataArray *anOutArr, *anInArr; + vtkSmartPointer anInData = anInput->GetCellData(); + vtkSmartPointer anOutData = anOutput->GetCellData(); + vtkSmartPointer anInArr, anOutArr; for (Standard_Integer anI = 0; anI < anInData->GetNumberOfArrays(); anI++) { anInArr = anInData->GetArray (anI); - anOutArr = vtkDataArray::CreateDataArray(anInArr->GetDataType()); + anOutArr = vtkSmartPointer::Take( + vtkDataArray::CreateDataArray(anInArr->GetDataType())); anOutArr->SetName(anInArr->GetName()); anOutArr->Allocate(anIdList->GetNumberOfIds() * anInArr->GetNumberOfComponents()); anOutArr->SetNumberOfTuples (anIdList->GetNumberOfIds()); @@ -119,16 +122,13 @@ int IVtkTools_SubPolyDataFilter::RequestData (vtkInformation *vtkNotUsed(theRequ for (Standard_Integer anI = 0; anI < anInData->GetNumberOfArrays(); anI++) { anInArr = anInData->GetArray (anI); - anOutArr = anOutData->GetArray (anI); + anOutArr = anOutData->GetArray(anI); for (anOutId = 0; anOutId < anIdList->GetNumberOfIds(); anOutId++) { anInId = anIdList->GetId (anOutId); anOutArr->SetTuple (anOutId, anInId, anInArr); } } - - anIdList->Delete(); - } else { diff --git a/src/IVtkTools/IVtkTools_SubPolyDataFilter.hxx b/src/IVtkTools/IVtkTools_SubPolyDataFilter.hxx index d6072f2d85..a24b0b6ea4 100644 --- a/src/IVtkTools/IVtkTools_SubPolyDataFilter.hxx +++ b/src/IVtkTools/IVtkTools_SubPolyDataFilter.hxx @@ -19,7 +19,6 @@ #include #include "vtkPolyDataAlgorithm.h" -#include //! @class IVtkTools_SubPolyDataFilter //! @brief Cells filter according to the given set of cells ids. @@ -57,7 +56,7 @@ protected: virtual int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *); IVtkTools_SubPolyDataFilter(); - ~IVtkTools_SubPolyDataFilter(); + virtual ~IVtkTools_SubPolyDataFilter(); protected: //! Set of ids to be passed through this filter. diff --git a/src/IVtkVTK/IVtkVTK_ShapeData.cxx b/src/IVtkVTK/IVtkVTK_ShapeData.cxx index 5714595c9e..c05c28b201 100644 --- a/src/IVtkVTK/IVtkVTK_ShapeData.cxx +++ b/src/IVtkVTK/IVtkVTK_ShapeData.cxx @@ -14,9 +14,9 @@ // commercial license or contractual agreement. #include -#include #include #include +#include #include #include #include @@ -38,7 +38,7 @@ IVtkVTK_ShapeData::IVtkVTK_ShapeData() { myPolyData = vtkSmartPointer::New(); myPolyData->Allocate(); - myPolyData->SetPoints (vtkPoints::New()); + myPolyData->SetPoints (vtkSmartPointer::New()); mySubShapeIDs = vtkSmartPointer::New(); mySubShapeIDs->SetName (IVtkVTK_ShapeData::ARRNAME_SUBSHAPE_IDS); @@ -112,7 +112,7 @@ void IVtkVTK_ShapeData::InsertLine (const IVtk_IdType theShapeID, { if (!thePointIds->IsEmpty()) { - vtkIdList* anIdList = vtkIdList::New(); + vtkSmartPointer anIdList = vtkSmartPointer::New(); // Fill the vtk id list by ids from IVtk_PointIdList. IVtk_PointIdList::Iterator anIterOfIds = IVtk_PointIdList::Iterator(*thePointIds); @@ -127,7 +127,6 @@ void IVtkVTK_ShapeData::InsertLine (const IVtk_IdType theShapeID, mySubShapeIDs->InsertNextTupleValue (&aShapeIDVTK); const vtkIdType aType = theMeshType; myMeshTypes->InsertNextTupleValue (&aType); - anIdList->Delete(); } } diff --git a/src/IVtkVTK/IVtkVTK_ShapeData.hxx b/src/IVtkVTK/IVtkVTK_ShapeData.hxx index 3827a40063..935921e704 100644 --- a/src/IVtkVTK/IVtkVTK_ShapeData.hxx +++ b/src/IVtkVTK/IVtkVTK_ShapeData.hxx @@ -17,11 +17,10 @@ #define __IVTKVTK_SHAPEDATA_H__ #include -#include +#include #include class vtkIdTypeArray; -class vtkPolyData; class IVtkVTK_ShapeData; DEFINE_STANDARD_HANDLE( IVtkVTK_ShapeData, IVtk_IShapeData ) @@ -106,7 +105,7 @@ public: //! @name Specific methods //! Get VTK PolyData. //! @return VTK PolyData - vtkSmartPointer< vtkPolyData > getVtkPolyData() const + vtkPolyData* getVtkPolyData() const { return myPolyData; } private: diff --git a/src/IVtkVTK/IVtkVTK_View.cxx b/src/IVtkVTK/IVtkVTK_View.cxx index 2eeaf3c3ed..b4e898c851 100644 --- a/src/IVtkVTK/IVtkVTK_View.cxx +++ b/src/IVtkVTK/IVtkVTK_View.cxx @@ -161,7 +161,8 @@ bool IVtkVTK_View::DisplayToWorld (const gp_XY& theDisplayPnt, gp_XYZ& theWorldP return false; } - theWorldPnt = gp_XYZ (aCoords[0] / aCoords[3], aCoords[1] / aCoords[3], aCoords[2] / aCoords[3]); + theWorldPnt = gp_XYZ (aCoords[0] / aCoords[3], + aCoords[1] / aCoords[3], aCoords[2] / aCoords[3]); return true; } @@ -188,9 +189,10 @@ void IVtkVTK_View::GetCamera (Graphic3d_Mat4d& theProj, theIsOrtho = !IsPerspective(); vtkMatrix4x4* aCompositeProj = - myRenderer->GetActiveCamera()->GetCompositeProjectionTransformMatrix (myRenderer->GetTiledAspectRatio(), - 0, - 1); + myRenderer->GetActiveCamera()-> + GetCompositeProjectionTransformMatrix (myRenderer->GetTiledAspectRatio(), + 0, + 1); for (Standard_Integer aRow = 0; aRow < 4; ++aRow) { for (Standard_Integer aCol = 0; aCol < 4; ++aCol) diff --git a/src/IVtkVTK/IVtkVTK_View.hxx b/src/IVtkVTK/IVtkVTK_View.hxx index cc6d69ea8e..50104af276 100644 --- a/src/IVtkVTK/IVtkVTK_View.hxx +++ b/src/IVtkVTK/IVtkVTK_View.hxx @@ -17,6 +17,7 @@ #define __IVTKVTK_VIEW_H__ #include +#include class vtkRenderer; @@ -92,7 +93,7 @@ public: DEFINE_STANDARD_RTTIEXT(IVtkVTK_View,IVtk_IView) private: - vtkRenderer* myRenderer; + vtkSmartPointer myRenderer; }; #endif // __IVTKVTK_VIEW_H__ diff --git a/tests/bugs/begin b/tests/bugs/begin index c80b2460a5..5427240b8a 100755 --- a/tests/bugs/begin +++ b/tests/bugs/begin @@ -43,59 +43,6 @@ proc checkarea {shape area_expected tol_abs tol_rel} { checkreal "area of $shape" $area $area_expected $tol_abs $tol_rel } -# Procedure to check if sequence of values in listval follows linear trend -# adding the same delta on each step. -# -# The function does statistical estimation of the mean variation of the -# values of the sequence, and dispersion, and returns true only if both -# dispersion and deviation of the mean from expected delta are within -# specified tolerance. -# -# If mean variation differs from expected delta on more than two dispersions, -# the check fails and procedure raises error with specified message. -# -# Otherwise the procedure returns false meaning that more iterations are needed. -# Note that false is returned in any case if length of listval is less than 3. -# -# See example of use to check memory leaks in bugs/caf/bug23489 -# -proc checktrend {listval delta tolerance message} { - set nbval [llength $listval] - if { $nbval < 3} { - return 0 - } - - # calculate mean value - set mean 0. - set prev [lindex $listval 0] - foreach val [lrange $listval 1 end] { - set mean [expr $mean + ($val - $prev)] - set prev $val - } - set mean [expr $mean / ($nbval - 1)] - - # calculate dispersion - set sigma 0. - set prev [lindex $listval 0] - foreach val [lrange $listval 1 end] { - set d [expr ($val - $prev) - $mean] - set sigma [expr $sigma + $d * $d] - set prev $val - } - set sigma [expr sqrt ($sigma / ($nbval - 2))] - - puts "Checking trend: nb = $nbval, mean delta = $mean, sigma = $sigma" - - # check if deviation is definitely too big - if { abs ($mean - $delta) > $tolerance + 2. * $sigma } { - puts "Checking trend failed: mean delta per step = $mean, sigma = $sigma, expected delta = $delta" - error "$message" - } - - # check if deviation is clearly within a range - return [expr abs ($mean - $delta) <= $sigma && $sigma <= $tolerance] -} - # Check if area of triangles is valid proc CheckTriArea {shape {eps 0}} { upvar #0 $shape result diff --git a/tests/v3d/ivtk/bug27567 b/tests/v3d/ivtk/bug27567 new file mode 100644 index 0000000000..5d110ad008 --- /dev/null +++ b/tests/v3d/ivtk/bug27567 @@ -0,0 +1,66 @@ +puts "For OCC27871: Possible memory leak in viewers in virtual windows mode" +puts "For OCC27871: Use 120 kb tolerance for checktrend because of leak on Linux in virtual windows mode" +puts "============" +puts "OCC27567" +puts "============" +puts "" +####################################################################### +# Visualization - possible memory leaks due to use of plain pointers +# in IVTK +####################################################################### + +ivtkinit + +dlog off +# Create i_max number of shapes +set i_max 15 + +set listmem {} +for {set i 1} {${i} <= ${i_max}} {incr i} { + + psphere s 10 15 80 + box box1 5 5 -5 + box box2 -5 -5 -5 + ptorus t 10 3 + + compound s box1 box2 t b$i + + unset s + unset box1 + unset box2 + unset t + + + # Display the j-th shape + ivtkdisplay b$i + + # Display shaded + ivtksetdispmode 1 + + # Display wired + ivtksetdispmode 0 + + # Select the shape + ivtkselect 200 200 + + # Deselect the shape + ivtkselect 0 0 + + # Highlight the shape + ivtkmoveto 200 200 + + # Unhighlight the shape + ivtkmoveto 50 50 + + # Hide the shape + ivtkerase b$i + + # Remove the shape presentation from memory + ivtkremove b$i + + unset b$i + + lappend listmem [meminfo h] + checktrend $listmem 0 120000 "Memory leak detected" +} +