0030669: Visualization - AIS_Manipulator ignores parent transformation IR-WEEK17
authorkgv <kgv@opencascade.com>
Wed, 24 Apr 2019 15:50:29 +0000 (18:50 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 25 Apr 2019 13:41:17 +0000 (16:41 +0300)
AIS_Manipulator::Transform() now considers object parent transformation.

Added new command vchild for easier testing of low-level connections between presentations.

src/AIS/AIS_Manipulator.cxx
src/ViewerTest/ViewerTest_ObjectCommands.cxx
tests/bugs/vis/bug30669 [new file with mode: 0644]

index 6413b1f..1e8fddc 100644 (file)
@@ -702,7 +702,20 @@ void AIS_Manipulator::Transform (const gp_Trsf& theTrsf)
     NCollection_Sequence<gp_Trsf>::Iterator aTrsfIter (myStartTrsfs);
     for (; anObjIter.More(); anObjIter.Next(), aTrsfIter.Next())
     {
-      anObjIter.ChangeValue()->SetLocalTransformation (theTrsf * aTrsfIter.Value());
+      const Handle(AIS_InteractiveObject)& anObj = anObjIter.ChangeValue();
+      const gp_Trsf& anOldTrsf = aTrsfIter.Value();
+      const Handle(Geom_Transformation)& aParentTrsf = anObj->CombinedParentTransformation();
+      if (!aParentTrsf.IsNull()
+        && aParentTrsf->Form() != gp_Identity)
+      {
+        // recompute local transformation relative to parent transformation
+        const gp_Trsf aNewLocalTrsf = aParentTrsf->Trsf().Inverted() * theTrsf * aParentTrsf->Trsf() * anOldTrsf;
+        anObj->SetLocalTransformation (aNewLocalTrsf);
+      }
+      else
+      {
+        anObj->SetLocalTransformation (theTrsf * anOldTrsf);
+      }
     }
   }
 
index 95fc846..2358acf 100644 (file)
@@ -4609,6 +4609,81 @@ static Standard_Integer VListConnected (Draw_Interpretor& /*di*/,
   return 0;
 }
 
+//=======================================================================
+//function : VChild
+//purpose  :
+//=======================================================================
+static Standard_Integer VChild (Draw_Interpretor& ,
+                                Standard_Integer theNbArgs,
+                                const char** theArgVec)
+{
+  Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
+  if (aContext.IsNull())
+  {
+    std::cout << "Error: no active view\n";
+    return 1;
+  }
+
+  int toAdd = -1;
+  Handle(AIS_InteractiveObject) aParent;
+  bool hasActions = false;
+  ViewerTest_AutoUpdater anUpdateTool (aContext, ViewerTest::CurrentView());
+  for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
+  {
+    TCollection_AsciiString anArg (theArgVec[anArgIter]);
+    anArg.LowerCase();
+    if (anUpdateTool.parseRedrawMode (anArg))
+    {
+      continue;
+    }
+    else if (anArg == "-add")
+    {
+      toAdd = 1;
+      continue;
+    }
+    else if (anArg == "-remove")
+    {
+      toAdd = 0;
+      continue;
+    }
+
+    Handle(AIS_InteractiveObject) aChild;
+    if (!GetMapOfAIS().Find2 (theArgVec[anArgIter], aChild))
+    {
+      std::cout << "Syntax error: object '" << theArgVec[anArgIter] << "' is not found\n";
+      return 1;
+    }
+
+    if (aParent.IsNull())
+    {
+      aParent = aChild;
+    }
+    else if (toAdd == -1)
+    {
+      std::cout << "Syntax error: no action specified\n";
+      return 1;
+    }
+    else
+    {
+      hasActions = true;
+      if (toAdd == 1)
+      {
+        aParent->AddChild (aChild);
+      }
+      else
+      {
+        aParent->RemoveChild (aChild);
+      }
+    }
+  }
+  if (!hasActions)
+  {
+    std::cout << "Syntax error: not enough arguments\n";
+    return 1;
+  }
+  return 0;
+}
+
 //===============================================================================================
 //function : VSetSelectionMode
 //purpose  : vselmode
@@ -6311,7 +6386,11 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
   theCommands.Add ("vsetlocation",
                    "alias for vlocation",
         __FILE__, VSetLocation, group);
-
+  theCommands.Add ("vchild",
+                   "vchild parent [-add] [-remove] child1 [child2] [...]"
+      "\n\t\t: Command for testing low-level presentation connections."
+      "\n\t\t: vconnect command should be used instead.",
+        __FILE__, VChild, group);
   theCommands.Add ("vcomputehlr",
                 "vcomputehlr shapeInput hlrResult [-algoType {algo|polyAlgo}=polyAlgo]"
       "\n\t\t:   [eyeX eyeY eyeZ dirX dirY dirZ upX upY upZ]"
diff --git a/tests/bugs/vis/bug30669 b/tests/bugs/vis/bug30669
new file mode 100644 (file)
index 0000000..5d21cdb
--- /dev/null
@@ -0,0 +1,28 @@
+puts "============="
+puts "0030669: Visualization - AIS_Manipulator ignores parent transformation"
+puts "============="
+
+pload MODELING VISUALIZATION
+box b1 0 0 0 1 2 3
+box b2 2 0 0 2 1 3
+vclear
+vinit View1
+vpoint p0 0 0 0
+vdisplay -dispMode 1 b1 b2
+vchild b1 -add b2
+vlocation b1  -setRotation  1 0 0 1 -setLocation 4 -2 0
+vfit
+vmanipulator m -attach b2
+
+set mouse_pick {265 265}
+set mouse_drag {265 200}
+
+vmoveto {*}$mouse_pick
+vselect {*}$mouse_pick
+vmanipulator m -startTransform {*}$mouse_pick
+vmanipulator m -transform {*}$mouse_drag
+vmanipulator m -stopTransform
+vselect 0 0
+
+if { [string trim [vlocation b2 -location]] != "0 1.80711 0" } { puts "Error: wrong location" }
+vdump $imagedir/${casename}.png