From 52c38ce17dba980542758d8c11a8c2946eea7e32 Mon Sep 17 00:00:00 2001 From: asl Date: Thu, 16 May 2019 11:23:21 +0300 Subject: [PATCH] 0030561: Visualization, PrsMgr_PresentableObject - Keep the current transformation for child in AddChild() New methods AddChildWithCurrentTransformation(), RemoveChildWithRestoreTransformation() are implemented to keep the current global transformation of the object (child). In DRAW a new command vchild is provided for testing low-level connections between presentations. --- src/PrsMgr/PrsMgr_PresentableObject.cxx | 22 ++++++++++ src/PrsMgr/PrsMgr_PresentableObject.hxx | 8 ++++ src/ViewerTest/ViewerTest_ObjectCommands.cxx | 45 ++++++++++++++++++-- tests/bugs/vis/bug30561 | 35 +++++++++++++++ 4 files changed, 106 insertions(+), 4 deletions(-) create mode 100644 tests/bugs/vis/bug30561 diff --git a/src/PrsMgr/PrsMgr_PresentableObject.cxx b/src/PrsMgr/PrsMgr_PresentableObject.cxx index 4d33a1b87c..90c297b3e2 100644 --- a/src/PrsMgr/PrsMgr_PresentableObject.cxx +++ b/src/PrsMgr/PrsMgr_PresentableObject.cxx @@ -407,6 +407,17 @@ void PrsMgr_PresentableObject::AddChild (const Handle(PrsMgr_PresentableObject)& theObject->SetCombinedParentTransform (myTransformation); } +//======================================================================= +//function : AddChildWithCurrentTransformation +//purpose : +//======================================================================= +void PrsMgr_PresentableObject::AddChildWithCurrentTransformation(const Handle(PrsMgr_PresentableObject)& theObject) +{ + gp_Trsf aTrsf = Transformation().Inverted() * theObject->Transformation(); + theObject->SetLocalTransformation(aTrsf); + AddChild(theObject); +} + //======================================================================= //function : RemoveChild //purpose : @@ -426,6 +437,17 @@ void PrsMgr_PresentableObject::RemoveChild (const Handle(PrsMgr_PresentableObjec } } +//======================================================================= +//function : RemoveChildWithRestoreTransformation +//purpose : +//======================================================================= +void PrsMgr_PresentableObject::RemoveChildWithRestoreTransformation(const Handle(PrsMgr_PresentableObject)& theObject) +{ + gp_Trsf aTrsf = theObject->Transformation(); + RemoveChild(theObject); + theObject->SetLocalTransformation(aTrsf); +} + //======================================================================= //function : SetZLayer //purpose : diff --git a/src/PrsMgr/PrsMgr_PresentableObject.hxx b/src/PrsMgr/PrsMgr_PresentableObject.hxx index c79bc8deb6..6275cc4cdd 100644 --- a/src/PrsMgr/PrsMgr_PresentableObject.hxx +++ b/src/PrsMgr/PrsMgr_PresentableObject.hxx @@ -295,9 +295,17 @@ public: //! @name parent/children properties //! Makes theObject child of current object in scene hierarchy. Standard_EXPORT virtual void AddChild (const Handle(PrsMgr_PresentableObject)& theObject); + //! Makes theObject child of current object in scene hierarchy with keeping the current global transformation + //! So the object keeps the same position/orientation in the global CS. + Standard_EXPORT void AddChildWithCurrentTransformation(const Handle(PrsMgr_PresentableObject)& theObject); + //! Removes theObject from children of current object in scene hierarchy. Standard_EXPORT virtual void RemoveChild (const Handle(PrsMgr_PresentableObject)& theObject); + //! Removes theObject from children of current object in scene hierarchy with keeping the current global transformation. + //! So the object keeps the same position/orientation in the global CS. + Standard_EXPORT void RemoveChildWithRestoreTransformation(const Handle(PrsMgr_PresentableObject)& theObject); + //! Returns true if object should have own presentations. Standard_Boolean HasOwnPresentations() const { return myHasOwnPresentations; } diff --git a/src/ViewerTest/ViewerTest_ObjectCommands.cxx b/src/ViewerTest/ViewerTest_ObjectCommands.cxx index 2358acfce9..954861d568 100644 --- a/src/ViewerTest/ViewerTest_ObjectCommands.cxx +++ b/src/ViewerTest/ViewerTest_ObjectCommands.cxx @@ -4627,6 +4627,7 @@ static Standard_Integer VChild (Draw_Interpretor& , int toAdd = -1; Handle(AIS_InteractiveObject) aParent; bool hasActions = false; + int toInheritTrsf = -1; ViewerTest_AutoUpdater anUpdateTool (aContext, ViewerTest::CurrentView()); for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter) { @@ -4646,6 +4647,33 @@ static Standard_Integer VChild (Draw_Interpretor& , toAdd = 0; continue; } + else if (anArg == "-inheritparenttrsf" + || anArg == "-inheritparentloc" + || anArg == "-inheritparentlocation" + || anArg == "-inheritparent" + || anArg == "-noinheritparenttrsf" + || anArg == "-noinheritparentloc" + || anArg == "-noinheritparentlocation" + || anArg == "-noinheritparent" + || anArg == "-ignoreparenttrsf" + || anArg == "-ignoreparentloc" + || anArg == "-ignoreparentlocation" + || anArg == "-ignoreparent") + { + bool aVal = true; + if (anArgIter + 1 < theNbArgs + && ViewerTest::ParseOnOff(theArgVec[anArgIter + 1], aVal)) + { + ++anArgIter; + } + if (anArg.StartsWith("-no") + || anArg.StartsWith("-ignore")) + { + aVal = !aVal; + } + toInheritTrsf = aVal ? 1 : 0; + continue; + } Handle(AIS_InteractiveObject) aChild; if (!GetMapOfAIS().Find2 (theArgVec[anArgIter], aChild)) @@ -4668,11 +4696,17 @@ static Standard_Integer VChild (Draw_Interpretor& , hasActions = true; if (toAdd == 1) { - aParent->AddChild (aChild); + if(toInheritTrsf == 0) + aParent->AddChildWithCurrentTransformation(aChild); + else + aParent->AddChild (aChild); } else { - aParent->RemoveChild (aChild); + if (toInheritTrsf == 0) + aParent->RemoveChildWithRestoreTransformation(aChild); + else + aParent->RemoveChild (aChild); } } } @@ -6373,6 +6407,7 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands) "\n\t\t: [-setLocation X Y [Z]]" "\n\t\t: [-setRotation QX QY QZ QW]" "\n\t\t: [-setScale [X Y Z] scale]" + "\n\t\t: [-inheritParentTrsf {on|off}]" "\n\t\t: Object local transformation management:" "\n\t\t: -reset reset transformation to identity" "\n\t\t: -translate translate object" @@ -6381,13 +6416,15 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands) "\n\t\t: -mirror applies mirror to local transformation" "\n\t\t: -setLocation assign object location" "\n\t\t: -setRotation assign object rotation (quaternion)" - "\n\t\t: -setScale assign object scale factor", + "\n\t\t: -setScale assign object scale factor" + "\n\t\t: -inheritParentTrsf option to inherit parent" + "\n\t\t: transformation or not (ON by default)", __FILE__, VSetLocation, group); theCommands.Add ("vsetlocation", "alias for vlocation", __FILE__, VSetLocation, group); theCommands.Add ("vchild", - "vchild parent [-add] [-remove] child1 [child2] [...]" + "vchild parent [-add] [-remove] [-ignoreParentTrsf {0|1}] child1 [child2] [...]" "\n\t\t: Command for testing low-level presentation connections." "\n\t\t: vconnect command should be used instead.", __FILE__, VChild, group); diff --git a/tests/bugs/vis/bug30561 b/tests/bugs/vis/bug30561 new file mode 100644 index 0000000000..3ca2a5bd7e --- /dev/null +++ b/tests/bugs/vis/bug30561 @@ -0,0 +1,35 @@ +puts "============" +puts "0030561: Visualization, PrsMgr_PresentableObject - Keep the local transformation for child in AddChild()" +puts "============" +puts "" + +pload MODELING VISUALIZATION +vclear +vinit View1 + +psphere m 3 +vdisplay -dispMode 1 m +vlocation m -setLocation 20 10 20 +box b1 1 1 1 +box b2 1 1 1 +vdisplay b1 -dispMode 1 +vdisplay b2 -dispMode 1 +vlocation b1 -setLocation -10 0 0 +vlocation b2 -setLocation -10 0 0 + +set r {1 2 3 4 5} +foreach i $r { psphere c$i 1 } +foreach i $r { vdisplay -dispMode 1 c$i } +foreach i $r { vlocation c$i -setLocation [expr 20+10*$i] 10 20 } +foreach i $r { vchild m -ignoreParentTrsf -add c$i } +vchild m -add b1 + +# change main shape's local transformation, the children should be correspondingly moved +vlocation m -setLocation 100 20 20 + +# change one of sub-shape's local transformation, other shapes MUST NOT move +vlocation c4 -setLocation 40 10 0 + +vfit + +checkview -screenshot -3d -path ${imagedir}/${test_image}.png