0030532: Visualization - Manipulator for dragging within a plane
authoranv <anv@opencascade.com>
Thu, 21 Feb 2019 09:32:33 +0000 (12:32 +0300)
committerapn <apn@opencascade.com>
Thu, 7 Mar 2019 15:06:47 +0000 (18:06 +0300)
Added dragging sectors to Manipulator presentation.
Test added.

src/AIS/AIS_Manipulator.cxx
src/AIS/AIS_Manipulator.hxx
src/AIS/AIS_ManipulatorMode.hxx
src/Prs3d/FILES
src/Prs3d/Prs3d_ToolSector.cxx [new file with mode: 0644]
src/Prs3d/Prs3d_ToolSector.hxx [new file with mode: 0644]
src/ViewerTest/ViewerTest_ViewerCommands.cxx
tests/v3d/manipulator/dragg [new file with mode: 0644]
tests/v3d/manipulator/translate

index e47a6c3..30c4ae9 100644 (file)
@@ -26,6 +26,7 @@
 #include <Prs3d_Root.hxx>
 #include <Prs3d_ShadingAspect.hxx>
 #include <Prs3d_ToolDisk.hxx>
+#include <Prs3d_ToolSector.hxx>
 #include <Prs3d_ToolSphere.hxx>
 #include <Select3D_SensitiveCircle.hxx>
 #include <Select3D_SensitivePoint.hxx>
@@ -151,6 +152,19 @@ void AIS_Manipulator::init()
   myHighlightAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
   myHighlightAspect->SetMaterial (aHilightMaterial);
 
+  Graphic3d_MaterialAspect aDraggerMaterial;
+  aDraggerMaterial.SetReflectionModeOff(Graphic3d_TOR_DIFFUSE);
+  aDraggerMaterial.SetReflectionModeOff(Graphic3d_TOR_SPECULAR);
+  aDraggerMaterial.SetReflectionModeOff(Graphic3d_TOR_EMISSION);
+  aDraggerMaterial.SetMaterialType(Graphic3d_MATERIAL_ASPECT);
+  aDraggerMaterial.SetAmbient(1.0);
+
+  myDraggerHighlight = new Prs3d_ShadingAspect();
+  myDraggerHighlight->Aspect()->SetInteriorStyle(Aspect_IS_SOLID);
+  myDraggerHighlight->SetMaterial(aDraggerMaterial);
+
+  myDraggerHighlight->SetTransparency(0.5);
+
   SetSize (100);
   SetZLayer (Graphic3d_ZLayerId_Topmost);
 }
@@ -170,10 +184,11 @@ Handle(Prs3d_Presentation) AIS_Manipulator::getHighlightPresentation (const Hand
 
   switch (anOwner->Mode())
   {
-    case AIS_MM_Translation: return myAxes[anOwner->Index()].TranslatorHighlightPrs();
-    case AIS_MM_Rotation   : return myAxes[anOwner->Index()].RotatorHighlightPrs();
-    case AIS_MM_Scaling    : return myAxes[anOwner->Index()].ScalerHighlightPrs();
-    case AIS_MM_None       : break;
+    case AIS_MM_Translation     : return myAxes[anOwner->Index()].TranslatorHighlightPrs();
+    case AIS_MM_Rotation        : return myAxes[anOwner->Index()].RotatorHighlightPrs();
+    case AIS_MM_Scaling         : return myAxes[anOwner->Index()].ScalerHighlightPrs();
+    case AIS_MM_TranslationPlane: return myAxes[anOwner->Index()].DraggerHighlightPrs();
+    case AIS_MM_None            : break;
   }
 
   return aDummyPrs;
@@ -194,10 +209,11 @@ Handle(Graphic3d_Group) AIS_Manipulator::getGroup (const Standard_Integer theInd
 
   switch (theMode)
   {
-    case AIS_MM_Translation: return myAxes[theIndex].TranslatorGroup();
-    case AIS_MM_Rotation   : return myAxes[theIndex].RotatorGroup();
-    case AIS_MM_Scaling    : return myAxes[theIndex].ScalerGroup();
-    case AIS_MM_None       : break;
+    case AIS_MM_Translation     : return myAxes[theIndex].TranslatorGroup();
+    case AIS_MM_Rotation        : return myAxes[theIndex].RotatorGroup();
+    case AIS_MM_Scaling         : return myAxes[theIndex].ScalerGroup();
+    case AIS_MM_TranslationPlane: return myAxes[theIndex].DraggerGroup();
+    case AIS_MM_None            : break;
   }
 
   return aDummyGroup;
@@ -266,6 +282,10 @@ void AIS_Manipulator::SetPart (const Standard_Integer theAxisIndex, const AIS_Ma
       myAxes[theAxisIndex].SetScaling (theIsEnabled);
       break;
 
+    case AIS_MM_TranslationPlane:
+      myAxes[theAxisIndex].SetDragging(theIsEnabled);
+      break;
+
     case AIS_MM_None:
       break;
   }
@@ -277,7 +297,7 @@ void AIS_Manipulator::SetPart (const Standard_Integer theAxisIndex, const AIS_Ma
 //=======================================================================
 void AIS_Manipulator::SetPart (const AIS_ManipulatorMode theMode, const Standard_Boolean theIsEnabled)
 {
-  for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
+  for (Standard_Integer anIt = 0; anIt < 4; ++anIt)
   {
     SetPart (anIt, theMode, theIsEnabled);
   }
@@ -400,6 +420,7 @@ void AIS_Manipulator::Attach (const Handle(AIS_ManipulatorObjectSequence)& theOb
     EnableMode (AIS_MM_Rotation);
     EnableMode (AIS_MM_Translation);
     EnableMode (AIS_MM_Scaling);
+    EnableMode (AIS_MM_TranslationPlane);
   }
 }
 
@@ -586,6 +607,34 @@ Standard_Boolean AIS_Manipulator::ObjectTransformation (const Standard_Integer t
       myPrevState = anAngle;
       return Standard_True;
     }
+    case AIS_MM_TranslationPlane:
+    {
+      const gp_Pnt aPosLoc = myStartPosition.Location();
+      const gp_Ax1 aCurrAxis = getAx1FromAx2Dir(myStartPosition, myCurrentIndex);
+      IntAna_IntConicQuad aIntersector(anInputLine, gp_Pln(aPosLoc, aCurrAxis.Direction()), Precision::Angular(), Precision::Intersection());
+      if (!aIntersector.IsDone() || aIntersector.NbPoints() < 1)
+      {
+        return Standard_False;
+      }
+
+      const gp_Pnt aNewPosition = aIntersector.Point(1);
+      if (!myHasStartedTransformation)
+      {
+        myStartPick = aNewPosition;
+        myHasStartedTransformation = Standard_True;
+        return Standard_True;
+      }
+
+      if (aNewPosition.Distance(myStartPick) < Precision::Confusion())
+      {
+        return Standard_False;
+      }
+
+      gp_Trsf aNewTrsf;
+      aNewTrsf.SetTranslation(gp_Vec(myStartPick, aNewPosition));
+      theTrsf *= aNewTrsf;
+      return Standard_True;
+    }
     case AIS_MM_None:
     {
       return Standard_False;
@@ -657,8 +706,9 @@ void AIS_Manipulator::Transform (const gp_Trsf& theTrsf)
     }
   }
 
-  if ((myCurrentMode == AIS_MM_Translation && myBehaviorOnTransform.FollowTranslation)
-   || (myCurrentMode == AIS_MM_Rotation    && myBehaviorOnTransform.FollowRotation))
+  if ((myCurrentMode == AIS_MM_Translation      && myBehaviorOnTransform.FollowTranslation)
+   || (myCurrentMode == AIS_MM_Rotation         && myBehaviorOnTransform.FollowRotation)
+   || (myCurrentMode == AIS_MM_TranslationPlane && myBehaviorOnTransform.FollowDragging))
   {
     gp_Pnt aPos  = myStartPosition.Location().Transformed (theTrsf);
     gp_Dir aVDir = myStartPosition.Direction().Transformed (theTrsf);
@@ -786,8 +836,13 @@ void AIS_Manipulator::DeactivateCurrentMode()
     Handle(Prs3d_ShadingAspect) anAspect = new Prs3d_ShadingAspect();
     anAspect->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
     anAspect->SetMaterial (myDrawer->ShadingAspect()->Material());
-    anAspect->SetTransparency (myDrawer->ShadingAspect()->Transparency());
-    anAspect->SetColor (myAxes[myCurrentIndex].Color());
+    if (myCurrentMode == AIS_MM_TranslationPlane)
+      anAspect->SetTransparency(1.0);
+    else
+    {
+      anAspect->SetTransparency(myDrawer->ShadingAspect()->Transparency());
+      anAspect->SetColor(myAxes[myCurrentIndex].Color());
+    }
 
     aGroup->SetGroupPrimitivesAspect (anAspect->Aspect());
   }
@@ -882,14 +937,14 @@ void AIS_Manipulator::Compute (const Handle(PrsMgr_PresentationManager3d)& thePr
 
   // Display center
   myCenter.Init (myAxes[0].AxisRadius() * 2.0f, gp::Origin());
-  aGroup = Prs3d_Root::NewGroup (thePrs);
+  aGroup = thePrs->NewGroup ();
   aGroup->SetPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
   aGroup->AddPrimitiveArray (myCenter.Array());
 
   for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
   {
     // Display axes
-    aGroup = Prs3d_Root::NewGroup (thePrs);
+    aGroup = thePrs->NewGroup ();
 
     Handle(Prs3d_ShadingAspect) anAspectAx = new Prs3d_ShadingAspect (new Graphic3d_AspectFillArea3d(*anAspect->Aspect()));
     anAspectAx->SetColor (myAxes[anIt].Color());
@@ -932,7 +987,13 @@ void AIS_Manipulator::HilightSelected (const Handle(PrsMgr_PresentationManager3d
     return;
   }
 
-  aGroup->SetGroupPrimitivesAspect (myHighlightAspect->Aspect());
+  if (anOwner->Mode() == AIS_MM_TranslationPlane)
+  {
+    myDraggerHighlight->SetColor(myAxes[anOwner->Index()].Color());
+    aGroup->SetGroupPrimitivesAspect(myDraggerHighlight->Aspect());
+  }
+  else
+    aGroup->SetGroupPrimitivesAspect(myHighlightAspect->Aspect());
 
   myCurrentIndex = anOwner->Index();
   myCurrentMode = anOwner->Mode();
@@ -961,7 +1022,15 @@ void AIS_Manipulator::HilightOwnerWithColor (const Handle(PrsMgr_PresentationMan
   {
     return;
   }
-  aPresentation->Highlight (theStyle);
+  if (anOwner->Mode() == AIS_MM_TranslationPlane)
+  {
+    Handle(Prs3d_Drawer) aStyle = new Prs3d_Drawer();
+    aStyle->SetColor(myAxes[anOwner->Index()].Color());
+    aStyle->SetTransparency(0.5);
+    aPresentation->Highlight(aStyle);
+  }
+  else
+    aPresentation->Highlight(theStyle);
   for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aPresentation->Groups());
        aGroupIter.More(); aGroupIter.Next())
   {
@@ -1076,6 +1145,38 @@ void AIS_Manipulator::ComputeSelection (const Handle(SelectMgr_Selection)& theSe
       theSelection->Add (aTri);
     }
   }
+
+  if (aMode == AIS_MM_TranslationPlane || aMode == AIS_MM_None)
+  {
+    for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
+    {
+      if (!myAxes[anIt].HasDragging())
+      {
+        continue;
+      }
+      if (aMode != AIS_MM_None)
+      {
+        anOwner = new AIS_ManipulatorOwner(this, anIt, AIS_MM_TranslationPlane, 9);
+      }
+
+      // define sensitivity by two crossed lines
+      gp_Pnt aP1, aP2;
+      aP1 = myAxes[((anIt + 1) % 3)].TranslatorTipPosition();
+      aP2 = myAxes[((anIt + 2) % 3)].TranslatorTipPosition();
+      gp_XYZ aMidP = (aP1.XYZ() + aP2.XYZ()) / 2.0;
+
+      Handle(Select3D_SensitiveSegment) aLine1 = new Select3D_SensitiveSegment(anOwner, aP1, aP2);
+      aLine1->SetSensitivityFactor(10);
+      theSelection->Add(aLine1);
+      Handle(Select3D_SensitiveSegment) aLine2 = new Select3D_SensitiveSegment(anOwner, gp::Origin(), aMidP);
+      aLine2->SetSensitivityFactor(10);
+      theSelection->Add(aLine2);
+
+      // enlarge sensitivity by triangulation
+      Handle(Select3D_SensitiveTriangulation) aTri = new Select3D_SensitiveTriangulation(anOwner, myAxes[anIt].DraggerSector().Triangulation(), TopLoc_Location(), Standard_True);
+      theSelection->Add(aTri);
+    }
+  }
 }
 
 //=======================================================================
@@ -1192,6 +1293,24 @@ void AIS_Manipulator::Cube::addTriangle (const Standard_Integer theIndex,
 }
 
 //=======================================================================
+//class    : Sector
+//function : Init
+//purpose  : 
+//=======================================================================
+void AIS_Manipulator::Sector::Init (const Standard_ShortReal theRadius,
+                                    const gp_Ax1&            thePosition,
+                                    const gp_Dir&            theXDirection,
+                                    const Standard_Integer   theSlicesNb,
+                                    const Standard_Integer   theStacksNb)
+{
+  Prs3d_ToolSector aTool(theRadius, theSlicesNb, theStacksNb);
+  gp_Ax3 aSystem(thePosition.Location(), thePosition.Direction(), theXDirection);
+  gp_Trsf aTrsf;
+  aTrsf.SetTransformation(aSystem, gp_Ax3());
+  aTool.FillArray(myArray, myTriangulation, aTrsf);
+}
+
+//=======================================================================
 //class    : Axis
 //function : Constructor
 //purpose  : 
@@ -1211,6 +1330,7 @@ AIS_Manipulator::Axis::Axis (const gp_Ax1& theAxis,
   myInnerRadius (myLength + myBoxSize),
   myDiskThickness (myBoxSize * 0.5f),
   myIndent (0.2f),
+  myHasDragging(Standard_True),
   myFacettesNumber (20),
   myCircleRadius (myLength + myBoxSize + myBoxSize * 0.5f * 0.5f)
 {
@@ -1239,7 +1359,7 @@ void AIS_Manipulator::Axis::Compute (const Handle(PrsMgr_PresentationManager)& t
                                                myAxisRadius * 1.5,
                                                anArrowLength,
                                                myFacettesNumber);
-    myTranslatorGroup = Prs3d_Root::NewGroup (thePrs);
+    myTranslatorGroup = thePrs->NewGroup ();
     myTranslatorGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
     myTranslatorGroup->AddPrimitiveArray (myTriangleArray);
 
@@ -1263,7 +1383,7 @@ void AIS_Manipulator::Axis::Compute (const Handle(PrsMgr_PresentationManager)& t
     myCubePos = myReferenceAxis.Direction().XYZ() * (myLength + myIndent);
     myCube.Init (gp_Ax1 (myCubePos, myReferenceAxis.Direction()), myBoxSize);
 
-    myScalerGroup = Prs3d_Root::NewGroup (thePrs);
+    myScalerGroup = thePrs->NewGroup ();
     myScalerGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
     myScalerGroup->AddPrimitiveArray (myCube.Array());
 
@@ -1286,7 +1406,7 @@ void AIS_Manipulator::Axis::Compute (const Handle(PrsMgr_PresentationManager)& t
   {
     myCircleRadius = myInnerRadius + myIndent * 2 + myDiskThickness * 0.5f;
     myCircle.Init (myInnerRadius + myIndent * 2, myInnerRadius + myDiskThickness + myIndent * 2, gp_Ax1(gp::Origin(), myReferenceAxis.Direction()), myFacettesNumber * 2);
-    myRotatorGroup = Prs3d_Root::NewGroup (thePrs);
+    myRotatorGroup = thePrs->NewGroup ();
     myRotatorGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
     myRotatorGroup->AddPrimitiveArray (myCircle.Array());
 
@@ -1304,4 +1424,36 @@ void AIS_Manipulator::Axis::Compute (const Handle(PrsMgr_PresentationManager)& t
       aGroup->AddPrimitiveArray (myCircle.Array());
     }
   }
+
+  if (myHasDragging)
+  {
+    gp_Dir aXDirection;
+    if (myReferenceAxis.Direction().X() > 0)
+      aXDirection = gp::DY();
+    else if (myReferenceAxis.Direction().Y() > 0)
+      aXDirection = gp::DZ();
+    else
+      aXDirection = gp::DX();
+
+    mySector.Init(myInnerRadius + myIndent * 2, gp_Ax1(gp::Origin(), myReferenceAxis.Direction()), aXDirection, myFacettesNumber * 2);
+    myDraggerGroup = thePrs->NewGroup();
+
+    Handle(Graphic3d_AspectFillArea3d) aFillArea = new Graphic3d_AspectFillArea3d();
+    myDraggerGroup->SetGroupPrimitivesAspect(aFillArea);
+    myDraggerGroup->AddPrimitiveArray(mySector.Array());
+
+    if (myHighlightDragger.IsNull())
+    {
+      myHighlightDragger = new Prs3d_Presentation(thePrsMgr->StructureManager());
+    }
+    else
+    {
+      myHighlightDragger->Clear();
+    }
+    {
+      Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup(myHighlightDragger);
+      aGroup->SetGroupPrimitivesAspect(aFillArea);
+      aGroup->AddPrimitiveArray(mySector.Array());
+    }
+  }
 }
index 1ba8d1c..1199979 100644 (file)
@@ -280,12 +280,14 @@ public:
   //! - FollowRotation - whether the manipulator will be rotated together with an object.
   struct BehaviorOnTransform {
 
-    BehaviorOnTransform() : FollowTranslation (Standard_True), FollowRotation (Standard_True) {}
+    BehaviorOnTransform() : FollowTranslation (Standard_True), FollowRotation (Standard_True), FollowDragging (Standard_True) {}
     BehaviorOnTransform& SetFollowTranslation (const Standard_Boolean theApply) { FollowTranslation = theApply; return *this; }
     BehaviorOnTransform& SetFollowRotation    (const Standard_Boolean theApply) { FollowRotation    = theApply; return *this; }
+    BehaviorOnTransform& SetFollowDragging    (const Standard_Boolean theApply) { FollowDragging    = theApply; return *this; }
 
     Standard_Boolean FollowTranslation;
     Standard_Boolean FollowRotation;
+    Standard_Boolean FollowDragging;
   };
 
   //! Sets behavior settings for transformation action carried on the manipulator,
@@ -446,6 +448,29 @@ protected: //! @name Auxiliary classes to fill presentation with proper primitiv
     Handle(Graphic3d_ArrayOfTriangles) myArray;
   };
 
+  class Sector : public Quadric
+  {
+  public:
+
+    Sector()
+      : Quadric(),
+      myRadius(0.0f)
+    { }
+
+    ~Sector() { }
+
+    void Init(const Standard_ShortReal theRadius,
+              const gp_Ax1&            thePosition,
+              const gp_Dir&            theXDirection,
+              const Standard_Integer   theSlicesNb = 5,
+              const Standard_Integer   theStacksNb = 5);
+
+  protected:
+
+    gp_Ax1             myPosition;
+    Standard_ShortReal myRadius;
+  };
+
   //! The class describes on axis sub-object.
   //! It includes sub-objects itself:
   //! -rotator
@@ -485,6 +510,11 @@ protected: //! @name Auxiliary classes to fill presentation with proper primitiv
       {
         myHighlightRotator->SetTransformPersistence (theTrsfPers);
       }
+
+      if (!myHighlightDragger.IsNull())
+      {
+        myHighlightDragger->SetTransformPersistence(theTrsfPers);
+      }
     }
 
     void Transform (const Handle(Geom_Transformation)& theTransformation)
@@ -503,6 +533,11 @@ protected: //! @name Auxiliary classes to fill presentation with proper primitiv
       {
         myHighlightRotator->SetTransformation (theTransformation);
       }
+
+      if (!myHighlightDragger.IsNull())
+      {
+        myHighlightDragger->SetTransformation(theTransformation);
+      }
     }
 
     Standard_Boolean HasTranslation() const { return myHasTranslation; }
@@ -511,12 +546,16 @@ protected: //! @name Auxiliary classes to fill presentation with proper primitiv
 
     Standard_Boolean HasScaling() const { return myHasScaling; }
 
+    Standard_Boolean HasDragging() const { return myHasDragging; }
+
     void SetTranslation (const Standard_Boolean theIsEnabled) { myHasTranslation = theIsEnabled; }
 
     void SetRotation (const Standard_Boolean theIsEnabled) { myHasRotation = theIsEnabled; }
 
     void SetScaling (const Standard_Boolean theIsEnabled) { myHasScaling = theIsEnabled; }
 
+    void SetDragging(const Standard_Boolean theIsEnabled) { myHasDragging = theIsEnabled; }
+
     Quantity_Color Color() const { return myColor; }
 
     Standard_ShortReal AxisLength() const { return myLength; }
@@ -531,12 +570,16 @@ protected: //! @name Auxiliary classes to fill presentation with proper primitiv
 
     const Handle(Prs3d_Presentation)& ScalerHighlightPrs() const { return myHighlightScaler; }
 
+    const Handle(Prs3d_Presentation)& DraggerHighlightPrs() const { return myHighlightDragger; }
+
     const Handle(Graphic3d_Group)& TranslatorGroup() const { return myTranslatorGroup; }
 
     const Handle(Graphic3d_Group)& RotatorGroup() const { return myRotatorGroup; }
 
     const Handle(Graphic3d_Group)& ScalerGroup() const { return myScalerGroup; }
 
+    const Handle(Graphic3d_Group)& DraggerGroup() const { return myDraggerGroup; }
+
     const Handle(Graphic3d_ArrayOfTriangles)& TriangleArray() const { return myTriangleArray; }
 
     void SetIndent (const Standard_ShortReal theValue) { myIndent = theValue; }
@@ -570,6 +613,7 @@ protected: //! @name Auxiliary classes to fill presentation with proper primitiv
   public:
 
     const gp_Pnt& TranslatorTipPosition() const { return myArrowTipPos; }
+    const Sector& DraggerSector() const { return mySector; }
     const Disk& RotatorDisk() const { return myCircle; }
     float RotatorDiskRadius() const { return myCircleRadius; }
     const Cube& ScalerCube() const { return myCube; }
@@ -593,11 +637,14 @@ protected: //! @name Auxiliary classes to fill presentation with proper primitiv
     Standard_ShortReal myDiskThickness;
     Standard_ShortReal myIndent; //!< Gap between visual part of the manipulator.
 
+    Standard_Boolean myHasDragging;
+
   protected:
 
     Standard_Integer myFacettesNumber;
 
     gp_Pnt   myArrowTipPos;
+    Sector   mySector;
     Disk     myCircle;
     float    myCircleRadius;
     Cube     myCube;
@@ -606,10 +653,12 @@ protected: //! @name Auxiliary classes to fill presentation with proper primitiv
     Handle(Graphic3d_Group) myTranslatorGroup;
     Handle(Graphic3d_Group) myScalerGroup;
     Handle(Graphic3d_Group) myRotatorGroup;
+    Handle(Graphic3d_Group) myDraggerGroup;
 
     Handle(Prs3d_Presentation) myHighlightTranslator;
     Handle(Prs3d_Presentation) myHighlightScaler;
     Handle(Prs3d_Presentation) myHighlightRotator;
+    Handle(Prs3d_Presentation) myHighlightDragger;
 
     Handle(Graphic3d_ArrayOfTriangles) myTriangleArray;
 
@@ -638,6 +687,9 @@ protected: //! @name Fields for interactive transformation. Fields only for inte
 
   //! Aspect used to color current detected part and current selected part.
   Handle(Prs3d_ShadingAspect) myHighlightAspect;
+
+  //! Aspect used to color sector part when it's selected.
+  Handle(Prs3d_ShadingAspect) myDraggerHighlight;
 public:
 
   DEFINE_STANDARD_RTTIEXT(AIS_Manipulator, AIS_InteractiveObject)
index 648876b..eea969a 100644 (file)
@@ -22,7 +22,8 @@ enum AIS_ManipulatorMode
   AIS_MM_None = 0,
   AIS_MM_Translation = 1,
   AIS_MM_Rotation,
-  AIS_MM_Scaling
+  AIS_MM_Scaling,
+  AIS_MM_TranslationPlane
 };
 
 #endif
\ No newline at end of file
index 1246488..52ee3ae 100755 (executable)
@@ -53,6 +53,8 @@ Prs3d_ToolCylinder.hxx
 Prs3d_ToolCylinder.cxx
 Prs3d_ToolQuadric.hxx
 Prs3d_ToolQuadric.cxx
+Prs3d_ToolSector.hxx
+Prs3d_ToolSector.cxx
 Prs3d_ToolSphere.hxx
 Prs3d_ToolSphere.cxx
 Prs3d_TypeOfHighlight.hxx
diff --git a/src/Prs3d/Prs3d_ToolSector.cxx b/src/Prs3d/Prs3d_ToolSector.cxx
new file mode 100644 (file)
index 0000000..ce8330d
--- /dev/null
@@ -0,0 +1,70 @@
+// Created on: 2019-02-25
+// Created by: Artem NOVIKOV
+// Copyright (c) 2019 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 <Prs3d_ToolSector.hxx>
+
+#include <Graphic3d_ArrayOfTriangles.hxx>
+#include <Poly_Array1OfTriangle.hxx>
+#include <Prs3d_ToolQuadric.hxx>
+
+//=======================================================================
+//function : Constructor
+//purpose  :
+//=======================================================================
+Prs3d_ToolSector::Prs3d_ToolSector (const Standard_Real    theRadius,
+                                    const Standard_Integer theNbSlices,
+                                    const Standard_Integer theNbStacks)
+: myRadius (theRadius)
+{
+  mySlicesNb = theNbSlices;
+  myStacksNb = theNbStacks;
+}
+
+//=======================================================================
+//function : Vertex
+//purpose  :
+//=======================================================================
+gp_Pnt Prs3d_ToolSector::Vertex (const Standard_Real theU, const Standard_Real theV)
+{
+  const Standard_Real aU      = theU * M_PI / 2.0;
+  const Standard_Real aRadius = myRadius * theV;
+  return gp_Pnt (Cos (aU) * aRadius,
+                 Sin (aU) * aRadius,
+                 0.0);
+}
+
+//=======================================================================
+//function : Add
+//purpose  :
+//=======================================================================
+gp_Dir Prs3d_ToolSector::Normal (const Standard_Real /*theU*/, const Standard_Real /*theV*/)
+{
+  return gp_Dir (0.0, 0.0, -1.0);
+}
+
+//=======================================================================
+//function : Perform
+//purpose  :
+//=======================================================================
+Handle(Graphic3d_ArrayOfTriangles) Prs3d_ToolSector::Create (const Standard_Real    theRadius,
+                                                             const Standard_Integer theNbSlices,
+                                                             const Standard_Integer theNbStacks,
+                                                             const gp_Trsf&         theTrsf)
+{
+  Handle(Graphic3d_ArrayOfTriangles) anArray;
+  Prs3d_ToolSector aTool (theRadius, theNbSlices, theNbStacks);
+  aTool.FillArray (anArray, theTrsf);
+  return anArray;
+}
diff --git a/src/Prs3d/Prs3d_ToolSector.hxx b/src/Prs3d/Prs3d_ToolSector.hxx
new file mode 100644 (file)
index 0000000..009dbe0
--- /dev/null
@@ -0,0 +1,52 @@
+// Created on: 2019-02-25
+// Created by: Artem NOVIKOV
+// Copyright (c) 2019 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 _Prs3d_ToolSector_HeaderFile
+#define _Prs3d_ToolSector_HeaderFile
+
+#include <Standard.hxx>
+#include <Prs3d_ToolQuadric.hxx>
+
+//! Standard presentation algorithm that outputs graphical primitives for disk surface.
+class Prs3d_ToolSector : public Prs3d_ToolQuadric
+{
+public:
+
+  //! Generate primitives for 3D quadric surface and return a filled array.
+  Standard_EXPORT static Handle(Graphic3d_ArrayOfTriangles) Create (const Standard_Real    theRadius,
+                                                                    const Standard_Integer theNbSlices,
+                                                                    const Standard_Integer theNbStacks,
+                                                                    const gp_Trsf&         theTrsf);
+public:
+
+  //! Initializes the algorithm.
+  Standard_EXPORT Prs3d_ToolSector (const Standard_Real    theRadius,
+                                    const Standard_Integer theNbSlices,
+                                    const Standard_Integer theNbStacks);
+protected:
+
+  //! Computes vertex at given parameter location of the surface.
+  Standard_EXPORT virtual gp_Pnt Vertex (const Standard_Real theU, const Standard_Real theV) Standard_OVERRIDE;
+
+  //! Computes normal at given parameter location of the surface.
+  Standard_EXPORT virtual gp_Dir Normal (const Standard_Real theU, const Standard_Real theV) Standard_OVERRIDE;
+
+protected:
+
+  Standard_Real myRadius;
+
+};
+
+#endif
index 0992d83..42b2fbd 100644 (file)
@@ -11662,6 +11662,7 @@ static int VManipulator (Draw_Interpretor& theDi,
   aCmd.AddOption ("autoActivate",      "... {0|1} - set activation on detection");
   aCmd.AddOption ("followTranslation", "... {0|1} - set following translation transform");
   aCmd.AddOption ("followRotation",    "... {0|1} - set following rotation transform");
+  aCmd.AddOption ("followDragging",    "... {0|1} - set following dragging transform");
   aCmd.AddOption ("gap",               "... value - set gap between sub-parts");
   aCmd.AddOption ("part",              "... axis mode {0|1} - set visual part");
   aCmd.AddOption ("pos",               "... x y z [nx ny nz [xx xy xz]] - set position of manipulator");
@@ -11750,6 +11751,10 @@ static int VManipulator (Draw_Interpretor& theDi,
   {
     aManipulator->ChangeTransformBehavior().SetFollowRotation (aCmd.ArgBool ("followRotation"));
   }
+  if (aCmd.HasOption("followDragging", 1, Standard_True))
+  {
+    aManipulator->ChangeTransformBehavior().SetFollowDragging(aCmd.ArgBool("followDragging"));
+  }
   if (aCmd.HasOption ("gap", 1, Standard_True))
   {
     aManipulator->SetGap (aCmd.ArgFloat ("gap"));
@@ -11759,9 +11764,9 @@ static int VManipulator (Draw_Interpretor& theDi,
     Standard_Integer anAxis = aCmd.ArgInt  ("part", 0);
     Standard_Integer aMode  = aCmd.ArgInt  ("part", 1);
     Standard_Boolean aOnOff = aCmd.ArgBool ("part", 2);
-    if (aMode < 1 || aMode > 3)
+    if (aMode < 1 || aMode > 4)
     {
-      std::cerr << theArgVec[0] << " error: mode value should be in range [1, 3].\n";
+      std::cerr << theArgVec[0] << " error: mode value should be in range [1, 4].\n";
       return 1;
     }
 
@@ -13019,6 +13024,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
       "\n      '-autoActivate      {0|1}'        - set activation on detection"
       "\n      '-followTranslation {0|1}'        - set following translation transform"
       "\n      '-followRotation    {0|1}'        - set following rotation transform"
+      "\n      '-followDragging    {0|1}'        - set following dragging transform"
       "\n      '-gap value'                      - set gap between sub-parts"
       "\n      '-part axis mode    {0|1}'        - set visual part"
       "\n      '-pos x y z [nx ny nz [xx xy xz]' - set position of manipulator"
diff --git a/tests/v3d/manipulator/dragg b/tests/v3d/manipulator/dragg
new file mode 100644 (file)
index 0000000..512bbac
--- /dev/null
@@ -0,0 +1,103 @@
+puts "====================================="
+puts "AIS_Manipulator - drag an object"
+puts "====================================="
+
+set anImage1 $imagedir/${casename}_1.png
+set anImage2 $imagedir/${casename}_2.png
+set anImage3 $imagedir/${casename}_3.png
+set anImage4 $imagedir/${casename}_4.png
+set anImage5 $imagedir/${casename}_5.png
+
+# -------------------------------------
+# create manipulated and helper objects
+# -------------------------------------
+
+pcylinder c1  5 10
+pcylinder c2 10 20
+ttranslate c1 105 0 20
+ttranslate c2 100 0 0
+trotate c1 100 0 25 0 1 0 90
+trotate c1 100 0 25 0 0 1 10
+
+# -------------------------------------
+# display manipulated objects
+# -------------------------------------
+
+vdisplay c1
+vdisplay c2
+vsetdispmode 1
+vaxo
+vfit
+
+# ------------------
+# attach manipulator
+# ------------------
+
+vmanipulator m -attach c1 -adjustPosition 1 -adjustSize 0 -enableModes 1 -size 40
+vmanipulator m -followRotation 1
+vmanipulator m -followTranslation 1
+vdump $anImage1
+
+# ----------------------------------------------------
+# test xz plane dragging transform (world reference frame)
+# ----------------------------------------------------
+
+set mouse_pick {211 129}
+set mouse_drag {284 248}
+
+vmoveto {*}$mouse_pick
+vselect {*}$mouse_pick
+vmanipulator m -startTransform {*}$mouse_pick
+vmanipulator m -transform {*}$mouse_drag
+vmanipulator m -stopTransform
+vselect 0 0
+vmoveto {*}$mouse_drag
+vdump $anImage2
+
+# -------------------------------------------
+# rotate around y axis
+# -------------------------------------------
+
+set mouse_pick {316 257}
+set mouse_drag {279 286}
+
+vmoveto {*}$mouse_pick
+vselect {*}$mouse_pick
+vmanipulator m -startTransform {*}$mouse_pick
+vmanipulator m -transform {*}$mouse_drag
+vmanipulator m -stopTransform
+vselect 0 0
+vmoveto {*}$mouse_drag
+vdump $anImage3
+
+# ----------------------------------------------------
+# test xy plane dragging transform (world reference frame)
+# ----------------------------------------------------
+
+set mouse_pick {278 267}
+set mouse_drag {156 276}
+
+vmoveto {*}$mouse_pick
+vselect {*}$mouse_pick
+vmanipulator m -startTransform {*}$mouse_pick
+vmanipulator m -transform {*}$mouse_drag
+vmanipulator m -stopTransform
+vselect 0 0
+vmoveto {*}$mouse_drag
+vdump $anImage4
+
+# ----------------------------------------------------
+# test yz plane dragging transform (world reference frame)
+# ----------------------------------------------------
+
+set mouse_pick {168 258}
+set mouse_drag {166 182}
+
+vmoveto {*}$mouse_pick
+vselect {*}$mouse_pick
+vmanipulator m -startTransform {*}$mouse_pick
+vmanipulator m -transform {*}$mouse_drag
+vmanipulator m -stopTransform
+vselect 0 0
+vmoveto {*}$mouse_drag
+vdump $anImage5
index b116ec6..9420013 100644 (file)
@@ -36,6 +36,9 @@ vfit
 vmanipulator m -attach c1 -adjustPosition 1 -adjustSize 0 -enableModes 1 -size 40
 vmanipulator m -followRotation 1
 vmanipulator m -followTranslation 1
+vmanipulator m -part 0 4 0
+vmanipulator m -part 1 4 0
+vmanipulator m -part 2 4 0
 
 # ----------------------------------------------------
 # test x translation transform (world reference frame)
@@ -103,6 +106,9 @@ vfit
 vmanipulator m -attach c1 -adjustPosition 1 -adjustSize 0 -enableModes 1 -size 40
 vmanipulator m -followRotation 1
 vmanipulator m -followTranslation 1
+vmanipulator m -part 0 4 0
+vmanipulator m -part 1 4 0
+vmanipulator m -part 2 4 0
 
 set mouse_pick {223 143}
 set mouse_drag {181 141}