diff --git a/samples/tcl/spheres.tcl b/samples/tcl/spheres.tcl new file mode 100644 index 0000000000..fdf88ed4f4 --- /dev/null +++ b/samples/tcl/spheres.tcl @@ -0,0 +1,142 @@ +# test performance of display of heavy scene involving multiple interactive +# objects, on example of 1000 spheres + +pload MODELING +pload VISUALIZATION + +vinit View1 w=1024 h=1024 +vclear + +# parameter NB defines number of spheres by each coordinate +set NB 10 +puts "Creating [expr $NB * $NB * $NB] spheres..." +set slist {} +for {set i 0} {$i < $NB} {incr i} { + for {set j 0} {$j < $NB} {incr j} { + for {set k 0} {$k < $NB} {incr k} { + psphere s$i$j$k 1. + lappend slist s$i$j$k + ttranslate s$i$j$k 3.*$i 3.*$j 3.*$k + } + } +} + +puts "Measuring FPS of display of spheres as separate objects..." +vaxo +vsetdispmode 1 +eval vdisplay $slist +vfit + +# measure FPS +puts [set fps_separate [vfps]] +vclear + +puts "Measuring FPS of display of spheres as single object..." +eval compound $slist c +vdisplay c + +# measure FPS +puts [set fps_compound [vfps]] +vclear + +# redisplay individual spheres, trying to avoid unnecessary internal updates +#vfrustumculling 0 ;# try to disable updates of frustum culling structures +eval vdisplay -mutable $slist + +# auxiliary procedure to make random update of variable +proc upd {theValueName theDeltaName theTime theToRand} { + upvar $theValueName aValue + upvar $theDeltaName aDelta + + # set colors to corner spheres + if { $theToRand == 1 } { + set aValue [expr $aValue + $aDelta * $theTime / 100.0] + set aDelta [expr 0.5 * (rand() - 0.5)] + return $aValue + } + + set aRes [expr $aValue + $aDelta * $theTime / 100.0] +} + +# move corner spheres in cycle +proc animateSpheres {{theDuration 10.0}} { + set nb [expr $::NB - 1] + + # set colors to corner spheres + for {set i 0} {$i < $::NB} {incr i $nb} { + for {set j 0} {$j < $::NB} {incr j $nb} { + for {set k 0} {$k < $::NB} {incr k $nb} { +# vaspects -noupdate s$i$j$k -setcolor red -setmaterial plastic + vaspects -noupdate s$i$j$k -setcolor red + set x$i$j$k 0.0 + set y$i$j$k 0.0 + set z$i$j$k 0.0 + set dx$i$j$k 0.0 + set dy$i$j$k 0.0 + set dz$i$j$k 0.0 + } + } + } + + set aDuration 0.0 + set aPrevRand 0.0 + set aTimeFrom [clock clicks -milliseconds] + uplevel #0 chrono anAnimTimer reset + uplevel #0 chrono anAnimTimer start + set toRand 1 + for {set aFrameIter 1} { $aFrameIter > 0 } {incr aFrameIter} { + set aCurrTime [expr [clock clicks -milliseconds] - $aTimeFrom] + if { $aCurrTime >= [expr $theDuration * 1000.0] } { + puts "Nb Frames: $aFrameIter" + puts "Duration: [expr $aCurrTime * 0.001] s" + set fps [expr ($aFrameIter - 1) / ($aDuration * 0.001) ] + puts "FPS: $fps" + uplevel #0 chrono anAnimTimer stop + uplevel #0 chrono anAnimTimer show + return $fps + } + + set aRandTime [expr $aCurrTime - $aPrevRand] + if { $aRandTime > 1000 } { + set toRand 1 + set aPrevRand $aCurrTime + } + + #puts "PTS: $aCurrTime ms" + for {set i 0} {$i < $::NB} {incr i $nb} { + for {set j 0} {$j < $::NB} {incr j $nb} { + for {set k 0} {$k < $::NB} {incr k $nb} { + uplevel #0 vsetlocation -noupdate s$i$j$k [upd x$i$j$k dx$i$j$k $aRandTime $toRand] [upd y$i$j$k dy$i$j$k $aRandTime $toRand] [upd z$i$j$k dz$i$j$k $aRandTime $toRand] + } + } + } + uplevel #0 vrepaint + set aDuration [expr [clock clicks -milliseconds] - $aTimeFrom] + set toRand 0 + + # sleep 1 ms allowing the user to interact with the viewer + after 1 set waiter 1 + vwait waiter + } +} + +puts "Animating movements of corner spheres (10 sec)..." +puts "(you can interact with the view during the process)" +set fps_animation [animateSpheres 10.0] + +puts "" +puts "Performance counters (FPS = \"Frames per second\"):" +puts "" +puts "Spheres as separate interactive objects:" +puts " Actual FPS: [lindex $fps_separate 1]" +puts " FPS estimate by CPU load: [expr 1000. / [lindex $fps_separate 3]]" +puts "" +puts "Spheres as one interactive object (compound):" +puts " Actual FPS: [lindex $fps_compound 1]" +puts " FPS estimate by CPU load: [expr 1000. / [lindex $fps_compound 3]]" +puts "" +puts "Animation FPS: $fps_animation" +puts "" +puts "Scene contains [lindex [trinfo c] 3] triangles" +puts "" +puts "Print 'animateSpheres 10.0' to restart animation" \ No newline at end of file diff --git a/src/ViewerTest/FILES b/src/ViewerTest/FILES index 066ac39f60..005c1282f6 100755 --- a/src/ViewerTest/FILES +++ b/src/ViewerTest/FILES @@ -1,5 +1,7 @@ EXTERNLIB ViewerTest_CMPLRS.edl +ViewerTest_AutoUpdater.hxx +ViewerTest_AutoUpdater.cxx ViewerTest_AviCommands.cxx ViewerTest_ViewerCommands.cxx ViewerTest_RelationCommands.cxx diff --git a/src/ViewerTest/ViewerTest.cxx b/src/ViewerTest/ViewerTest.cxx index 1edd03e7ec..210a3d0d75 100644 --- a/src/ViewerTest/ViewerTest.cxx +++ b/src/ViewerTest/ViewerTest.cxx @@ -25,6 +25,7 @@ #include #include + #include #include #include @@ -57,13 +58,13 @@ #include #include #include +#include #include #include #include #include -#include // avoid warnings on 'extern "C"' functions returning C++ classes #ifdef WNT @@ -84,34 +85,6 @@ extern int ViewerMainLoop(Standard_Integer argc, const char** argv); #define DEFAULT_COLOR Quantity_NOC_GOLDENROD #define DEFAULT_MATERIAL Graphic3d_NOM_BRASS -enum ViewerTest_RedrawMode -{ - ViewerTest_RM_Auto = -1, - ViewerTest_RM_RedrawForce, - ViewerTest_RM_RedrawSuppress -}; - -//! Auxiliary method to parse redraw mode argument -static Standard_Boolean parseRedrawMode (const TCollection_AsciiString& theArg, - ViewerTest_RedrawMode& theMode) -{ - TCollection_AsciiString anArgCase (theArg); - anArgCase.LowerCase(); - if (anArgCase == "-update" - || anArgCase == "-redraw") - { - theMode = ViewerTest_RM_RedrawForce; - return Standard_True; - } - else if (anArgCase == "-noupdate" - || anArgCase == "-noredraw") - { - theMode = ViewerTest_RM_RedrawSuppress; - return Standard_True; - } - return Standard_False; -} - //======================================================================= //function : GetColorFromName //purpose : get the Quantity_NameOfColor from a string @@ -1313,17 +1286,17 @@ static int VSetInteriorStyle (Draw_Interpretor& theDI, const char** theArgVec) { const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext(); + ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView()); if (aCtx.IsNull()) { std::cerr << "Error: no active view!\n"; return 1; } - ViewerTest_RedrawMode aToUpdate = ViewerTest_RM_Auto; - Standard_Integer anArgIter = 1; + Standard_Integer anArgIter = 1; for (; anArgIter < theArgNb; ++anArgIter) { - if (!parseRedrawMode (theArgVec[anArgIter], aToUpdate)) + if (!anUpdateTool.parseRedrawMode (theArgVec[anArgIter])) { break; } @@ -1397,15 +1370,6 @@ static int VSetInteriorStyle (Draw_Interpretor& theDI, aCtx->RecomputePrsOnly (anIO, Standard_False, Standard_True); } } - - // update the screen and redraw the view - const Standard_Boolean isAutoUpdate = a3DView()->SetImmediateUpdate (Standard_False); - a3DView()->SetImmediateUpdate (isAutoUpdate); - if ((isAutoUpdate && aToUpdate != ViewerTest_RM_RedrawSuppress) - || aToUpdate == ViewerTest_RM_RedrawForce) - { - TheAISContext()->UpdateCurrentViewer(); - } return 0; } @@ -1490,19 +1454,19 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/, { TCollection_AsciiString aCmdName (theArgVec[0]); const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext(); + ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView()); if (aCtx.IsNull()) { std::cerr << "Error: no active view!\n"; return 1; } - ViewerTest_RedrawMode aToUpdate = ViewerTest_RM_Auto; - Standard_Integer anArgIter = 1; + Standard_Integer anArgIter = 1; NCollection_Sequence aNames; for (; anArgIter < theArgNb; ++anArgIter) { TCollection_AsciiString anArg = theArgVec[anArgIter]; - if (parseRedrawMode (anArg, aToUpdate)) + if (anUpdateTool.parseRedrawMode (anArg)) { continue; } @@ -1885,15 +1849,6 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/, } } } - - // update the screen and redraw the view - const Standard_Boolean isAutoUpdate = a3DView()->SetImmediateUpdate (Standard_False); - a3DView()->SetImmediateUpdate (isAutoUpdate); - if ((isAutoUpdate && aToUpdate != ViewerTest_RM_RedrawSuppress) - || aToUpdate == ViewerTest_RM_RedrawForce) - { - TheAISContext()->UpdateCurrentViewer(); - } return 0; } @@ -1908,6 +1863,7 @@ static int VDonly2 (Draw_Interpretor& , const char** theArgVec) { const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext(); + ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView()); if (aCtx.IsNull()) { std::cerr << "Error: no active view!\n"; @@ -1918,12 +1874,11 @@ static int VDonly2 (Draw_Interpretor& , { aCtx->CloseLocalContext(); } - ViewerTest_RedrawMode aToUpdate = ViewerTest_RM_Auto; Standard_Integer anArgIter = 1; for (; anArgIter < theArgNb; ++anArgIter) { - if (!parseRedrawMode (theArgVec[anArgIter], aToUpdate)) + if (!anUpdateTool.parseRedrawMode (theArgVec[anArgIter])) { break; } @@ -1986,16 +1941,6 @@ static int VDonly2 (Draw_Interpretor& , TheNISContext()->Erase (aShape); } } - - // update the screen and redraw the view - const Standard_Boolean isAutoUpdate = a3DView()->SetImmediateUpdate (Standard_False); - a3DView()->SetImmediateUpdate (isAutoUpdate); - if ((isAutoUpdate && aToUpdate != ViewerTest_RM_RedrawSuppress) - || aToUpdate == ViewerTest_RM_RedrawForce) - { - TheAISContext()->UpdateCurrentViewer(); - } - return 0; } @@ -2011,18 +1956,19 @@ int VRemove (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec) { - if (a3DView().IsNull()) + const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext(); + ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView()); + if (aCtx.IsNull()) { - std::cout << "Error: wrong syntax!\n"; + std::cout << "Error: no active view!\n"; return 1; } - TheAISContext()->CloseAllContexts (Standard_False); + aCtx->CloseAllContexts (Standard_False); - ViewerTest_RedrawMode aToUpdate = ViewerTest_RM_Auto; - Standard_Boolean isContextOnly = Standard_False; - Standard_Boolean toRemoveAll = Standard_False; - Standard_Boolean toPrintInfo = Standard_True; + Standard_Boolean isContextOnly = Standard_False; + Standard_Boolean toRemoveAll = Standard_False; + Standard_Boolean toPrintInfo = Standard_True; Standard_Integer anArgIter = 1; for (; anArgIter < theArgNb; ++anArgIter) @@ -2041,7 +1987,7 @@ int VRemove (Draw_Interpretor& theDI, { toPrintInfo = Standard_False; } - else if (!parseRedrawMode (anArg, aToUpdate)) + else if (!anUpdateTool.parseRedrawMode (anArg)) { break; } @@ -2078,7 +2024,7 @@ int VRemove (Draw_Interpretor& theDI, const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (aTransientObj); if (!anIO.IsNull()) { - if (anIO->GetContext() != TheAISContext()) + if (anIO->GetContext() != aCtx) { theDI << aName.ToCString() << " was not displayed in current context.\n"; theDI << "Please activate view with this object displayed and try again.\n"; @@ -2096,7 +2042,7 @@ int VRemove (Draw_Interpretor& theDI, } } } - else if (TheAISContext()->NbCurrents() > 0 + else if (aCtx->NbCurrents() > 0 || TheNISContext()->GetSelected().Extent() > 0) { for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS()); @@ -2105,7 +2051,7 @@ int VRemove (Draw_Interpretor& theDI, const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1()); if (!anIO.IsNull()) { - if (!TheAISContext()->IsCurrent (anIO)) + if (!aCtx->IsCurrent (anIO)) { continue; } @@ -2134,7 +2080,7 @@ int VRemove (Draw_Interpretor& theDI, const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (anIter.Value())); if (!anIO.IsNull()) { - TheAISContext()->Remove (anIO, Standard_False); + aCtx->Remove (anIO, Standard_False); if (toPrintInfo) { theDI << anIter.Value().ToCString() << " was removed\n"; @@ -2157,16 +2103,6 @@ int VRemove (Draw_Interpretor& theDI, GetMapOfAIS().UnBind2 (anIter.Value()); } } - - // update the screen and redraw the view - const Standard_Boolean isAutoUpdate = a3DView()->SetImmediateUpdate (Standard_False); - a3DView()->SetImmediateUpdate (isAutoUpdate); - if ((isAutoUpdate && aToUpdate != ViewerTest_RM_RedrawSuppress) - || aToUpdate == ViewerTest_RM_RedrawForce) - { - TheAISContext()->UpdateCurrentViewer(); - } - return 0; } @@ -2179,20 +2115,21 @@ int VErase (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec) { - if (a3DView().IsNull()) + const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext(); + ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView()); + if (aCtx.IsNull()) { std::cout << "Error: no active view!\n"; return 1; } - TheAISContext()->CloseAllContexts (Standard_False); + aCtx->CloseAllContexts (Standard_False); - ViewerTest_RedrawMode aToUpdate = ViewerTest_RM_Auto; const Standard_Boolean toEraseAll = TCollection_AsciiString (theArgNb > 0 ? theArgVec[0] : "") == "veraseall"; Standard_Integer anArgIter = 1; for (; anArgIter < theArgNb; ++anArgIter) { - if (!parseRedrawMode (theArgVec[anArgIter], aToUpdate)) + if (!anUpdateTool.parseRedrawMode (theArgVec[anArgIter])) { break; } @@ -2220,7 +2157,7 @@ int VErase (Draw_Interpretor& theDI, theDI << aName.ToCString() << " "; if (!anIO.IsNull()) { - TheAISContext()->Erase (anIO, Standard_False); + aCtx->Erase (anIO, Standard_False); } else { @@ -2233,7 +2170,7 @@ int VErase (Draw_Interpretor& theDI, } } else if (!toEraseAll - && TheAISContext()->NbCurrents() > 0) + && aCtx->NbCurrents() > 0) { // remove all currently selected objects for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS()); @@ -2241,10 +2178,10 @@ int VErase (Draw_Interpretor& theDI, { const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1()); if (!anIO.IsNull() - && TheAISContext()->IsCurrent (anIO)) + && aCtx->IsCurrent (anIO)) { theDI << anIter.Key2().ToCString() << " "; - TheAISContext()->Erase (anIO, Standard_False); + aCtx->Erase (anIO, Standard_False); } } } @@ -2257,7 +2194,7 @@ int VErase (Draw_Interpretor& theDI, const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1()); if (!anIO.IsNull()) { - TheAISContext()->Erase (anIO, Standard_False); + aCtx->Erase (anIO, Standard_False); } else { @@ -2269,16 +2206,6 @@ int VErase (Draw_Interpretor& theDI, } } } - - // update the screen and redraw the view - const Standard_Boolean isAutoUpdate = a3DView()->SetImmediateUpdate (Standard_False); - a3DView()->SetImmediateUpdate (isAutoUpdate); - if ((isAutoUpdate && aToUpdate != ViewerTest_RM_RedrawSuppress) - || aToUpdate == ViewerTest_RM_RedrawForce) - { - TheAISContext()->UpdateCurrentViewer(); - } - return 0; } @@ -2292,18 +2219,18 @@ static int VDisplayAll (Draw_Interpretor& , const char** theArgVec) { - if (a3DView().IsNull()) + const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext(); + ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView()); + if (aCtx.IsNull()) { std::cout << "Error: no active view!\n"; return 1; } - ViewerTest_RedrawMode aToUpdate = ViewerTest_RM_Auto; - Standard_Integer anArgIter = 1; for (; anArgIter < theArgNb; ++anArgIter) { - if (!parseRedrawMode (theArgVec[anArgIter], aToUpdate)) + if (!anUpdateTool.parseRedrawMode (theArgVec[anArgIter])) { break; } @@ -2314,9 +2241,9 @@ static int VDisplayAll (Draw_Interpretor& , return 1; } - if (TheAISContext()->HasOpenedContext()) + if (aCtx->HasOpenedContext()) { - TheAISContext()->CloseLocalContext(); + aCtx->CloseLocalContext(); } for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (GetMapOfAIS()); @@ -2325,7 +2252,7 @@ static int VDisplayAll (Draw_Interpretor& , if (anIter.Key1()->IsKind (STANDARD_TYPE(AIS_InteractiveObject))) { const Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1()); - TheAISContext()->Erase (aShape, Standard_False); + aCtx->Erase (aShape, Standard_False); } else if (anIter.Key1()->IsKind(STANDARD_TYPE(NIS_InteractiveObject))) { @@ -2340,7 +2267,7 @@ static int VDisplayAll (Draw_Interpretor& , if (anIter.Key1()->IsKind (STANDARD_TYPE(AIS_InteractiveObject))) { const Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (anIter.Key1()); - TheAISContext()->Display (aShape, Standard_False); + aCtx->Display (aShape, Standard_False); } else if (anIter.Key1()->IsKind (STANDARD_TYPE(NIS_InteractiveObject))) { @@ -2348,16 +2275,6 @@ static int VDisplayAll (Draw_Interpretor& , TheNISContext()->Display (aShape); } } - - // update the screen and redraw the view - const Standard_Boolean isAutoUpdate = a3DView()->SetImmediateUpdate (Standard_False); - a3DView()->SetImmediateUpdate (isAutoUpdate); - if ((isAutoUpdate && aToUpdate != ViewerTest_RM_RedrawSuppress) - || aToUpdate == ViewerTest_RM_RedrawForce) - { - TheAISContext()->UpdateCurrentViewer(); - } - return 0; } @@ -2436,15 +2353,15 @@ int VBounding (Draw_Interpretor& theDI, const char** theArgVec) { Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext(); + ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView()); if (aCtx.IsNull()) { std::cout << "Error: no active view!\n"; return 1; } - ViewerTest_RedrawMode aToUpdate = ViewerTest_RM_Auto; - ViewerTest_BndAction anAction = BndAction_Show; - Standard_Integer aMode = -1; + ViewerTest_BndAction anAction = BndAction_Show; + Standard_Integer aMode = -1; Standard_Integer anArgIter = 1; for (; anArgIter < theArgNb; ++anArgIter) @@ -2472,7 +2389,7 @@ int VBounding (Draw_Interpretor& theDI, } aMode = Draw::Atoi (theArgVec[anArgIter]); } - else if (!parseRedrawMode (anArg, aToUpdate)) + else if (!anUpdateTool.parseRedrawMode (anArg)) { break; } @@ -2500,7 +2417,7 @@ int VBounding (Draw_Interpretor& theDI, bndPresentation (theDI, aPrs, aName, anAction); } } - else if (TheAISContext()->NbCurrents() > 0) + else if (aCtx->NbCurrents() > 0) { // remove all currently selected objects for (aCtx->InitCurrent(); aCtx->MoreCurrent(); aCtx->NextCurrent()) @@ -2527,16 +2444,6 @@ int VBounding (Draw_Interpretor& theDI, } } } - - // update the screen and redraw the view - const Standard_Boolean isAutoUpdate = a3DView()->SetImmediateUpdate (Standard_False); - a3DView()->SetImmediateUpdate (isAutoUpdate); - if ((isAutoUpdate && aToUpdate != ViewerTest_RM_RedrawSuppress) - || aToUpdate == ViewerTest_RM_RedrawForce) - { - TheAISContext()->UpdateCurrentViewer(); - } - return 0; } @@ -2838,32 +2745,33 @@ static int VDisplay2 (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec) { + Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext(); if (theArgNb < 2) { std::cout << theArgVec[0] << "Error: wrong syntax!\n"; return 1; } - else if (a3DView().IsNull()) + else if (aCtx.IsNull()) { ViewerTest::ViewerInit(); std::cout << "Command vinit should be called before!\n"; // return 1; + aCtx = ViewerTest::GetAISContext(); } - const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext(); + ViewerTest_AutoUpdater anUpdateTool (aCtx, ViewerTest::CurrentView()); if (aCtx->HasOpenedContext()) { aCtx->CloseLocalContext(); } - ViewerTest_RedrawMode aToUpdate = ViewerTest_RM_Auto; - Standard_Integer isMutable = -1; + Standard_Integer isMutable = -1; for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter) { const TCollection_AsciiString aName = theArgVec[anArgIter]; TCollection_AsciiString aNameCase = aName; aNameCase.LowerCase(); - if (parseRedrawMode (aName, aToUpdate)) + if (anUpdateTool.parseRedrawMode (aName)) { continue; } @@ -2923,15 +2831,6 @@ static int VDisplay2 (Draw_Interpretor& theDI, TheNISContext()->Display (aShape); } } - - const Standard_Boolean isAutoUpdate = a3DView()->SetImmediateUpdate (Standard_False); - a3DView()->SetImmediateUpdate (isAutoUpdate); - if ((isAutoUpdate && aToUpdate != ViewerTest_RM_RedrawSuppress) - || aToUpdate == ViewerTest_RM_RedrawForce) - { - // update the screen and redraw the view - aCtx->UpdateCurrentViewer(); - } return 0; } diff --git a/src/ViewerTest/ViewerTest_AutoUpdater.cxx b/src/ViewerTest/ViewerTest_AutoUpdater.cxx new file mode 100644 index 0000000000..2d6db65e3a --- /dev/null +++ b/src/ViewerTest/ViewerTest_AutoUpdater.cxx @@ -0,0 +1,98 @@ +// Created on: 2014-04-24 +// Created by: Kirill Gavrilov +// Copyright (c) 2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +//======================================================================= +//function : ViewerTest_AutoUpdater +//purpose : +//======================================================================= +ViewerTest_AutoUpdater::ViewerTest_AutoUpdater (const Handle(AIS_InteractiveContext)& theContext, + const Handle(V3d_View)& theView) +: myContext (theContext), + myView (theView), + myToUpdate (RedrawMode_Auto), + myWasAutoUpdate (Standard_False) +{ + if (!theView.IsNull()) + { + myWasAutoUpdate = theView->SetImmediateUpdate (Standard_False); + } +} + +//======================================================================= +//function : ~ViewerTest_AutoUpdater +//purpose : +//======================================================================= +ViewerTest_AutoUpdater::~ViewerTest_AutoUpdater() +{ + Update(); +} + +//======================================================================= +//function : parseRedrawMode +//purpose : +//======================================================================= +Standard_Boolean ViewerTest_AutoUpdater::parseRedrawMode (const TCollection_AsciiString& theArg) +{ + TCollection_AsciiString anArgCase (theArg); + anArgCase.LowerCase(); + if (anArgCase == "-update" + || anArgCase == "-redraw") + { + myToUpdate = RedrawMode_Forced; + return Standard_True; + } + else if (anArgCase == "-noupdate" + || anArgCase == "-noredraw") + { + myToUpdate = RedrawMode_Suppressed; + return Standard_True; + } + return Standard_False; +} + +//======================================================================= +//function : Invalidate +//purpose : +//======================================================================= +void ViewerTest_AutoUpdater::Invalidate() +{ + myContext.Nullify(); + if (myWasAutoUpdate) + { + myView->SetImmediateUpdate (myWasAutoUpdate); + } +} + +//======================================================================= +//function : Update +//purpose : +//======================================================================= +void ViewerTest_AutoUpdater::Update() +{ + if (myContext.IsNull()) + { + return; + } + + // update the screen and redraw the view + myView->SetImmediateUpdate (myWasAutoUpdate); + if ((myWasAutoUpdate && myToUpdate != ViewerTest_AutoUpdater::RedrawMode_Suppressed) + || myToUpdate == ViewerTest_AutoUpdater::RedrawMode_Forced) + { + myContext->UpdateCurrentViewer(); + } +} diff --git a/src/ViewerTest/ViewerTest_AutoUpdater.hxx b/src/ViewerTest/ViewerTest_AutoUpdater.hxx new file mode 100644 index 0000000000..96a3c52bdf --- /dev/null +++ b/src/ViewerTest/ViewerTest_AutoUpdater.hxx @@ -0,0 +1,64 @@ +// Created on: 2014-09-10 +// Created by: Kirill Gavrilov +// Copyright (c) 2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _ViewerTest_AutoUpdater_HeaderFile +#define _ViewerTest_AutoUpdater_HeaderFile + +#include +#include + +class TCollection_AsciiString; + +//! Auxiliary tool to control view updates. +class ViewerTest_AutoUpdater +{ +public: + + //! Enumeration to control auto-update + enum RedrawMode + { + RedrawMode_Auto = -1, + RedrawMode_Forced, + RedrawMode_Suppressed + }; + +public: + + //! Constructor + Standard_EXPORT ViewerTest_AutoUpdater (const Handle(AIS_InteractiveContext)& theContext, + const Handle(V3d_View)& theView); + + //! Destructor to automatically update view + Standard_EXPORT ~ViewerTest_AutoUpdater(); + + //! Parse redraw mode argument + Standard_EXPORT Standard_Boolean parseRedrawMode (const TCollection_AsciiString& theArg); + + //! Disable autoupdate + Standard_EXPORT void Invalidate(); + + //! Finally update view + Standard_EXPORT void Update(); + +private: + + Handle(AIS_InteractiveContext) myContext; + Handle(V3d_View) myView; + ViewerTest_AutoUpdater::RedrawMode myToUpdate; + Standard_Boolean myWasAutoUpdate; + +}; + +#endif // _ViewerTest_AutoUpdater_HeaderFile diff --git a/src/ViewerTest/ViewerTest_ObjectCommands.cxx b/src/ViewerTest/ViewerTest_ObjectCommands.cxx index a05402dde6..009a941b80 100644 --- a/src/ViewerTest/ViewerTest_ObjectCommands.cxx +++ b/src/ViewerTest/ViewerTest_ObjectCommands.cxx @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -3481,53 +3482,72 @@ static int VDrawPArray (Draw_Interpretor& di, Standard_Integer argc, const char* //======================================================================= static Standard_Integer VSetLocation (Draw_Interpretor& /*di*/, - Standard_Integer argc, - const char ** argv) + Standard_Integer theArgNb, + const char** theArgVec) { Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext(); + ViewerTest_AutoUpdater anUpdateTool (aContext, ViewerTest::CurrentView()); if (aContext.IsNull()) { - std::cout << argv[0] << "ERROR : use 'vinit' command before " << "\n"; + std::cout << "Error: no active view!\n"; return 1; } - if (argc != 5) - { - std::cout << "ERROR : Usage : " << argv[0] << " name x y z; new location" << "\n"; - return 1; - } + TCollection_AsciiString aName; + gp_Vec aLocVec; + Standard_Boolean isSetLoc = Standard_False; - TCollection_AsciiString aName (argv[1]); - Standard_Real aX = Draw::Atof (argv[2]); - Standard_Real aY = Draw::Atof (argv[3]); - Standard_Real aZ = Draw::Atof (argv[4]); - - // find object - ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS(); - Handle(AIS_InteractiveObject) anIObj; - if (!aMap.IsBound2 (aName)) + Standard_Integer anArgIter = 1; + for (; anArgIter < theArgNb; ++anArgIter) { - std::cout << "Use 'vdisplay' before" << "\n"; - return 1; - } - else - { - anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (aName)); - - // not an AIS_InteractiveObject - if (anIObj.IsNull()) + Standard_CString anArg = theArgVec[anArgIter]; + if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter])) { - std::cout << argv[1] << " : Not an AIS interactive object" << "\n"; + continue; + } + else if (aName.IsEmpty()) + { + aName = anArg; + } + else if (!isSetLoc) + { + isSetLoc = Standard_True; + if (anArgIter + 1 >= theArgNb) + { + std::cout << "Error: syntax error at '" << anArg << "'\n"; + return 1; + } + aLocVec.SetX (Draw::Atof (theArgVec[anArgIter++])); + aLocVec.SetY (Draw::Atof (theArgVec[anArgIter])); + if (anArgIter + 1 < theArgNb) + { + aLocVec.SetZ (Draw::Atof (theArgVec[++anArgIter])); + } + } + else + { + std::cout << "Error: unknown argument '" << anArg << "'\n"; return 1; } - - gp_Trsf aTrsf; - aTrsf.SetTranslation (gp_Vec (aX, aY, aZ)); - TopLoc_Location aLocation (aTrsf); - aContext->SetLocation (anIObj, aLocation); - aContext->UpdateCurrentViewer(); } + // find object + const ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS(); + Handle(AIS_InteractiveObject) anIObj; + if (aMap.IsBound2 (aName)) + { + anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (aName)); + } + if (anIObj.IsNull()) + { + std::cout << "Error: object '" << aName << "' is not displayed!\n"; + return 1; + } + + gp_Trsf aTrsf; + aTrsf.SetTranslation (aLocVec); + TopLoc_Location aLocation (aTrsf); + aContext->SetLocation (anIObj, aLocation); return 0; } @@ -5429,7 +5449,8 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands) __FILE__,VDrawSphere,group); theCommands.Add ("vsetlocation", - "vsetlocation : name x y z; set new location for an interactive object", + "vsetlocation [-noupdate|-update] name x y z" + "\n\t\t: Set new location for an interactive object.", __FILE__, VSetLocation, group); theCommands.Add (