Added transform persistence property to Graphic3d_Group and Select3D_SensitiveEntity.
SelectMgr_ViewerSelector, Graphic3d_Layer and OpenGl_Structure have been updated
to process per-group transform persistence within picking, ZFit and rendering.
Added zoomable state to Prs3d_ArrowAspect supported by PrsDim_Dimension.
Added gp_GTrsf::SetMat4(), opposite to gp_GTrsf::GetMat4().
//purpose :
//=============================================================================
Graphic3d_CStructure::Graphic3d_CStructure (const Handle(Graphic3d_StructureManager)& theManager)
-: myZLayer (Graphic3d_ZLayerId_Default),
- Priority (Structure_MAX_PRIORITY / 2),
+: Priority (Structure_MAX_PRIORITY / 2),
PreviousPriority (Structure_MAX_PRIORITY / 2),
ContainsFacet (0),
+ //
+ myGraphicDriver (theManager->GraphicDriver()),
+ myZLayer (Graphic3d_ZLayerId_Default),
+ myIsCulled (Standard_True),
+ myBndBoxClipCheck(Standard_True),
+ myHasGroupTrsf (Standard_False),
+ //
IsInfinite (0),
stick (0),
highlight (0),
HLRValidation (0),
IsForHighlight (Standard_False),
IsMutable (Standard_False),
- Is2dText (Standard_False),
- myGraphicDriver (theManager->GraphicDriver()),
- myIsCulled (Standard_True),
- myBndBoxClipCheck(Standard_True)
+ Is2dText (Standard_False)
{
Id = myGraphicDriver->NewIdentification();
}
//! Low-level graphic structure interface
class Graphic3d_CStructure : public Standard_Transient
{
+ DEFINE_STANDARD_RTTIEXT(Graphic3d_CStructure, Standard_Transient)
protected:
//! Auxiliary wrapper to iterate through structure list.
//! Set transformation persistence.
virtual void SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers) { myTrsfPers = theTrsfPers; }
+ //! Return TRUE if some groups might have transform persistence; FALSE by default.
+ bool HasGroupTransformPersistence() const { return myHasGroupTrsf; }
+
+ //! Set if some groups might have transform persistence.
+ void SetGroupTransformPersistence (bool theValue) { myHasGroupTrsf = theValue; }
+
//! @return associated clip planes
const Handle(Graphic3d_SequenceOfHClipPlane)& ClipPlanes() const
{
public:
- int Id;
- Graphic3d_ZLayerId myZLayer;
- int Priority;
- int PreviousPriority;
-
- int ContainsFacet;
-
Handle(Graphic3d_ViewAffinity) ViewAffinity; //!< view affinity mask
- unsigned IsInfinite : 1;
- unsigned stick : 1; //!< displaying state - should be set when structure has been added to scene graph (but can be in hidden state)
- unsigned highlight : 1;
- unsigned visible : 1; //!< visibility flag - can be used to suppress structure while leaving it in the scene graph
- unsigned HLRValidation : 1;
- unsigned IsForHighlight : 1;
- unsigned IsMutable : 1;
- unsigned Is2dText : 1;
+ Standard_Integer Id;
+ Standard_Integer Priority;
+ Standard_Integer PreviousPriority;
+
+ Standard_Integer ContainsFacet;
protected:
Handle(Graphic3d_SequenceOfHClipPlane) myClipPlanes;
Handle(Graphic3d_PresentationAttributes) myHighlightStyle; //! Current highlight style; is set only if highlight flag is true
+ Graphic3d_ZLayerId myZLayer;
+
mutable Standard_Boolean myIsCulled; //!< A status specifying is structure needs to be rendered after BVH tree traverse
Standard_Boolean myBndBoxClipCheck; //!< Flag responsible for checking of bounding box clipping before drawing of object
+ Standard_Boolean myHasGroupTrsf; //!< flag specifying that some groups might have transform persistence
+
public:
- DEFINE_STANDARD_RTTIEXT(Graphic3d_CStructure,Standard_Transient) // Type definition
+ unsigned IsInfinite : 1;
+ unsigned stick : 1; //!< displaying state - should be set when structure has been added to scene graph (but can be in hidden state)
+ unsigned highlight : 1;
+ unsigned visible : 1; //!< visibility flag - can be used to suppress structure while leaving it in the scene graph
+ unsigned HLRValidation : 1;
+ unsigned IsForHighlight : 1;
+ unsigned IsMutable : 1;
+ unsigned Is2dText : 1;
};
&& !myBounds.IsValid();
}
+// =======================================================================
+// function : SetTransformPersistence
+// purpose :
+// =======================================================================
+void Graphic3d_Group::SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers)
+{
+ if (myTrsfPers != theTrsfPers)
+ {
+ myTrsfPers = theTrsfPers;
+ if (!IsDeleted()
+ && !theTrsfPers.IsNull())
+ {
+ myStructure->CStructure()->SetGroupTransformPersistence (true);
+ }
+ }
+}
+
// =======================================================================
// function : SetMinMaxValues
// purpose :
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)
class Graphic3d_Structure;
class Graphic3d_ArrayOfPrimitives;
class Graphic3d_Text;
+class Graphic3d_TransformPers;
//! This class allows the definition of groups
//! of primitives inside of graphic objects (presentations).
//! 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.
+ Standard_EXPORT virtual void SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers);
+
//! Returns true if the group contains Polygons, Triangles or Quadrangles.
bool ContainsFacet() const { return myContainsFacet; }
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
|| Abs (theBndBox.CornerMin().z()) >= ShortRealLast();
}
+//! Extend bounding box with another box.
+static void addBox3dToBndBox (Bnd_Box& theResBox,
+ const Graphic3d_BndBox3d& theBox)
+{
+ // skip too big boxes to prevent float overflow at camera parameters calculation
+ 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 :
}
}
+ if (!theToIncludeAuxiliary
+ && aStructure->HasGroupTransformPersistence())
+ {
+ // add per-group transform-persistence point in a bounding box
+ for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aStructure->Groups()); aGroupIter.More(); aGroupIter.Next())
+ {
+ const Handle(Graphic3d_Group)& aGroup = aGroupIter.Value();
+ if (!aGroup->TransformPersistence().IsNull()
+ && aGroup->TransformPersistence()->IsZoomOrRotate())
+ {
+ const gp_Pnt anAnchor = aGroup->TransformPersistence()->AnchorPoint();
+ myBoundingBox[aBoxId].Add (anAnchor);
+ }
+ }
+ }
+
Graphic3d_BndBox3d aBox = aStructure->BoundingBox();
if (!aBox.IsValid())
{
{
aStructure->TransformPersistence()->Apply (theCamera, aProjectionMat, aWorldViewMat, theWindowWidth, theWindowHeight, aBox);
}
-
- // skip too big boxes to prevent float overflow at camera parameters calculation
- if (aBox.IsValid()
- && !isInfiniteBndBox (aBox))
- {
- myBoundingBox[aBoxId].Add (gp_Pnt (aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z()));
- myBoundingBox[aBoxId].Add (gp_Pnt (aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z()));
- }
+ addBox3dToBndBox (myBoundingBox[aBoxId], aBox);
}
}
{
continue;
}
- else if (aStructure->TransformPersistence().IsNull()
- || !aStructure->TransformPersistence()->IsTrihedronOr2d())
+
+ // handle per-group transformation persistence specifically
+ if (aStructure->HasGroupTransformPersistence())
{
- continue;
+ for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aStructure->Groups()); aGroupIter.More(); aGroupIter.Next())
+ {
+ const Handle(Graphic3d_Group)& aGroup = aGroupIter.Value();
+ const Graphic3d_BndBox4f& aBoxF = aGroup->BoundingBox();
+ if (aGroup->TransformPersistence().IsNull()
+ || !aBoxF.IsValid())
+ {
+ continue;
+ }
+
+ Graphic3d_BndBox3d aBoxCopy (Graphic3d_Vec3d (aBoxF.CornerMin().xyz()),
+ Graphic3d_Vec3d (aBoxF.CornerMax().xyz()));
+ aGroup->TransformPersistence()->Apply (theCamera, aProjectionMat, aWorldViewMat, theWindowWidth, theWindowHeight, aBoxCopy);
+ addBox3dToBndBox (aResBox, aBoxCopy);
+ }
}
- Graphic3d_BndBox3d aBox = aStructure->BoundingBox();
- if (!aBox.IsValid())
+ const Graphic3d_BndBox3d& aStructBox = aStructure->BoundingBox();
+ if (!aStructBox.IsValid()
+ || 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 aBoxCopy = aStructBox;
+ aStructure->TransformPersistence()->Apply (theCamera, aProjectionMat, aWorldViewMat, theWindowWidth, theWindowHeight, aBoxCopy);
+ addBox3dToBndBox (aResBox, aBoxCopy);
}
return aResBox;
GraphicClear (theWithDestruction);
myCStructure->ContainsFacet = 0;
+ myCStructure->SetGroupTransformPersistence (false);
myStructureManager->Clear (this, theWithDestruction);
Update (true);
Graphic3d_BndBox4f aBnd;
for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myCStructure->Groups()); aGroupIter.More(); aGroupIter.Next())
{
+ if (!aGroupIter.Value()->TransformPersistence().IsNull())
+ {
+ continue; // should be translated to current view orientation to make sense
+ }
+
aBnd.Combine (aGroupIter.Value()->BoundingBox());
}
return aBnd;
//! @param theWorldView world-view matrix to modify
//! @param theViewportWidth viewport width
//! @param theViewportHeight viewport height
+ //! @param theAnchor if not NULL, overrides anchor point
template<class T>
void Apply (const Handle(Graphic3d_Camera)& theCamera,
const NCollection_Mat4<T>& theProjection,
NCollection_Mat4<T>& theWorldView,
const Standard_Integer theViewportWidth,
- const Standard_Integer theViewportHeight) const;
+ const Standard_Integer theViewportHeight,
+ const gp_Pnt* theAnchor = NULL) const;
//! Dumps the content of me into the stream
Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
const NCollection_Mat4<T>& theProjection,
NCollection_Mat4<T>& theWorldView,
const Standard_Integer theViewportWidth,
- const Standard_Integer theViewportHeight) const
+ const Standard_Integer theViewportHeight,
+ const gp_Pnt* theAnchor) const
{
(void )theViewportWidth;
(void )theProjection;
{
// Compute reference point for transformation in untransformed projection space.
NCollection_Mat4<Standard_Real> aWorldView = theCamera->OrientationMatrix();
- Graphic3d_TransformUtils::Translate (aWorldView, myParams.Params3d.PntX, myParams.Params3d.PntY, myParams.Params3d.PntZ);
+ if (theAnchor != NULL)
+ {
+ Graphic3d_TransformUtils::Translate (aWorldView, theAnchor->X(), theAnchor->Y(), theAnchor->Z());
+ }
+ else
+ {
+ Graphic3d_TransformUtils::Translate (aWorldView, myParams.Params3d.PntX, myParams.Params3d.PntY, myParams.Params3d.PntZ);
+ }
+
if ((myMode & Graphic3d_TMF_RotatePers) != 0)
{
// lock rotation by nullifying rotation component
//! Returns scaling factor from 3x3 affine matrix.
template<class T>
- static Standard_Real ScaleFactor (const typename MatrixType<T>::Mat4& theMatrix);
+ static Standard_Real ScaleFactor (const NCollection_Mat4<T>& theMatrix)
+ {
+ // The determinant of the matrix should give the scale factor (cubed).
+ const T aDeterminant = theMatrix.DeterminantMat3();
+ return Pow (static_cast<Standard_Real> (aDeterminant), 1.0 / 3.0);
+ }
}
// =======================================================================
return Standard_True;
}
-// =======================================================================
-// function : ScaleFactor
-// purpose :
-// =======================================================================
-template<class T>
-static Standard_Real Graphic3d_TransformUtils::ScaleFactor (const typename MatrixType<T>::Mat4& theMatrix)
-{
- // The determinant of the matrix should give the scale factor (cubed).
- const T aDeterminant = (theMatrix.GetValue (0, 0) * theMatrix.GetValue (1, 1) * theMatrix.GetValue (2, 2) +
- theMatrix.GetValue (0, 1) * theMatrix.GetValue (1, 2) * theMatrix.GetValue (2, 0) +
- theMatrix.GetValue (0, 2) * theMatrix.GetValue (1, 0) * theMatrix.GetValue (2, 1))
- - (theMatrix.GetValue (0, 2) * theMatrix.GetValue (1, 1) * theMatrix.GetValue (2, 0) +
- theMatrix.GetValue (0, 0) * theMatrix.GetValue (1, 2) * theMatrix.GetValue (2, 1) +
- theMatrix.GetValue (0, 1) * theMatrix.GetValue (1, 0) * theMatrix.GetValue (2, 2));
-
- return Pow (static_cast<Standard_Real> (aDeterminant), 1.0 / 3.0);
-}
-
#endif // _Graphic3d_TransformUtils_HeaderFile
*this = Transposed();
}
+ //! Return determinant of the matrix.
+ Element_t Determinant() const
+ {
+ return (GetValue (0, 0) * GetValue (1, 1) * GetValue (2, 2)
+ + GetValue (0, 1) * GetValue (1, 2) * GetValue (2, 0)
+ + GetValue (0, 2) * GetValue (1, 0) * GetValue (2, 1))
+ - (GetValue (0, 2) * GetValue (1, 1) * GetValue (2, 0)
+ + GetValue (0, 0) * GetValue (1, 2) * GetValue (2, 1)
+ + GetValue (0, 1) * GetValue (1, 0) * GetValue (2, 2));
+ }
+
//! Return adjoint (adjugate matrix, e.g. conjugate transpose).
Standard_NODISCARD NCollection_Mat3 Adjoint() const
{
return anInv;
}
+ //! Return determinant of the 3x3 sub-matrix.
+ Element_t DeterminantMat3() const
+ {
+ return (GetValue (0, 0) * GetValue (1, 1) * GetValue (2, 2)
+ + GetValue (0, 1) * GetValue (1, 2) * GetValue (2, 0)
+ + GetValue (0, 2) * GetValue (1, 0) * GetValue (2, 1))
+ - (GetValue (0, 2) * GetValue (1, 1) * GetValue (2, 0)
+ + GetValue (0, 0) * GetValue (1, 2) * GetValue (2, 1)
+ + GetValue (0, 1) * GetValue (1, 0) * GetValue (2, 2));
+ }
+
//! Return adjoint (adjugate matrix, e.g. conjugate transpose).
Standard_NODISCARD NCollection_Mat4<Element_t> Adjoint() const
{
myInstancedStructure->renderGeometry (theWorkspace, theHasClosed);
}
+ bool anOldCastShadows = false;
+ const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
{
- theHasClosed = theHasClosed || aGroupIter.Value()->IsClosed();
- aGroupIter.Value()->Render (theWorkspace);
+ const OpenGl_Group* aGroup = aGroupIter.Value();
+
+ const Handle(Graphic3d_TransformPers)& aTrsfPers = aGroup->TransformPersistence();
+ if (!aTrsfPers.IsNull())
+ {
+ applyPersistence (aCtx, aTrsfPers, true, anOldCastShadows);
+ aCtx->ApplyModelViewMatrix();
+ }
+
+ theHasClosed = theHasClosed || aGroup->IsClosed();
+ aGroup->Render (theWorkspace);
+
+ if (!aTrsfPers.IsNull())
+ {
+ revertPersistence (aCtx, aTrsfPers, true, anOldCastShadows);
+ aCtx->ApplyModelViewMatrix();
+ }
}
}
#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, false, anOldCastShadows);
#ifdef GL_DEPTH_CLAMP
if (myTrsfPers->Mode() == Graphic3d_TMF_CameraPers
if (!myTrsfPers.IsNull())
{
- aCtx->WorldViewState.Pop();
- aCtx->ShaderManager()->SetCastShadows (anOldCastShadows);
+ revertPersistence (aCtx, myTrsfPers, false, anOldCastShadows);
#ifdef GL_DEPTH_CLAMP
if (toRestoreDepthClamp) { aCtx->core11fwd->glDisable (GL_DEPTH_CLAMP); }
#endif
return new OpenGl_StructureShadow (theManager, this);
}
+// =======================================================================
+// function : applyPersistence
+// purpose :
+// =======================================================================
+void OpenGl_Structure::applyPersistence (const Handle(OpenGl_Context)& theCtx,
+ const Handle(Graphic3d_TransformPers)& theTrsfPers,
+ const Standard_Boolean theIsLocal,
+ Standard_Boolean& theOldCastShadows) const
+{
+ // temporarily disable shadows on non-3d objects
+ theOldCastShadows = theCtx->ShaderManager()->SetCastShadows (false);
+
+ theCtx->WorldViewState.Push();
+ OpenGl_Mat4& aWorldView = theCtx->WorldViewState.ChangeCurrent();
+
+ if (theIsLocal
+ && theTrsfPers->IsZoomOrRotate())
+ {
+ // move anchor point to presentation location
+ theCtx->ModelWorldState.Push();
+ OpenGl_Mat4& aModelWorld = theCtx->ModelWorldState.ChangeCurrent();
+ gp_Pnt aStartPnt = theTrsfPers->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)); // reset translation part
+ aStartPnt.SetCoord (anAnchorPoint.x(), anAnchorPoint.y(), anAnchorPoint.z());
+
+ theTrsfPers->Apply (theCtx->Camera(),
+ theCtx->ProjectionState.Current(), aWorldView,
+ theCtx->VirtualViewport()[2], theCtx->VirtualViewport()[3],
+ &aStartPnt);
+ }
+ else
+ {
+ theTrsfPers->Apply (theCtx->Camera(),
+ theCtx->ProjectionState.Current(), aWorldView,
+ theCtx->VirtualViewport()[2], theCtx->VirtualViewport()[3]);
+ }
+
+#if !defined(GL_ES_VERSION_2_0)
+ if (!theCtx->IsGlNormalizeEnabled()
+ && theCtx->core11ffp != NULL)
+ {
+ const Standard_Real aScale = Graphic3d_TransformUtils::ScaleFactor (aWorldView);
+ if (Abs (aScale - 1.0) > Precision::Confusion())
+ {
+ theCtx->SetGlNormalizeEnabled (true);
+ }
+ }
+#endif
+}
+
+// =======================================================================
+// function : revertPersistence
+// purpose :
+// =======================================================================
+void OpenGl_Structure::revertPersistence (const Handle(OpenGl_Context)& theCtx,
+ const Handle(Graphic3d_TransformPers)& theTrsfPers,
+ const Standard_Boolean theIsLocal,
+ const Standard_Boolean theOldCastShadows) const
+{
+ if (theIsLocal
+ && theTrsfPers->IsZoomOrRotate())
+ {
+ theCtx->ModelWorldState.Pop();
+ }
+ theCtx->WorldViewState.Pop();
+ theCtx->ShaderManager()->SetCastShadows (theOldCastShadows);
+}
+
//=======================================================================
//function : DumpJson
//purpose :
//! 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 otherwise.
+ //! @param[in] theCtx current context
+ //! @param[in] theTrsfPers transform persistence
+ //! @param[in] theIsLocal specifies if transform persistence is defined locally or to entire presentation
+ //! @param[out] theOldCastShadows state of the previous cast shadows state
+ Standard_EXPORT void applyPersistence (const Handle(OpenGl_Context)& theCtx,
+ const Handle(Graphic3d_TransformPers)& theTrsfPersistence,
+ const Standard_Boolean theIsLocal,
+ Standard_Boolean& theOldCastShadows) const;
+
+ //! Restore context from transform persistence changes.
+ //! @param[in] theCtx current context
+ //! @param[in] theTrsfPers transform persistence
+ //! @param[in] theIsLocal specifies if transform persistence is defined locally or to entire presentation
+ //! @param[in] theOldCastShadows state of the previous cast shadows state
+ Standard_EXPORT void revertPersistence (const Handle(OpenGl_Context)& theCtx,
+ const Handle(Graphic3d_TransformPers)& theTrsfPersistence,
+ const Standard_Boolean theIsLocal,
+ const Standard_Boolean theOldCastShadows) const;
+
protected:
OpenGl_Structure* myInstancedStructure;
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)
{
//
}
//! 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; TRUE by default.
+ bool IsZoomable() const { return myIsZoomable; }
+
void SetColor (const Quantity_Color& theColor) { myArrowAspect->SetColor (theColor); }
const Handle(Graphic3d_AspectLine3d)& Aspect() const { return myArrowAspect; }
Handle(Graphic3d_AspectLine3d) myArrowAspect;
Standard_Real myAngle;
Standard_Real myLength;
+ Standard_Boolean myIsZoomable;
};
aFirstArrowBegin = aFirstAttach;
aSecondArrowBegin = aSecondAttach;
- aFirstArrowEnd = aFirstAttach.Translated (-aFirstArrowVec);
- aSecondArrowEnd = aSecondAttach.Translated (-aSecondArrowVec);
+ aFirstArrowEnd = aFirstAttach;
+ aSecondArrowEnd = aSecondAttach;
+
+ if (aDimensionAspect->ArrowAspect()->IsZoomable())
+ {
+ aFirstArrowEnd.Translate (-aFirstArrowVec);
+ aSecondArrowEnd.Translate (-aSecondArrowVec);
+ }
// Group1: stenciling text and the angle dimension arc
thePresentation->NewGroup();
Standard_Real aLength = myDrawer->DimensionAspect()->ArrowAspect()->Length();
Standard_Real anAngle = myDrawer->DimensionAspect()->ArrowAspect()->Angle();
+ Standard_Boolean isZoomable = myDrawer->DimensionAspect()->ArrowAspect()->IsZoomable();
if (myDrawer->DimensionAspect()->IsArrows3d())
{
}
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
aGroup->SetPrimitivesAspect (aShadingStyle);
aGroup->AddPrimitiveArray (anArrow);
+ if (!isZoomable)
+ {
+ aGroup->SetTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_ZoomPers, theLocation));
+ }
}
SelectionGeometry::Arrow& aSensitiveArrow = mySelectionGeom.NewArrow();
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()->IsZoomable())
+ {
+ 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
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());
#include <SelectMgr_SelectingVolumeManager.hxx>
#include <TopLoc_Location.hxx>
+class Graphic3d_TransformPers;
class SelectMgr_EntityOwner;
//! Abstract framework to define 3D sensitive entities.
//! 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;
protected:
Handle(SelectMgr_EntityOwner) myOwnerId;
+ Handle(Graphic3d_TransformPers) myTrsfPers;
Standard_Integer mySFactor;
};
const Handle(Graphic3d_Camera)& theCamera,
const Graphic3d_Mat4d& theProjectionMat,
const Graphic3d_Mat4d& theWorldViewMat,
- const Standard_Integer theWidth,
- const Standard_Integer theHeight)
+ const Graphic3d_Vec2i& theWinSize)
: myObjects (theObjects)
{
myBoundings.ReSize (myObjects.Size());
Bnd_Box aBoundingBox;
anObject->BoundingBox (aBoundingBox);
- if (aBoundingBox.IsVoid()
- || anObject->TransformPersistence().IsNull())
+ if (!aBoundingBox.IsVoid()
+ && !anObject->TransformPersistence().IsNull())
+ {
+ anObject->TransformPersistence()->Apply (theCamera,
+ theProjectionMat, theWorldViewMat,
+ theWinSize.x(), theWinSize.y(),
+ aBoundingBox);
+ }
+
+ // processing presentations with own transform persistence
+ for (PrsMgr_Presentations::Iterator aPrsIter (anObject->Presentations()); aPrsIter.More(); aPrsIter.Next())
+ {
+ const Handle(PrsMgr_Presentation)& aPrs3d = aPrsIter.Value();
+ if (!aPrs3d->CStructure()->HasGroupTransformPersistence())
+ {
+ continue;
+ }
+
+ for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aPrs3d->Groups()); aGroupIter.More(); aGroupIter.Next())
+ {
+ const Handle(Graphic3d_Group)& aGroup = aGroupIter.Value();
+ const Graphic3d_BndBox4f& aBndBox = aGroup->BoundingBox();
+ if (aGroup->TransformPersistence().IsNull()
+ || !aBndBox.IsValid())
+ {
+ continue;
+ }
+
+ Bnd_Box aGroupBox;
+ aGroupBox.Update (aBndBox.CornerMin().x(), aBndBox.CornerMin().y(), aBndBox.CornerMin().z(),
+ aBndBox.CornerMax().x(), aBndBox.CornerMax().y(), aBndBox.CornerMax().z());
+ aGroup->TransformPersistence()->Apply (theCamera,
+ theProjectionMat, theWorldViewMat,
+ theWinSize.x(), theWinSize.y(),
+ aGroupBox);
+ aBoundingBox.Add (aGroupBox);
+ }
+ }
+
+ 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()),
// Purpose :
//=============================================================================
SelectMgr_SelectableObjectSet::SelectMgr_SelectableObjectSet()
-: myLastWidth (0),
- myLastHeight (0)
{
myBVH[BVHSubset_2dPersistent] = new BVH_Tree<Standard_Real, 3>();
myBVH[BVHSubset_3dPersistent] = new BVH_Tree<Standard_Real, 3>();
// Function: UpdateBVH
// Purpose :
//=============================================================================
-void SelectMgr_SelectableObjectSet::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)
+void SelectMgr_SelectableObjectSet::UpdateBVH (const Handle(Graphic3d_Camera)& theCam,
+ const Graphic3d_Vec2i& theWinSize)
{
// -----------------------------------------
// check and update 3D BVH tree if necessary
myIsDirty[BVHSubset_3d] = Standard_False;
}
- if (!theCamera.IsNull())
+ if (!theCam.IsNull())
{
- const Standard_Boolean isWindowSizeChanged =
- (myLastHeight != theViewportHeight) || (myLastWidth != theViewportWidth);
+ const Standard_Boolean isWinSizeChanged = myLastWinSize != theWinSize;
+ const Graphic3d_Mat4d& aProjMat = theCam->ProjectionMatrix();
+ const Graphic3d_Mat4d& aWorldViewMat = theCam->OrientationMatrix();
+ const Graphic3d_WorldViewProjState& aViewState = theCam->WorldViewProjState();
// -----------------------------------------------------
// check and update 3D persistence BVH tree if necessary
// -----------------------------------------------------
- if (!IsEmpty (BVHSubset_3dPersistent) &&
- (myIsDirty[BVHSubset_3dPersistent] || myLastViewState.IsChanged (theViewState) || isWindowSizeChanged))
+ if (!IsEmpty (BVHSubset_3dPersistent)
+ && (myIsDirty[BVHSubset_3dPersistent]
+ || myLastViewState.IsChanged (aViewState)
+ || isWinSizeChanged))
{
// construct adaptor over private fields to provide direct access for the BVH builder
BVHBuilderAdaptorPersistent anAdaptor (myObjects[BVHSubset_3dPersistent],
- theCamera, theProjectionMat, theWorldViewMat, theViewportWidth, theViewportHeight);
+ theCam, aProjMat, aWorldViewMat, theWinSize);
// update corresponding BVH tree data structure
myBuilder[BVHSubset_3dPersistent]->Build (&anAdaptor, myBVH[BVHSubset_3dPersistent].get(), anAdaptor.Box());
// -----------------------------------------------------
// check and update 2D persistence BVH tree if necessary
// -----------------------------------------------------
- if (!IsEmpty (BVHSubset_2dPersistent) &&
- (myIsDirty[BVHSubset_2dPersistent] || myLastViewState.IsProjectionChanged (theViewState) || isWindowSizeChanged))
+ if (!IsEmpty (BVHSubset_2dPersistent)
+ && (myIsDirty[BVHSubset_2dPersistent]
+ || myLastViewState.IsProjectionChanged (aViewState)
+ || isWinSizeChanged))
{
// construct adaptor over private fields to provide direct access for the BVH builder
BVHBuilderAdaptorPersistent anAdaptor (myObjects[BVHSubset_2dPersistent],
- theCamera, theProjectionMat, SelectMgr_SelectableObjectSet_THE_IDENTITY_MAT, theViewportWidth, theViewportHeight);
+ theCam, aProjMat, SelectMgr_SelectableObjectSet_THE_IDENTITY_MAT, theWinSize);
// update corresponding BVH tree data structure
myBuilder[BVHSubset_2dPersistent]->Build (&anAdaptor, myBVH[BVHSubset_2dPersistent].get(), anAdaptor.Box());
myIsDirty[BVHSubset_2dPersistent] = Standard_False;
// keep last view state
- myLastViewState = theViewState;
+ myLastViewState = aViewState;
}
// keep last window state
- myLastWidth = theViewportWidth;
- myLastHeight = theViewportHeight;
+ myLastWinSize = theWinSize;
}
//=============================================================================
TCollection_AsciiString separator;
OCCT_DUMP_FIELD_VALUE_STRING (theOStream, separator)
}
- OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myLastWidth)
- OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myLastHeight)
+ OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myLastWinSize.x())
+ OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myLastWinSize.y())
}
//! 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);
+ Standard_EXPORT void UpdateBVH (const Handle(Graphic3d_Camera)& theCam,
+ const Graphic3d_Vec2i& theWinSize);
//! Marks every BVH subset for update.
Standard_EXPORT void MarkDirty();
{
if (theObject->TransformPersistence().IsNull())
{
+ const PrsMgr_Presentations& aPresentations = theObject->Presentations();
+ for (PrsMgr_Presentations::Iterator aPrsIter (aPresentations); aPrsIter.More(); aPrsIter.Next())
+ {
+ const Handle(PrsMgr_Presentation)& aPrs3d = aPrsIter.ChangeValue();
+ if (aPrs3d->CStructure()->HasGroupTransformPersistence())
+ {
+ return SelectMgr_SelectableObjectSet::BVHSubset_3dPersistent;
+ }
+ }
return SelectMgr_SelectableObjectSet::BVHSubset_3d;
}
else if (theObject->TransformPersistence()->Mode() == Graphic3d_TMF_2d)
opencascade::handle<BVH_Tree<Standard_Real, 3> > myBVH[BVHSubsetNb]; //!< BVH tree computed for each subset
Handle(Select3D_BVHBuilder3d) myBuilder[BVHSubsetNb]; //!< Builder allocated for each subset
Standard_Boolean myIsDirty[BVHSubsetNb]; //!< Dirty flag for each subset
- Graphic3d_WorldViewProjState myLastViewState; //!< Last view-projection state used for construction of BVH
- Standard_Integer myLastWidth; //!< Last viewport's (window's) width used for construction of BVH
- Standard_Integer myLastHeight; //!< Last viewport's (window's) height used for construction of BVH
+ Graphic3d_WorldViewProjState myLastViewState; //!< Last view-projection state used for construction of BVH
+ Graphic3d_Vec2i myLastWinSize; //!< Last viewport's (window's) width used for construction of BVH
friend class Iterator;
};
#include <SelectMgr_SensitiveEntitySet.hxx>
+#include <Graphic3d_TransformPers.hxx>
#include <Select3D_SensitiveEntity.hxx>
#include <SelectMgr_SensitiveEntity.hxx>
{
addOwner (theEntity->BaseSensitive()->OwnerId());
}
+ if (!theEntity->BaseSensitive()->TransformPersistence().IsNull())
+ {
+ myHasEntityWithPersistence = Standard_True;
+ }
MarkDirty();
}
{
for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next())
{
- if (!aSelEntIter.Value()->BaseSensitive()->IsKind (STANDARD_TYPE(Select3D_SensitiveEntity)))
+ const Handle(SelectMgr_SensitiveEntity)& aSensEnt = aSelEntIter.Value();
+ if (!aSensEnt->BaseSensitive()->IsKind (STANDARD_TYPE(Select3D_SensitiveEntity)))
{
- aSelEntIter.Value()->ResetSelectionActiveStatus();
+ aSensEnt->ResetSelectionActiveStatus();
continue;
}
const Standard_Integer anExtent = mySensitives.Extent();
- if (mySensitives.Add (aSelEntIter.Value()) > anExtent)
+ if (mySensitives.Add (aSensEnt) > anExtent)
+ {
+ addOwner (aSensEnt->BaseSensitive()->OwnerId());
+ }
+ if (!aSensEnt->BaseSensitive()->TransformPersistence().IsNull())
{
- addOwner (aSelEntIter.Value()->BaseSensitive()->OwnerId());
+ myHasEntityWithPersistence = Standard_True;
}
}
MarkDirty();
//=======================================================================
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())
+ {
+ return Select3D_BndBox3d();
+ }
+
+ return aSensitive->BoundingBox();
}
//=======================================================================
typedef NCollection_IndexedMap<Handle(SelectMgr_SensitiveEntity)> SelectMgr_IndexedMapOfHSensitive;
typedef NCollection_DataMap<Handle(SelectMgr_EntityOwner), Standard_Integer> SelectMgr_MapOfOwners;
-//! This class is used to store all calculated sensitive entites of one selectable
-//! object. It provides an interface for building BVH tree which is used to speed-up
+//! This class is used to store all calculated sensitive entities of one selectable object.
+//! It provides an interface for building BVH tree which is used to speed-up
//! the performance of searching for overlap among sensitives of one selectable object
class SelectMgr_SensitiveEntitySet : public BVH_PrimitiveSet3d
{
//! Returns map of owners.
const SelectMgr_MapOfOwners& Owners() const { return myOwnersMap; }
+ //! Returns map of entities.
+ Standard_Boolean HasEntityWithPersistence() const { return myHasEntityWithPersistence; }
+
protected:
//! Adds entity owner to the map of owners (or increases its counter if it is already there).
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
+ 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
+ Standard_Boolean myHasEntityWithPersistence; //!< flag if some of sensitive entity has own transform persistence
};
#endif // _SelectMgr_SensitiveEntitySet_HeaderFile
const Handle(Graphic3d_Camera)& theCamera,
const Graphic3d_Mat4d& theProjectionMat,
const Graphic3d_Mat4d& theWorldViewMat,
- const Standard_Integer theViewportWidth,
- const Standard_Integer theViewportHeight)
+ const Graphic3d_Vec2i& theWinSize)
{
Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
if (anEntitySet->Size() == 0)
return;
}
+ const bool hasEntityTrsfPers = anEntitySet->HasEntityWithPersistence()
+ && !theCamera.IsNull();
const opencascade::handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH();
gp_GTrsf aInversedTrsf;
if (theObject->HasTransformation() || !theObject->TransformPersistence().IsNull())
{
return;
}
- gp_GTrsf aTPers;
- Graphic3d_Mat4d aMat = theObject->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)));
+ const Graphic3d_Mat4d aMat = theObject->TransformPersistence()->Compute (theCamera,
+ theProjectionMat, theWorldViewMat,
+ theWinSize.x(), theWinSize.y());
+ gp_GTrsf aTPers;
+ aTPers.SetMat4 (aMat);
aInversedTrsf = (aTPers * gp_GTrsf (theObject->Transformation())).Inverted();
}
}
SelectMgr_SelectingVolumeManager aMgr = aInversedTrsf.Form() != gp_Identity
? theMgr.ScaleAndTransform (1, aInversedTrsf, NULL)
: theMgr;
- if (!aMgr.OverlapsBox (aSensitivesTree->MinPoint (0),
+ if (!hasEntityTrsfPers
+ && !aMgr.OverlapsBox (aSensitivesTree->MinPoint (0),
aSensitivesTree->MaxPoint (0)))
{
return;
{
const Standard_Integer aLeftChildIdx = aSensitivesTree->Child<0> (aNode);
const Standard_Integer aRightChildIdx = aSensitivesTree->Child<1> (aNode);
- const Standard_Boolean isLeftChildIn = aMgr.OverlapsBox (aSensitivesTree->MinPoint (aLeftChildIdx),
- aSensitivesTree->MaxPoint (aLeftChildIdx));
- const Standard_Boolean isRightChildIn = aMgr.OverlapsBox (aSensitivesTree->MinPoint (aRightChildIdx),
+ const Standard_Boolean isLeftChildIn = hasEntityTrsfPers
+ || aMgr.OverlapsBox (aSensitivesTree->MinPoint (aLeftChildIdx),
+ aSensitivesTree->MaxPoint (aLeftChildIdx));
+ const Standard_Boolean isRightChildIn = hasEntityTrsfPers
+ || aMgr.OverlapsBox (aSensitivesTree->MinPoint (aRightChildIdx),
aSensitivesTree->MaxPoint (aRightChildIdx));
if (isLeftChildIn
- && isRightChildIn)
+ && isRightChildIn)
{
aNode = aLeftChildIdx;
++aHead;
}
if (!aClipped)
{
- Standard_Integer aStartIdx = aSensitivesTree->BegPrimitive (aNode);
- Standard_Integer anEndIdx = aSensitivesTree->EndPrimitive (aNode);
+ const Standard_Integer aStartIdx = aSensitivesTree->BegPrimitive (aNode);
+ const Standard_Integer anEndIdx = aSensitivesTree->EndPrimitive (aNode);
for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
{
const Handle(SelectMgr_SensitiveEntity)& aSensitive = anEntitySet->GetSensitiveById (anIdx);
- if (aSensitive->IsActiveForSelection())
+ if (!aSensitive->IsActiveForSelection())
+ {
+ continue;
+ }
+
+ const Handle(Select3D_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
+
+ gp_GTrsf aInvSensTrsf = aInversedTrsf;
+ if (!anEnt->TransformPersistence().IsNull())
{
- const Handle(Select3D_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
- computeFrustum (anEnt, theMgr, aMgr, aInversedTrsf, aScaledTrnsfFrustums, aTmpMgr);
- checkOverlap (anEnt, aInversedTrsf, aTmpMgr);
+ if (theCamera.IsNull())
+ {
+ continue;
+ }
+ const Graphic3d_Mat4d aMat = anEnt->TransformPersistence()->Compute (theCamera,
+ theProjectionMat, theWorldViewMat,
+ theWinSize.x(), theWinSize.y());
+ gp_GTrsf aTPers;
+ aTPers.SetMat4 (aMat);
+ aInvSensTrsf = (aTPers * gp_GTrsf(theObject->Transformation())).Inverted();
}
+
+ computeFrustum (anEnt, theMgr, aMgr, aInvSensTrsf, aScaledTrnsfFrustums, aTmpMgr);
+ checkOverlap (anEnt, aInvSensTrsf, aTmpMgr);
}
}
if (aHead < 0)
mystored.Clear();
- Standard_Integer aWidth = 0;
- Standard_Integer aHeight = 0;
- mySelectingVolumeMgr.WindowSize (aWidth, aHeight);
+ Graphic3d_Vec2i aWinSize;
+ mySelectingVolumeMgr.WindowSize (aWinSize.x(), aWinSize.y());
const Handle(Graphic3d_Camera)& aCamera = mySelectingVolumeMgr.Camera();
Graphic3d_Mat4d aProjectionMat, aWorldViewMat;
myCameraScale = aCamera->IsOrthographic()
? aCamera->Scale()
: 2.0 * Tan (aCamera->FOVy() * M_PI / 360.0);
- const double aPixelSize = Max (1.0 / aWidth, 1.0 / aHeight);
+ const double aPixelSize = Max (1.0 / aWinSize.x(), 1.0 / aWinSize.y());
myCameraScale *= aPixelSize;
}
- mySelectableObjects.UpdateBVH (aCamera, aProjectionMat, aWorldViewMat, aViewState, aWidth, aHeight);
+ mySelectableObjects.UpdateBVH (aCamera, aWinSize);
for (Standard_Integer aBVHSetIt = 0; aBVHSetIt < SelectMgr_SelectableObjectSet::BVHSubsetNb; ++aBVHSetIt)
{
aWorldViewMat = aNewCamera->OrientationMatrix(); // should be identity matrix
aProjectionMat = aNewCamera->ProjectionMatrix(); // should be the same to aProjectionMat
aBuilder->SetCamera (aNewCamera);
- aBuilder->SetWindowSize (aWidth, aHeight);
+ aBuilder->SetWindowSize (aWinSize.x(), aWinSize.y());
aMgr = mySelectingVolumeMgr.ScaleAndTransform (1, aTFrustum, aBuilder);
}
else
const Handle(SelectMgr_SelectableObject)& aSelectableObject =
mySelectableObjects.GetObjectById (aBVHSubset, anIdx);
- traverseObject (aSelectableObject, aMgr, aCamera, aProjectionMat, aWorldViewMat, aWidth, aHeight);
+ traverseObject (aSelectableObject, aMgr, aCamera, aProjectionMat, aWorldViewMat, aWinSize);
}
if (aHead < 0)
{
if (theIsForce)
{
- Standard_Integer aViewportWidth, aViewportHeight;
- mySelectingVolumeMgr.WindowSize (aViewportWidth, aViewportHeight);
-
- Standard_Integer aWidth;
- Standard_Integer aHeight;
- mySelectingVolumeMgr.WindowSize (aWidth, aHeight);
- const Handle(Graphic3d_Camera)& aCamera = mySelectingVolumeMgr.Camera();
- const Graphic3d_Mat4d& aProjMat = !aCamera.IsNull() ? aCamera->ProjectionMatrix()
- : SelectMgr_ViewerSelector_THE_IDENTITY_MAT;
- const Graphic3d_Mat4d& anOrientMat = !aCamera.IsNull() ? aCamera->OrientationMatrix()
- : SelectMgr_ViewerSelector_THE_IDENTITY_MAT;
- Graphic3d_WorldViewProjState aViewState = !aCamera.IsNull() ? aCamera->WorldViewProjState()
- : Graphic3d_WorldViewProjState();
- mySelectableObjects.UpdateBVH (aCamera, aProjMat, anOrientMat, aViewState, aWidth, aHeight);
+ Graphic3d_Vec2i aWinSize;
+ mySelectingVolumeMgr.WindowSize (aWinSize.x(), aWinSize.y());
+ mySelectableObjects.UpdateBVH (mySelectingVolumeMgr.Camera(), aWinSize);
}
}
const Handle(Graphic3d_Camera)& theCamera,
const Graphic3d_Mat4d& theProjectionMat,
const Graphic3d_Mat4d& theWorldViewMat,
- const Standard_Integer theViewportWidth,
- const Standard_Integer theViewportHeight);
+ const Graphic3d_Vec2i& theWinSize);
//! Internal function that checks if a particular sensitive
//! entity theEntity overlaps current selecting volume precisely
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]);
+ Standard_Boolean isZoomableArrow = Standard_True;
+ if (!Draw::ParseOnOff (aValue.ToCString(), isZoomableArrow))
+ {
+ Message::SendFail() << "Error: zoomable arrow value should be 0 or 1.";
+ return 1;
+ }
+ theAspect->ArrowAspect()->SetZoomable (isZoomableArrow);
+ }
else if (aParam.IsEqual ("-arrowlength") || aParam.IsEqual ("-arlen"))
{
TCollection_AsciiString aValue (theArgVec[++anIt]);
"[-font FontName]\n"
"[-label left|right|hcenter|hfit top|bottom|vcenter|vfit]\n"
"[-arrow external|internal|fit]\n"
+ "[-zoomablearrow]\n"
"[{-arrowlength|-arlen} RealArrowLength]\n"
"[{-arrowangle|-arangle} ArrowAngle(degrees)]\n"
"[-plane xoy|yoz|zox]\n"
"[-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"
theMat.SetValue (3, 3, static_cast<T> (1));
}
+ //! Convert transformation from 4x4 matrix.
+ template<class T>
+ void SetMat4 (const NCollection_Mat4<T>& theMat)
+ {
+ shape = gp_Other;
+ scale = 0.0;
+ matrix.SetValue (1, 1, theMat.GetValue (0, 0));
+ matrix.SetValue (1, 2, theMat.GetValue (0, 1));
+ matrix.SetValue (1, 3, theMat.GetValue (0, 2));
+ matrix.SetValue (2, 1, theMat.GetValue (1, 0));
+ matrix.SetValue (2, 2, theMat.GetValue (1, 1));
+ matrix.SetValue (2, 3, theMat.GetValue (1, 2));
+ matrix.SetValue (3, 1, theMat.GetValue (2, 0));
+ matrix.SetValue (3, 2, theMat.GetValue (2, 1));
+ matrix.SetValue (3, 3, theMat.GetValue (2, 2));
+ loc.SetCoord (theMat.GetValue (0, 3), theMat.GetValue (1, 3), theMat.GetValue (2, 3));
+ }
+
//! Dumps the content of me into the stream
Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
--- /dev/null
+puts "============="
+puts "0027919: Visualization - support multiple transformation persistence groups within single presentation"
+puts "============="
+
+pload VISUALIZATION
+
+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}_def.png
+vseldump $imagedir/${casename}_def_selowner.png -type owner
+
+vlocation angle -reset -setlocation 10 0 0 -rotate 0 0 0 1 0 0 40
+vdump $imagedir/${casename}_rot1.png
+vseldump $imagedir/${casename}_rot1_selowner.png -type owner
+
+vzoom 0.25
+vlocation angle -reset -setlocation 30 0 0 -rotate 0 0 0 1 0 0 40
+vdump $imagedir/${casename}_rot2.png
+vseldump $imagedir/${casename}_rot2_selowner.png -type owner