]> OCCT Git - occt-copy.git/commitdiff
0027919: Visualization - support multiple transformation persistence groups within...
authorNatalia Ermolaeva <natalia.ermolaeva@opencascade.com>
Sat, 26 Jun 2021 07:36:40 +0000 (10:36 +0300)
committerNatalia Ermolaeva <natalia.ermolaeva@opencascade.com>
Sat, 26 Jun 2021 22:22:57 +0000 (01:22 +0300)
(cherry picked from commit 57f02cff1af4c6a62a586c96dcdb53c6fba5b370)

# Conflicts:
# src/SelectMgr/SelectMgr_ViewerSelector.cxx

19 files changed:
src/Graphic3d/Graphic3d_Group.cxx
src/Graphic3d/Graphic3d_Group.hxx
src/Graphic3d/Graphic3d_Layer.cxx
src/Graphic3d/Graphic3d_Structure.cxx
src/OpenGl/OpenGl_Structure.cxx
src/OpenGl/OpenGl_Structure.hxx
src/Prs3d/Prs3d_ArrowAspect.cxx
src/Prs3d/Prs3d_ArrowAspect.hxx
src/PrsDim/PrsDim_AngleDimension.cxx
src/PrsDim/PrsDim_Dimension.cxx
src/Select3D/Select3D_SensitiveEntity.cxx
src/Select3D/Select3D_SensitiveEntity.hxx
src/SelectMgr/SelectMgr_SelectableObjectSet.cxx
src/SelectMgr/SelectMgr_SelectableObjectSet.hxx
src/SelectMgr/SelectMgr_SensitiveEntitySet.cxx
src/SelectMgr/SelectMgr_SensitiveEntitySet.hxx
src/SelectMgr/SelectMgr_ViewerSelector.cxx
src/ViewerTest/ViewerTest_RelationCommands.cxx
tests/bugs/vis/bug27919 [new file with mode: 0644]

index 9ea7a7d29ba44608df87831f3cf0b38f15838e94..687dcf4d6032740e756ab04806b0e24136e4bc78 100644 (file)
@@ -458,6 +458,8 @@ void Graphic3d_Group::DumpJson (Standard_OStream& theOStream, Standard_Integer t
 
   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, this)
 
+  OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myTrsfPers.get())
+
   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myStructure)
   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myBounds)
 
index e26516f351e66b55325e617aee7d192d038ca463..69a1e3a67bb7e31f9d422c39c0f622abb89fa083 100644 (file)
@@ -32,6 +32,7 @@
 #include <Graphic3d_IndexBuffer.hxx>
 #include <Graphic3d_Buffer.hxx>
 #include <Graphic3d_BoundBuffer.hxx>
+#include <Graphic3d_TransformPers.hxx>
 #include <gp_Ax2.hxx>
 #include <TCollection_ExtendedString.hxx>
 
@@ -137,6 +138,12 @@ public:
   //! sets the flipping to theIsEnabled state.
   Standard_EXPORT virtual void SetFlippingOptions (const Standard_Boolean theIsEnabled, const gp_Ax2& theRefPlane) = 0;
 
+  //! Return transformation persistence.
+  const Handle(Graphic3d_TransformPers)& TransformPersistence() const { return myTrsfPers; }
+
+  //! Set transformation persistence.
+  virtual void SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers) { myTrsfPers = theTrsfPers; }
+
   //! Returns true if the group contains Polygons, Triangles or Quadrangles.
   bool ContainsFacet() const { return myContainsFacet; }
 
@@ -294,6 +301,7 @@ protected:
 
 protected:
 
+  Handle(Graphic3d_TransformPers) myTrsfPers; //!< current transform persistence
   Graphic3d_Structure* myStructure;     //!< pointer to the parent structure
   Graphic3d_BndBox4f   myBounds;        //!< bounding box
   bool                 myIsClosed;      //!< flag indicating closed volume
index 6b723c8f31118229743394c57927729b8727668c..84ec9c1ecb3e0d95d2f56e296d6abdcffde6619f 100644 (file)
@@ -171,6 +171,37 @@ inline bool isInfiniteBndBox (const Graphic3d_BndBox3d& theBndBox)
       || Abs (theBndBox.CornerMin().z()) >= ShortRealLast();
 }
 
+// =======================================================================
+// function : updateBoundingBox
+// purpose  :
+// =======================================================================
+void updateBoundingBox (const Handle(Graphic3d_Camera)& theCamera,
+                        const Graphic3d_Mat4d& aProjectionMat,
+                        const Graphic3d_Mat4d& aWorldViewMat,
+                        Standard_Integer theWindowWidth,
+                        Standard_Integer theWindowHeight,
+                        const Handle(Graphic3d_TransformPers)& theTrsfPers,
+                        Graphic3d_BndBox3d& theBox,
+                        Bnd_Box& theResBox)
+{
+  if (theTrsfPers.IsNull())
+  {
+    return;
+  }
+
+  if (!theBox.IsValid())
+  {
+    return;
+  }
+
+  theTrsfPers->Apply (theCamera, aProjectionMat, aWorldViewMat, theWindowWidth, theWindowHeight, theBox);
+  if (theBox.IsValid() && !isInfiniteBndBox (theBox))
+  {
+    theResBox.Add (gp_Pnt (theBox.CornerMin().x(), theBox.CornerMin().y(), theBox.CornerMin().z()));
+    theResBox.Add (gp_Pnt (theBox.CornerMax().x(), theBox.CornerMax().y(), theBox.CornerMax().z()));
+  }
+}
+
 // =======================================================================
 // function : BoundingBox
 // purpose  :
@@ -268,25 +299,34 @@ Bnd_Box Graphic3d_Layer::BoundingBox (Standard_Integer theViewId,
     {
       continue;
     }
-    else if (aStructure->TransformPersistence().IsNull()
-         || !aStructure->TransformPersistence()->IsTrihedronOr2d())
+    for (Graphic3d_SequenceOfGroup::Iterator aGroupIter(aStructure->Groups()); aGroupIter.More(); aGroupIter.Next())
     {
-      continue;
+      const Handle(Graphic3d_Group)& aGroup = aGroupIter.Value();
+      if (aGroup->TransformPersistence().IsNull())
+      {
+        continue;
+      }
+
+      const Graphic3d_BndBox4f& aBoxF = aGroup->BoundingBox();
+      Graphic3d_BndBox3d aBox = Graphic3d_BndBox3d (Graphic3d_Vec3d ((Standard_Real)aBoxF.CornerMin().x(),
+                                                                     (Standard_Real)aBoxF.CornerMin().y(),
+                                                                     (Standard_Real)aBoxF.CornerMin().z()),
+                                                    Graphic3d_Vec3d ((Standard_Real)aBoxF.CornerMax().x(),
+                                                                     (Standard_Real)aBoxF.CornerMax().y(),
+                                                                     (Standard_Real)aBoxF.CornerMax().z()));
+      updateBoundingBox (theCamera, aProjectionMat, aWorldViewMat, theWindowWidth, theWindowHeight,
+                         aGroup->TransformPersistence(), aBox, aResBox);
     }
 
-    Graphic3d_BndBox3d aBox = aStructure->BoundingBox();
-    if (!aBox.IsValid())
+    if (aStructure->TransformPersistence().IsNull()
+     || !aStructure->TransformPersistence()->IsTrihedronOr2d())
     {
       continue;
     }
 
-    aStructure->TransformPersistence()->Apply (theCamera, aProjectionMat, aWorldViewMat, theWindowWidth, theWindowHeight, aBox);
-    if (aBox.IsValid()
-    && !isInfiniteBndBox (aBox))
-    {
-      aResBox.Add (gp_Pnt (aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z()));
-      aResBox.Add (gp_Pnt (aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z()));
-    }
+    Graphic3d_BndBox3d aBox = aStructure->BoundingBox();
+    updateBoundingBox (theCamera, aProjectionMat, aWorldViewMat, theWindowWidth, theWindowHeight,
+                       aStructure->TransformPersistence(), aBox, aResBox);
   }
 
   return aResBox;
index a3f1e4e4d4f5719182680758d3e79604430573bb..16a56f40240499aa07d1da00f6ee0eb8d4a911bc 100644 (file)
@@ -802,6 +802,10 @@ Graphic3d_BndBox4f Graphic3d_Structure::minMaxCoord() const
   Graphic3d_BndBox4f aBnd;
   for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myCStructure->Groups()); aGroupIter.More(); aGroupIter.Next())
   {
+    if (!aGroupIter.Value()->TransformPersistence().IsNull())
+    {
+      continue;
+    }
     aBnd.Combine (aGroupIter.Value()->BoundingBox());
   }
   return aBnd;
index ded5c09c4a267ccff20cb1f6a052b8f317969fc6..6d26cd51bffb645fd7822d076def6e42f72a0c46 100644 (file)
@@ -394,10 +394,42 @@ void OpenGl_Structure::renderGeometry (const Handle(OpenGl_Workspace)& theWorksp
     myInstancedStructure->renderGeometry (theWorkspace, theHasClosed);
   }
 
+  const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
   for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
   {
+    const Handle(Graphic3d_TransformPers)& aTrsfPersistence = aGroupIter.Value()->TransformPersistence();
+    Standard_Boolean anOldCastShadows;
+    gp_Pnt aStartPnt;
+
+    if (!aTrsfPersistence.IsNull())
+    {
+      if (aTrsfPersistence->IsZoomOrRotate())
+      {
+        aCtx->ModelWorldState.Push();
+        OpenGl_Mat4& aModelWorld = aCtx->ModelWorldState.ChangeCurrent();
+        aStartPnt = aTrsfPersistence->AnchorPoint();
+        Graphic3d_Vec4 anAnchorPoint = aModelWorld * Graphic3d_Vec4 ((Standard_ShortReal)aStartPnt.X(),
+          (Standard_ShortReal)aStartPnt.Y(), (Standard_ShortReal)aStartPnt.Z(), 1.0f);
+        aModelWorld.SetColumn (3, Graphic3d_Vec4 (Graphic3d_Vec3 (0.0), 1.0));
+        aTrsfPersistence->SetAnchorPoint (gp_Pnt (anAnchorPoint.x(), anAnchorPoint.y(), anAnchorPoint.z()));
+      }
+      applyPersistence (aCtx, aTrsfPersistence, anOldCastShadows, Standard_True);
+      aCtx->ApplyModelViewMatrix();
+    }
+
     theHasClosed = theHasClosed || aGroupIter.Value()->IsClosed();
     aGroupIter.Value()->Render (theWorkspace);
+
+    if (!aTrsfPersistence.IsNull())
+    {
+      if (aTrsfPersistence->IsZoomOrRotate())
+      {
+        aTrsfPersistence->SetAnchorPoint (aStartPnt);
+        aCtx->ModelWorldState.Pop();
+      }
+      applyPersistence (aCtx, aTrsfPersistence, anOldCastShadows, Standard_False);
+      aCtx->ApplyModelViewMatrix();
+    }
   }
 }
 
@@ -446,26 +478,7 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
 #endif
   if (!myTrsfPers.IsNull())
   {
-    // temporarily disable shadows on non-3d objects
-    anOldCastShadows = aCtx->ShaderManager()->SetCastShadows (false);
-
-    aCtx->WorldViewState.Push();
-    OpenGl_Mat4& aWorldView = aCtx->WorldViewState.ChangeCurrent();
-    myTrsfPers->Apply (aCtx->Camera(),
-                       aCtx->ProjectionState.Current(), aWorldView,
-                       aCtx->VirtualViewport()[2], aCtx->VirtualViewport()[3]);
-
-  #if !defined(GL_ES_VERSION_2_0)
-    if (!aCtx->IsGlNormalizeEnabled()
-      && aCtx->core11ffp != NULL)
-    {
-      const Standard_Real aScale = Graphic3d_TransformUtils::ScaleFactor<Standard_ShortReal> (aWorldView);
-      if (Abs (aScale - 1.0) > Precision::Confusion())
-      {
-        aCtx->SetGlNormalizeEnabled (Standard_True);
-      }
-    }
-  #endif
+    applyPersistence (aCtx, myTrsfPers, anOldCastShadows, Standard_True);
 
   #ifdef GL_DEPTH_CLAMP
     if (myTrsfPers->Mode() == Graphic3d_TMF_CameraPers
@@ -623,7 +636,7 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con
 
   if (!myTrsfPers.IsNull())
   {
-    aCtx->WorldViewState.Pop();
+    applyPersistence (aCtx, myTrsfPers, anOldCastShadows, Standard_False);
     aCtx->ShaderManager()->SetCastShadows (anOldCastShadows);
   #ifdef GL_DEPTH_CLAMP
     if (toRestoreDepthClamp) { aCtx->core11fwd->glDisable (GL_DEPTH_CLAMP); }
@@ -666,6 +679,46 @@ Handle(Graphic3d_CStructure) OpenGl_Structure::ShadowLink (const Handle(Graphic3
   return new OpenGl_StructureShadow (theManager, this);
 }
 
+// =======================================================================
+// function : applyPersistence
+// purpose  :
+// =======================================================================
+void OpenGl_Structure::applyPersistence (const Handle(OpenGl_Context)& theContext,
+                                         const Handle(Graphic3d_TransformPers)& theTrsfPersistence,
+                                         Standard_Boolean& theOldCastShadows,
+                                         const Standard_Boolean toEnable) const
+{
+  if (toEnable)
+  {
+    // temporarily disable shadows on non-3d objects
+    theOldCastShadows = theContext->ShaderManager()->SetCastShadows (false);
+
+    theContext->WorldViewState.Push();
+    OpenGl_Mat4& aWorldView = theContext->WorldViewState.ChangeCurrent();
+    theTrsfPersistence->Apply (theContext->Camera(),
+                               theContext->ProjectionState.Current(), aWorldView,
+                               theContext->VirtualViewport()[2], theContext->VirtualViewport()[3]);
+
+  #if !defined(GL_ES_VERSION_2_0)
+    if (!theContext->IsGlNormalizeEnabled()
+      && theContext->core11ffp != NULL)
+    {
+      const Standard_Real aScale = Graphic3d_TransformUtils::ScaleFactor<Standard_ShortReal> (aWorldView);
+      if (Abs (aScale - 1.0) > Precision::Confusion())
+      {
+        theContext->SetGlNormalizeEnabled (Standard_True);
+      }
+    }
+  #endif
+  }
+  else
+  {
+    theContext->WorldViewState.Pop();
+    theContext->ShaderManager()->SetCastShadows (theOldCastShadows);
+    theContext->ApplyModelViewMatrix();
+  }
+}
+
 //=======================================================================
 //function : DumpJson
 //purpose  : 
index e603e309731553ee02663ef537228bfe49fbef6f..48aa3f36412b44c91b1248663502498637887641 100644 (file)
@@ -146,6 +146,18 @@ protected:
   //! Render the bounding box.
   Standard_EXPORT void renderBoundingBox(const Handle(OpenGl_Workspace)& theWorkspace) const;
 
+
+  //! Apply transform persistence into context.
+  //! It disables shadows on non - 3d objects when toEnable is true and restores overwise.
+  //! @param theWorkspace current workspace
+  //! @param theTrsfPersistence transform persistence
+  //! @param theOldCastShadows state of the the previous cast shadows state
+  //! @param toEnable flag to switch ON/OFF persistence
+  Standard_EXPORT void applyPersistence (const Handle(OpenGl_Context)& theContext,
+                                         const Handle(Graphic3d_TransformPers)& theTrsfPersistence,
+                                         Standard_Boolean& theOldCastShadows,
+                                         const Standard_Boolean toEnable) const;
+
 protected:
 
   OpenGl_Structure*          myInstancedStructure;
index 130d868900a712d4966f70dbfa1ce61e13e3a7b8..aac00a74ef583f1979ae0bf9742b335335fae807 100644 (file)
@@ -26,7 +26,8 @@ IMPLEMENT_STANDARD_RTTIEXT(Prs3d_ArrowAspect, Prs3d_BasicAspect)
 Prs3d_ArrowAspect::Prs3d_ArrowAspect()
 : myArrowAspect (new Graphic3d_AspectLine3d (Quantity_Color(Quantity_NOC_WHITE), Aspect_TOL_SOLID, 1.0)),
   myAngle (M_PI / 180.0 * 10.0),
-  myLength(1.0)
+  myLength (1.0),
+  myIsZoomable (Standard_True)
 {
   //
 }
index f63e59a41790194aa0c1300817ab320a3965d4b9..0c9276f0615881271934132f6b343803de644242 100644 (file)
@@ -51,6 +51,12 @@ public:
   //! Returns the current value of the length used when drawing an arrow.
   Standard_Real Length() const { return myLength; }
 
+  //! Turns usage of arrow zoomable on/off
+  void SetZoomable (bool theIsZoomable) { myIsZoomable = theIsZoomable; }
+
+  //! Returns TRUE when the Arrow Zoomable is on.
+  bool Zoomable() const { return myIsZoomable; }
+
   void SetColor (const Quantity_Color& theColor) { myArrowAspect->SetColor (theColor); }
   
   const Handle(Graphic3d_AspectLine3d)& Aspect() const { return myArrowAspect; }
@@ -65,6 +71,7 @@ protected:
   Handle(Graphic3d_AspectLine3d) myArrowAspect;
   Standard_Real myAngle;
   Standard_Real myLength;
+  Standard_Boolean myIsZoomable;
 
 };
 
index a58af9cc218877acd83fc1fd7022ca14a60976b7..7fdb93b51853e03e21f0b9b2a1e12e0688b3364c 100644 (file)
@@ -691,8 +691,14 @@ void PrsDim_AngleDimension::Compute (const Handle(PrsMgr_PresentationManager)& ,
 
   aFirstArrowBegin  = aFirstAttach;
   aSecondArrowBegin = aSecondAttach;
-  aFirstArrowEnd    = aFirstAttach.Translated (-aFirstArrowVec);
-  aSecondArrowEnd   = aSecondAttach.Translated (-aSecondArrowVec);
+  aFirstArrowEnd    = aFirstAttach;
+  aSecondArrowEnd   = aSecondAttach;
+
+  if (aDimensionAspect->ArrowAspect()->Zoomable())
+  {
+    aFirstArrowEnd.Translate (-aFirstArrowVec);
+    aSecondArrowEnd.Translate (-aSecondArrowVec);
+  }
 
   // Group1: stenciling text and the angle dimension arc
   thePresentation->NewGroup();
index deba152a405fd9ffcaf648c54aef3b92b0e821f2..9bb67a07846c7d5d29c17513ddd10e11d741fb61 100644 (file)
@@ -363,6 +363,7 @@ void PrsDim_Dimension::DrawArrow (const Handle(Prs3d_Presentation)& thePresentat
 
   Standard_Real aLength = myDrawer->DimensionAspect()->ArrowAspect()->Length();
   Standard_Real anAngle = myDrawer->DimensionAspect()->ArrowAspect()->Angle();
+  Standard_Boolean isZoomable = myDrawer->DimensionAspect()->ArrowAspect()->Zoomable();
 
   if (myDrawer->DimensionAspect()->IsArrows3d())
   {
@@ -375,16 +376,17 @@ void PrsDim_Dimension::DrawArrow (const Handle(Prs3d_Presentation)& thePresentat
   }
   else
   {
+    gp_Pnt aLocation = isZoomable ? theLocation : gp::Origin();
     gp_Pnt aLeftPoint (gp::Origin());
     gp_Pnt aRightPoint (gp::Origin());
     const gp_Dir& aPlane = GetPlane().Axis().Direction();
 
-    PointsForArrow (theLocation, theDirection, aPlane, aLength, anAngle, aLeftPoint, aRightPoint);
+    PointsForArrow (aLocation, theDirection, aPlane, aLength, anAngle, aLeftPoint, aRightPoint);
 
     Handle(Graphic3d_ArrayOfTriangles) anArrow = new Graphic3d_ArrayOfTriangles(3);
 
     anArrow->AddVertex (aLeftPoint);
-    anArrow->AddVertex (theLocation);
+    anArrow->AddVertex (aLocation);
     anArrow->AddVertex (aRightPoint);
 
     // Set aspect for arrow triangles
@@ -400,6 +402,10 @@ void PrsDim_Dimension::DrawArrow (const Handle(Prs3d_Presentation)& thePresentat
 
     aGroup->SetPrimitivesAspect (aShadingStyle);
     aGroup->AddPrimitiveArray (anArrow);
+    if (!isZoomable)
+    {
+      aGroup->SetTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_ZoomPers, theLocation));
+    }
   }
 
   SelectionGeometry::Arrow& aSensitiveArrow = mySelectionGeom.NewArrow();
@@ -707,10 +713,16 @@ void PrsDim_Dimension::DrawLinearDimension (const Handle(Prs3d_Presentation)& th
 
   aFirstArrowBegin  = aLineBegPoint;
   aSecondArrowBegin = aLineEndPoint;
-  aFirstArrowEnd    = aLineBegPoint.Translated (-gp_Vec (aFirstArrowDir).Scaled (anArrowLength));
-  aSecondArrowEnd   = aLineEndPoint.Translated (-gp_Vec (aSecondArrowDir).Scaled (anArrowLength));
+  aFirstArrowEnd    = aLineBegPoint;
+  aSecondArrowEnd   = aLineEndPoint;
+
+  if (aDimensionAspect->ArrowAspect()->Zoomable())
+  {
+    aFirstArrowEnd.Translate (-gp_Vec (aFirstArrowDir).Scaled (anArrowLength));
+    aSecondArrowEnd.Translate (-gp_Vec (aSecondArrowDir).Scaled (anArrowLength));
+  }
 
-  gp_Pnt aCenterLineBegin = isArrowsExternal 
+  gp_Pnt aCenterLineBegin = isArrowsExternal
     ? aLineBegPoint : aFirstArrowEnd;
 
   gp_Pnt aCenterLineEnd = isArrowsExternal || theIsOneSide
index 97bc6a36841e107efb6eead7f748fc05d9906f9a..d63246c9e31fc7a069fc408e6730e7b08a2d671f 100644 (file)
@@ -40,7 +40,8 @@ void Select3D_SensitiveEntity::DumpJson (Standard_OStream& theOStream, Standard_
   OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
 
   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myOwnerId.get())
-  OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, mySFactor)
+  OCCT_DUMP_FIELD_VALUES_DUMPED(theOStream, theDepth, myTrsfPers.get())
+  OCCT_DUMP_FIELD_VALUE_NUMERICAL(theOStream, mySFactor)
 
   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, NbSubElements());
 
index 3015a14d5b52e4970a7dd5f5a904201ac78fb554..9abc398b47701592f1b85ec5128d57e88fabfb37 100644 (file)
@@ -27,6 +27,7 @@
 #include <SelectMgr_SelectingVolumeManager.hxx>
 #include <TopLoc_Location.hxx>
 
+class Graphic3d_TransformPers;
 class SelectMgr_EntityOwner;
 
 //! Abstract framework to define 3D sensitive entities.
@@ -93,6 +94,12 @@ public:
   //! Otherwise, returns identity matrix.
   virtual gp_GTrsf InvInitLocation() const { return gp_GTrsf(); }
 
+  //! Return transformation persistence.
+  const Handle(Graphic3d_TransformPers)& TransformPersistence() const { return myTrsfPers; }
+
+  //! Set transformation persistence.
+  virtual void SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers) { myTrsfPers = theTrsfPers; }
+
   //! Dumps the content of me into the stream
   Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
 
@@ -103,6 +110,7 @@ protected:
 protected:
 
   Handle(SelectMgr_EntityOwner) myOwnerId;
+  Handle(Graphic3d_TransformPers)  myTrsfPers;
   Standard_Integer mySFactor;
 
 };
index 15be832ffd207ffc0a0aba24067c0715e2abb412..4c343b573c25cf6d0eb304cce7afba1e84f9e2bf 100644 (file)
@@ -125,15 +125,40 @@ namespace
 
         Bnd_Box aBoundingBox;
         anObject->BoundingBox (aBoundingBox);
-        if (aBoundingBox.IsVoid()
-         || anObject->TransformPersistence().IsNull())
+        if (!aBoundingBox.IsVoid()
+         && !anObject->TransformPersistence().IsNull())
+        {
+          anObject->TransformPersistence()->Apply (theCamera, theProjectionMat, theWorldViewMat, theWidth, theHeight, aBoundingBox);
+        }
+        // processing presentations with own transform persistence
+        PrsMgr_Presentations& aPresentations = anObject->Presentations();
+        for (PrsMgr_Presentations::Iterator aPrsIter (aPresentations); aPrsIter.More(); aPrsIter.Next())
+        {
+          const Handle(PrsMgr_Presentation)& aPrs3d = aPrsIter.ChangeValue();
+          for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aPrs3d->Groups()); aGroupIter.More(); aGroupIter.Next())
+          {
+            if (!aGroupIter.Value()->TransformPersistence().IsNull())
+            {
+              const Graphic3d_BndBox4f& aBndBox = aGroupIter.Value()->BoundingBox();
+              if (!aBndBox.IsValid())
+              {
+                continue;
+              }
+              Bnd_Box aGroupBoundingBox;
+              aGroupBoundingBox.Update (aBndBox.CornerMin().x(), aBndBox.CornerMin().y(), aBndBox.CornerMin().z(),
+                                        aBndBox.CornerMax().x(), aBndBox.CornerMax().y(), aBndBox.CornerMax().z());
+              aGroupIter.Value()->TransformPersistence()->Apply (theCamera, theProjectionMat, theWorldViewMat, theWidth, theHeight, aGroupBoundingBox);
+              aBoundingBox.Add (aGroupBoundingBox);
+            }
+          }
+        }
+
+        if (aBoundingBox.IsVoid())
         {
           myBoundings.Add (new Select3D_HBndBox3d());
         }
         else
         {
-          anObject->TransformPersistence()->Apply (theCamera, theProjectionMat, theWorldViewMat, theWidth, theHeight, aBoundingBox);
-
           const gp_Pnt aMin = aBoundingBox.CornerMin();
           const gp_Pnt aMax = aBoundingBox.CornerMax();
           myBoundings.Add (new Select3D_HBndBox3d (Select3D_Vec3 (aMin.X(), aMin.Y(), aMin.Z()),
index 2925e42b427c7ca03df55d0883809b842c0c5c94..51dea02574d294c721da947d4930f7b2ade1ee4c 100644 (file)
@@ -190,6 +190,18 @@ private:
   {
     if (theObject->TransformPersistence().IsNull())
     {
+      PrsMgr_Presentations& aPresentations = theObject->Presentations();
+      for (PrsMgr_Presentations::Iterator aPrsIter (aPresentations); aPrsIter.More(); aPrsIter.Next())
+      {
+        const Handle(PrsMgr_Presentation)& aPrs3d = aPrsIter.ChangeValue();
+        for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aPrs3d->Groups()); aGroupIter.More(); aGroupIter.Next())
+        {
+          if (!aGroupIter.Value()->TransformPersistence().IsNull())
+          {
+            return SelectMgr_SelectableObjectSet::BVHSubset_3dPersistent;
+          }
+        }
+      }
       return SelectMgr_SelectableObjectSet::BVHSubset_3d;
     }
     else if (theObject->TransformPersistence()->Mode() == Graphic3d_TMF_2d)
index bad281a5e138fb97d799f8a1cbfac5c95e05f636..bf50591a638b56363d472600c484eedbc994a935 100644 (file)
 
 #include <SelectMgr_SensitiveEntitySet.hxx>
 
+#include <Graphic3d_TransformPers.hxx>
 #include <Select3D_SensitiveEntity.hxx>
 #include <SelectMgr_SensitiveEntity.hxx>
 
 IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_SensitiveEntitySet, BVH_PrimitiveSet3d)
 
+class SelectMgr_AdaptorPersistent : public Standard_Transient
+{
+  DEFINE_STANDARD_RTTIEXT(SelectMgr_AdaptorPersistent, Standard_Transient)
+public:
+  SelectMgr_AdaptorPersistent (const Handle(Graphic3d_Camera)& theCamera,
+                               const Graphic3d_Mat4d& theProjectionMat,
+                               const Graphic3d_Mat4d& theWorldViewMat,
+                               const Graphic3d_WorldViewProjState& theViewState,
+                               const Standard_Integer theViewportWidth,
+                               const Standard_Integer theViewportHeight)
+    : myCamera (theCamera), myProjectionMat (theProjectionMat),
+      myWorldViewMat (theWorldViewMat), myViewState (theViewState),
+      myViewportWidth (theViewportWidth), myViewportHeight (theViewportHeight) {}
+
+  const Handle(Graphic3d_Camera)& Camera() const { return myCamera; }
+  const Graphic3d_Mat4d& ProjectionMat() const { return myProjectionMat; }
+  const Graphic3d_Mat4d& WorldViewMat() const { return myWorldViewMat; }
+  const Graphic3d_WorldViewProjState& ViewState() const { return myViewState; }
+  Standard_Integer ViewportWidth() const { return myViewportWidth; }
+  Standard_Integer ViewportHeight() const { return myViewportHeight; }
+
+private:
+  Handle(Graphic3d_Camera) myCamera;
+  Graphic3d_Mat4d myProjectionMat;
+  Graphic3d_Mat4d myWorldViewMat;
+  Graphic3d_WorldViewProjState myViewState;
+  Standard_Integer myViewportWidth;
+  Standard_Integer myViewportHeight;
+};
+
+DEFINE_STANDARD_HANDLE(SelectMgr_AdaptorPersistent, Standard_Transient)
+IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_AdaptorPersistent, Standard_Transient)
+
 //=======================================================================
 // function : SelectMgr_SensitiveEntitySet
 // purpose  :
@@ -47,6 +81,11 @@ void SelectMgr_SensitiveEntitySet::Append (const Handle(SelectMgr_SensitiveEntit
   {
     addOwner (theEntity->BaseSensitive()->OwnerId());
   }
+  mySensitives.Add (theEntity);
+  if (!theEntity->BaseSensitive()->TransformPersistence().IsNull())
+  {
+    myHasEntityWithPersistence = Standard_True;
+  }
   MarkDirty();
 }
 
@@ -70,6 +109,11 @@ void SelectMgr_SensitiveEntitySet::Append (const Handle(SelectMgr_Selection)& th
     {
       addOwner (aSelEntIter.Value()->BaseSensitive()->OwnerId());
     }
+    mySensitives.Add (aSelEntIter.Value());
+    if (!aSelEntIter.Value()->BaseSensitive()->TransformPersistence().IsNull())
+    {
+      myHasEntityWithPersistence = Standard_True;
+    }
   }
   MarkDirty();
 }
@@ -96,6 +140,7 @@ void SelectMgr_SensitiveEntitySet::Remove (const Handle(SelectMgr_Selection)& th
 
     mySensitives.RemoveLast();
     removeOwner (aSelEntIter.Value()->BaseSensitive()->OwnerId());
+    // TODO: update myHasEntityWithPersistence state, clear myAdaptorPersistent if false
   }
 
   MarkDirty();
@@ -107,7 +152,31 @@ void SelectMgr_SensitiveEntitySet::Remove (const Handle(SelectMgr_Selection)& th
 //=======================================================================
 Select3D_BndBox3d SelectMgr_SensitiveEntitySet::Box (const Standard_Integer theIndex) const
 {
-  return GetSensitiveById (theIndex)->BaseSensitive()->BoundingBox();
+  const Handle(Select3D_SensitiveEntity)& aSensitive = GetSensitiveById (theIndex)->BaseSensitive();
+  if (aSensitive->TransformPersistence().IsNull() || myAdaptorPersistent.IsNull())
+  {
+    return GetSensitiveById (theIndex)->BaseSensitive()->BoundingBox();
+  }
+
+  Select3D_BndBox3d aSensitiveBndBox = GetSensitiveById (theIndex)->BaseSensitive()->BoundingBox();
+  Select3D_BndBox3d aBndBoxInPersistence;
+
+  Bnd_Box aBndBox (
+    gp_Pnt (aSensitiveBndBox.CornerMin().x(), aSensitiveBndBox.CornerMin().y(), aSensitiveBndBox.CornerMin().z()),
+    gp_Pnt (aSensitiveBndBox.CornerMax().x(), aSensitiveBndBox.CornerMin().y(), aSensitiveBndBox.CornerMin().z()));
+
+  aSensitive->TransformPersistence()->Apply (
+    myAdaptorPersistent->Camera(),
+    myAdaptorPersistent->ProjectionMat(),
+    myAdaptorPersistent->WorldViewMat(),
+    myAdaptorPersistent->ViewportWidth(),
+    myAdaptorPersistent->ViewportHeight(),
+    aBndBox);
+
+  gp_Pnt aBndBoxMin = aBndBox.CornerMin();
+  gp_Pnt aBndBoxMax = aBndBox.CornerMax();
+  return Select3D_BndBox3d (SelectMgr_Vec3 (aBndBoxMin.X(), aBndBoxMin.Y(), aBndBoxMin.Z()),
+                            SelectMgr_Vec3 (aBndBoxMax.X(), aBndBoxMax.Y(), aBndBoxMax.Z()));
 }
 
 //=======================================================================
@@ -189,3 +258,29 @@ void SelectMgr_SensitiveEntitySet::removeOwner (const Handle(SelectMgr_EntityOwn
     }
   }
 }
+
+//=======================================================================
+// function : UpdateBVH
+// purpose  :
+//=======================================================================
+void SelectMgr_SensitiveEntitySet::UpdateBVH (const Handle(Graphic3d_Camera)& theCamera,
+                                              const Graphic3d_Mat4d& theProjectionMat,
+                                              const Graphic3d_Mat4d& theWorldViewMat,
+                                              const Graphic3d_WorldViewProjState& theViewState,
+                                              const Standard_Integer theViewportWidth,
+                                              const Standard_Integer theViewportHeight)
+{
+  if (!myHasEntityWithPersistence)
+  {
+    return;
+  }
+  myAdaptorPersistent = new SelectMgr_AdaptorPersistent(theCamera, theProjectionMat,
+                                                        theWorldViewMat,
+                                                        theViewState,
+                                                        theViewportWidth,
+                                                        theViewportHeight);
+
+  MarkDirty();
+  BVH();
+  myAdaptorPersistent.Nullify();
+}
index 61f8d84f921959dd942ab00a3d4d58af27ae319d..7a8b3e593e5225e20cd8a4e8e6ec6120417907ad 100644 (file)
@@ -25,6 +25,8 @@
 #include <SelectMgr_SensitiveEntity.hxx>
 #include <SelectMgr_Selection.hxx>
 
+class SelectMgr_AdaptorPersistent;
+
 typedef NCollection_IndexedMap<Handle(SelectMgr_SensitiveEntity)> SelectMgr_IndexedMapOfHSensitive;
 typedef NCollection_DataMap<Handle(SelectMgr_EntityOwner), Standard_Integer> SelectMgr_MapOfOwners;
 
@@ -79,6 +81,18 @@ public:
   //! Returns map of owners.
   const SelectMgr_MapOfOwners& Owners() const { return myOwnersMap; }
 
+  //! Returns map of entities.
+  Standard_EXPORT Standard_Boolean HasEntityWithPersistence() const { return myHasEntityWithPersistence; }
+
+  //! Updates outdated BVH trees and remembers the last state of the
+  //! camera view-projection matrices and viewport (window) dimensions.
+  Standard_EXPORT void UpdateBVH (const Handle(Graphic3d_Camera)& theCamera,
+                                  const Graphic3d_Mat4d& theProjectionMat,
+                                  const Graphic3d_Mat4d& theWorldViewMat,
+                                  const Graphic3d_WorldViewProjState& theViewState,
+                                  const Standard_Integer theViewportWidth,
+                                  const Standard_Integer theViewportHeight);
+  
 protected:
 
   //! Adds entity owner to the map of owners (or increases its counter if it is already there).
@@ -91,6 +105,8 @@ private:
 
   SelectMgr_IndexedMapOfHSensitive mySensitives;     //!< Map of entities and its corresponding index in BVH
   SelectMgr_MapOfOwners myOwnersMap;                 //!< Map of entity owners and its corresponding number of sensitives
+  Handle(SelectMgr_AdaptorPersistent) myAdaptorPersistent; //!< camera parameters to apply transform persistence
+  Standard_Boolean myHasEntityWithPersistence;       //!< flag if some of sensitive entity has own transform persistence
 };
 
 #endif // _SelectMgr_SensitiveEntitySet_HeaderFile
index 30805b3e38375a5a359c2f6208b9946340cfbae2..2f9cb907d8a8353d9bd212ebe50e7ebaf2d284ce 100644 (file)
@@ -369,6 +369,17 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
     return;
   }
 
+  if (anEntitySet->HasEntityWithPersistence())
+  {
+    Standard_Integer aWidth;
+    Standard_Integer aHeight;
+    mySelectingVolumeMgr.WindowSize (aWidth, aHeight);
+    anEntitySet->UpdateBVH (mySelectingVolumeMgr.Camera(),
+                            mySelectingVolumeMgr.Camera()->ProjectionMatrix(),
+                            mySelectingVolumeMgr.Camera()->OrientationMatrix(),
+                            mySelectingVolumeMgr.Camera()->WorldViewProjState(),
+                            aWidth, aHeight);
+  }
   const opencascade::handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH();
   gp_GTrsf aInversedTrsf;
   if (theObject->HasTransformation() || !theObject->TransformPersistence().IsNull())
@@ -400,7 +411,8 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
   SelectMgr_SelectingVolumeManager aMgr = aInversedTrsf.Form() != gp_Identity
                                         ? theMgr.ScaleAndTransform (1, aInversedTrsf, NULL)
                                         : theMgr;
-  if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0),
+  if (!anEntitySet->HasEntityWithPersistence()
+   && !aMgr.Overlaps (aSensitivesTree->MinPoint (0),
                       aSensitivesTree->MaxPoint (0)))
   {
     return;
@@ -551,9 +563,33 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
           const Handle(SelectMgr_SensitiveEntity)& aSensitive = anEntitySet->GetSensitiveById (anIdx);
           if (aSensitive->IsActiveForSelection())
           {
+            gp_GTrsf aInversedSensitiveTrsf;
+            if (aSensitive->BaseSensitive()->TransformPersistence().IsNull())
+            {
+              aInversedSensitiveTrsf = aInversedTrsf;
+            }
+            else
+            {
+              gp_GTrsf aTPers;
+              Graphic3d_Mat4d aMat = aSensitive->BaseSensitive()->TransformPersistence()->Compute (theCamera, theProjectionMat, theWorldViewMat, theViewportWidth, theViewportHeight);
+
+              aTPers.SetValue (1, 1, aMat.GetValue (0, 0));
+              aTPers.SetValue (1, 2, aMat.GetValue (0, 1));
+              aTPers.SetValue (1, 3, aMat.GetValue (0, 2));
+              aTPers.SetValue (2, 1, aMat.GetValue (1, 0));
+              aTPers.SetValue (2, 2, aMat.GetValue (1, 1));
+              aTPers.SetValue (2, 3, aMat.GetValue (1, 2));
+              aTPers.SetValue (3, 1, aMat.GetValue (2, 0));
+              aTPers.SetValue (3, 2, aMat.GetValue (2, 1));
+              aTPers.SetValue (3, 3, aMat.GetValue (2, 2));
+              aTPers.SetTranslationPart (gp_XYZ (aMat.GetValue (0, 3), aMat.GetValue (1, 3), aMat.GetValue (2, 3)));
+
+              aInversedSensitiveTrsf = (aTPers * gp_GTrsf(theObject->Transformation())).Inverted();
+            }
+
             const Handle(Select3D_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
-            computeFrustum (anEnt, theMgr, aMgr, aInversedTrsf, aScaledTrnsfFrustums, aTmpMgr);
-            checkOverlap (anEnt, aInversedTrsf, aTmpMgr);
+            computeFrustum (anEnt, theMgr, aMgr, aInversedSensitiveTrsf, aScaledTrnsfFrustums, aTmpMgr);
+            checkOverlap (anEnt, aInversedSensitiveTrsf, aTmpMgr);
           }
         }
       }
index 2c85248e1e7facdad69b87ad9cbb1961e902b51c..cf799e20591d7b413c89b5ca1479bb6f32ad0d5f 100644 (file)
@@ -377,6 +377,16 @@ static int ParseDimensionParams (Standard_Integer  theArgNum,
       if (aLocalParam == "internal") { theAspect->SetArrowOrientation (Prs3d_DAO_Internal); }
       if (aLocalParam == "fit")      { theAspect->SetArrowOrientation (Prs3d_DAO_Fit); }
     }
+    else if (aParam.IsEqual ("-zoomablearrow"))
+    {
+      TCollection_AsciiString aValue (theArgVec[++anIt]);
+      if (!aValue.IsIntegerValue())
+      {
+        Message::SendFail() << "Error: zoomable arrow value should be 0 or 1.";
+        return 1;
+      }
+      theAspect->ArrowAspect()->SetZoomable (Draw::Atoi (aValue.ToCString()) != 0);
+    }
     else if (aParam.IsEqual ("-arrowlength") || aParam.IsEqual ("-arlen"))
     {
       TCollection_AsciiString aValue (theArgVec[++anIt]);
@@ -1936,6 +1946,7 @@ void ViewerTest::RelationCommands(Draw_Interpretor& theCommands)
       "[-font FontName]\n"
       "[-label left|right|hcenter|hfit top|bottom|vcenter|vfit]\n"
       "[-arrow external|internal|fit]\n"
+      "[-zoomablearrow 0|1]\n"
       "[{-arrowlength|-arlen} RealArrowLength]\n"
       "[{-arrowangle|-arangle} ArrowAngle(degrees)]\n"
       "[-plane xoy|yoz|zox]\n"
@@ -1971,6 +1982,7 @@ void ViewerTest::RelationCommands(Draw_Interpretor& theCommands)
     "[-font FontName]\n"
     "[-label left|right|hcenter|hfit top|bottom|vcenter|vfit]\n"
     "[-arrow external|internal|fit]\n"
+    "[-zoomablearrow 0|1]\n"
     "[{-arrowlength|-arlen} RealArrowLength]\n"
     "[{-arrowangle|-arangle} ArrowAngle(degrees)]\n"
     "[-plane xoy|yoz|zox]\n"
diff --git a/tests/bugs/vis/bug27919 b/tests/bugs/vis/bug27919
new file mode 100644 (file)
index 0000000..038837c
--- /dev/null
@@ -0,0 +1,25 @@
+puts "============="
+puts "0027919: Visualization - support multiple transformation persistence groups within single presentation"
+puts "============="
+
+vinit 
+vtrihedron t1
+
+vpoint p11 -25 50 0
+vpoint p12 25 50 0
+vdimension dim -length -plane xoy -shapes p11 p12
+vdimparam dim -flyout 1 -arrowlength 30 -arrow internal -label hcenter -zoomablearrow 0
+
+vpoint p21 -100 0 0
+vpoint p22 0 0 0
+vpoint p23 100 0 0
+vdimension angle -angle -shapes p21 p22 p23 -arrowlength 30 -zoomablearrow 0
+
+vtop 
+vfit
+vzoom 1.5
+
+if {[vreadpixel 182 119 rgb name] != "BLACK"} { puts "ERROR: the arrow of the dimension should not be zoomable" }
+if {[vreadpixel 149 195 rgb name] != "BLACK"} { puts "ERROR: the arrow of the angle dimension should not be zoomable" }
+
+vdump $imagedir/${casename}.png