OpenGl_View now caches bounding boxes per Z-layer (instead of bounding box of entire scene in Graphic3d_CView).
Redundant invalidation of cached scene bounding box is now avoided in case
when new presentation attributes are assigned to the graphic structure.
Add a new methods ConsiderZoomPersistenceObjects() and considerZoomPersistenceObjects() in the Graphic3d_CView, OpenGl_View and OpenGl_Layer classes.
Call ConsiderZoomPersistenceObjects() in the V3d_View::FitMinMax method.
std::numeric_limits<T>::lowest() fix
IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_CView,Graphic3d_DataStructureManager)
+namespace
+{
+ static const int THE_DEFAULT_LAYERS[] = { Graphic3d_ZLayerId_Top,
+ Graphic3d_ZLayerId_Topmost,
+ Graphic3d_ZLayerId_BotOSD,
+ Graphic3d_ZLayerId_TopOSD };
+
+ static const int THE_NB_DEFAULT_LAYERS = sizeof(THE_DEFAULT_LAYERS) / sizeof(*THE_DEFAULT_LAYERS);
+
+ void combineBox (Bnd_Box& aCombined, const Graphic3d_BndBox4f& theBox)
+ {
+ if (theBox.IsValid())
+ {
+ aCombined.Add (gp_Pnt (theBox.CornerMin().x(),
+ theBox.CornerMin().y(),
+ theBox.CornerMin().z()));
+ aCombined.Add (gp_Pnt (theBox.CornerMax().x(),
+ theBox.CornerMax().y(),
+ theBox.CornerMax().z()));
+ }
+ }
+}
+
//=======================================================================
//function : Constructor
//purpose :
// function : Update
// purpose :
// =======================================================================
-void Graphic3d_CView::Update (const Aspect_TypeOfUpdate theUpdateMode)
+void Graphic3d_CView::Update (const Aspect_TypeOfUpdate theUpdateMode,
+ const Graphic3d_ZLayerId theLayerId)
{
- myMinMax.Invalidate();
+ InvalidateZLayerBoundingBox (theLayerId);
+
if (theUpdateMode == Aspect_TOU_ASAP)
{
Compute();
// =======================================================================
Bnd_Box Graphic3d_CView::MinMaxValues (const Standard_Boolean theToIgnoreInfiniteFlag) const
{
- if (myMinMax.IsOutdated (theToIgnoreInfiniteFlag))
+ Bnd_Box aResult;
+
+ if (!IsDefined())
+ {
+ return aResult;
+ }
+
+ Handle(Graphic3d_Camera) aCamera = Camera();
+ Standard_Integer aWinWidth = 0;
+ Standard_Integer aWinHeight = 0;
+
+ Window()->Size (aWinWidth, aWinHeight);
+
+ for (Standard_Integer aLayer = 0; aLayer < THE_NB_DEFAULT_LAYERS; ++aLayer)
+ {
+ Graphic3d_BndBox4f aBox = ZLayerBoundingBox (THE_DEFAULT_LAYERS[aLayer],
+ aCamera,
+ aWinWidth,
+ aWinHeight,
+ theToIgnoreInfiniteFlag);
+ combineBox (aResult, aBox);
+ }
+
+ Standard_Integer aMaxZLayer = ZLayerMax();
+ for (Standard_Integer aLayerId = Graphic3d_ZLayerId_Default; aLayerId <= aMaxZLayer; ++aLayerId)
+ {
+ Graphic3d_BndBox4f aBox = ZLayerBoundingBox (aLayerId, aCamera, aWinWidth, aWinHeight, theToIgnoreInfiniteFlag);
+ combineBox (aResult, aBox);
+ }
+
+ return aResult;
+}
+
+// =======================================================================
+// function : ConsiderZoomPersistenceObjects
+// purpose :
+// =======================================================================
+Standard_Real Graphic3d_CView::ConsiderZoomPersistenceObjects()
+{
+ if (!IsDefined())
+ {
+ return 1.0;
+ }
+
+ Handle(Graphic3d_Camera) aCamera = Camera();
+ Standard_Integer aWinWidth = 0;
+ Standard_Integer aWinHeight = 0;
+
+ Window()->Size (aWinWidth, aWinHeight);
+
+ Standard_Real aMaxCoef = 1.0;
+ for (Standard_Integer aLayer = 0; aLayer < THE_NB_DEFAULT_LAYERS; ++aLayer)
+ {
+ aMaxCoef = Max (aMaxCoef, considerZoomPersistenceObjects (THE_DEFAULT_LAYERS[aLayer], aCamera, aWinWidth, aWinHeight, Standard_False));
+ }
+
+ for (Standard_Integer aLayer = Graphic3d_ZLayerId_Default; aLayer <= ZLayerMax(); ++aLayer)
{
- myMinMax.BoundingBox (theToIgnoreInfiniteFlag) = MinMaxValues (myStructsDisplayed, theToIgnoreInfiniteFlag);
- myMinMax.IsOutdated (theToIgnoreInfiniteFlag) = Standard_False;
+ aMaxCoef = Max (aMaxCoef, considerZoomPersistenceObjects (aLayer, aCamera, aWinWidth, aWinHeight, Standard_False));
}
- return myMinMax.BoundingBox (theToIgnoreInfiniteFlag);
+ return aMaxCoef;
}
// =======================================================================
theStructure->CalculateBoundBox();
displayStructure (theStructure->CStructure(), theStructure->DisplayPriority());
- Update (theUpdateMode);
+ Update (theUpdateMode, theStructure->GetZLayer());
return;
}
else if (anAnswer != Graphic3d_TOA_COMPUTE)
}
displayStructure (anOldStruct->CStructure(), theStructure->DisplayPriority());
- Update (theUpdateMode);
+ Update (theUpdateMode, anOldStruct->GetZLayer());
return;
}
else
const Handle(Graphic3d_Structure)& aNewStruct = myStructsComputed.Value (aNewIndex);
myStructsComputed.SetValue (anIndex, aNewStruct);
displayStructure (aNewStruct->CStructure(), theStructure->DisplayPriority());
- Update (theUpdateMode);
+ Update (theUpdateMode, aNewStruct->GetZLayer());
return;
}
else
myStructsDisplayed.Add (theStructure);
displayStructure (aStruct->CStructure(), theStructure->DisplayPriority());
- Update (theUpdateMode);
+ Update (theUpdateMode, aStruct->GetZLayer());
}
// =======================================================================
}
}
myStructsDisplayed.Remove (theStructure);
- Update (theUpdateMode);
+ Update (theUpdateMode, theStructure->GetZLayer());
}
// =======================================================================
//! Computes the new presentation of the structure displayed in this view with the type Graphic3d_TOS_COMPUTED.
Standard_EXPORT void ReCompute (const Handle(Graphic3d_Structure)& theStructure);
- //! Updates screen in function of modifications of the structures.
- Standard_EXPORT void Update (const Aspect_TypeOfUpdate theUpdateMode);
+ //! Updates screen in function of modifications of the structures
+ //! and invalidates bounding box of specified ZLayerId.
+ Standard_EXPORT void Update (const Aspect_TypeOfUpdate theUpdateMode,
+ const Graphic3d_ZLayerId theLayerId = Graphic3d_ZLayerId_UNKNOWN);
//! Returns Standard_True if one of the structures displayed in the view contains Polygons, Triangles or Quadrangles.
Standard_EXPORT Standard_Boolean ContainsFacet() const;
Standard_EXPORT Standard_Boolean IsComputed (const Standard_Integer theStructId,
Handle(Graphic3d_Structure)& theComputedStruct) const;
- //! Returns the coordinates of the boundary box of all
- //! structures displayed in the view.
+ //! Returns the bounding box of all structures displayed in the view.
//! If <theToIgnoreInfiniteFlag> is TRUE, then the boundary box
//! also includes minimum and maximum limits of graphical elements
//! forming parts of infinite structures.
//! ID for the structure.
virtual void AddZLayer (const Graphic3d_ZLayerId theLayerId) = 0;
+ //! Returns the maximum Z layer ID.
+ //! First layer ID is Graphic3d_ZLayerId_Default, last ID is ZLayerMax().
+ virtual Standard_Integer ZLayerMax() const = 0;
+
+ //! Returns the bounding box of all structures displayed in the Z layer.
+ virtual void InvalidateZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId) const = 0;
+
+ //! Returns the bounding box of all structures displayed in the Z layer.
+ virtual Graphic3d_BndBox4f ZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId,
+ const Handle(Graphic3d_Camera)& theCamera,
+ const Standard_Integer theWindowWidth,
+ const Standard_Integer theWindowHeight,
+ const Standard_Boolean theToIgnoreInfiniteFlag) const = 0;
+
//! Remove Z layer from the specified view. All structures
//! displayed at the moment in layer will be displayed in default layer
//! ( the bottom-level z layer ). To unset layer ID from associated
virtual void SetZLayerSettings (const Graphic3d_ZLayerId theLayerId,
const Graphic3d_ZLayerSettings& theSettings) = 0;
+ //! Returns zoom-scale factor.
+ Standard_EXPORT Standard_Real ConsiderZoomPersistenceObjects();
+
//! Returns pointer to an assigned framebuffer object.
virtual Handle(Standard_Transient) FBO() const = 0;
virtual void changePriority (const Handle(Graphic3d_CStructure)& theCStructure,
const Standard_Integer theNewPriority) = 0;
-protected:
-
- struct CachedMinMax
- {
- CachedMinMax() { Invalidate(); }
-
- Bnd_Box& BoundingBox (const Standard_Boolean theToIgnoreInfiniteFlag)
- {
- return !theToIgnoreInfiniteFlag ? myBoundingBox[0] : myBoundingBox[1];
- }
- Standard_Boolean& IsOutdated (const Standard_Boolean theToIgnoreInfiniteFlag)
- {
- return !theToIgnoreInfiniteFlag ? myIsOutdated[0] : myIsOutdated[1];
- }
- void Invalidate()
- {
- myIsOutdated[0] = Standard_True;
- myIsOutdated[1] = Standard_True;
- }
-
- Standard_Boolean myIsOutdated [2];
- Bnd_Box myBoundingBox[2];
- };
+ //! Returns zoom-scale factor.
+ virtual Standard_Real considerZoomPersistenceObjects (const Graphic3d_ZLayerId theLayerId,
+ const Handle(Graphic3d_Camera)& theCamera,
+ const Standard_Integer theWindowWidth,
+ const Standard_Integer theWindowHeight,
+ const Standard_Boolean theToIgnoreInfiniteFlag) const = 0;
protected:
Standard_Boolean myIsActive;
Standard_Boolean myIsRemoved;
Graphic3d_TypeOfVisualization myVisualization;
- mutable CachedMinMax myMinMax;
private:
myCStructure->ContainsFacet = 0;
myStructureManager->Clear (this, theWithDestruction);
- Update();
+ Update (true);
}
//=======================================================================
myCStructure->visible = isVisible;
myCStructure->OnVisibilityChanged();
- Update();
+ Update (true);
}
//=============================================================================
GraphicConnect (theStructure);
myStructureManager->Connect (this, theStructure);
- Update();
+ Update (true);
}
else // Graphic3d_TOC_ANCESTOR
{
myStructureManager->Disconnect (this, theStructure);
CalculateBoundBox();
- Update();
+ Update (true);
}
else if (RemoveAncestor (aStructure))
{
myCStructure->UpdateTransformation();
myStructureManager->SetTransform (this, aNewTrsf);
- Update();
+ Update (true);
}
//=============================================================================
//function : Update
//purpose :
//=============================================================================
-void Graphic3d_Structure::Update() const
+void Graphic3d_Structure::Update (const bool theUpdateLayer) const
{
if (IsDeleted())
{
return;
}
- myStructureManager->Update (myStructureManager->UpdateMode());
+ myStructureManager->Update (myStructureManager->UpdateMode(),
+ theUpdateLayer ? myCStructure->ZLayer() : Graphic3d_ZLayerId_UNKNOWN);
}
//=============================================================================
//! Returns the manager to which <me> is associated.
Standard_EXPORT Handle(Graphic3d_StructureManager) StructureManager() const;
- //! Calls the Update method of the StructureManager which
- //! contains the Structure <me>.
- Standard_EXPORT void Update() const;
+ //! Calls the Update method of the StructureManager which contains the Structure <me>.
+ //! If theUpdateLayer is true then invalidates bounding box of ZLayer.
+ Standard_EXPORT void Update (const bool theUpdateLayer = false) const;
//! Updates the c structure associated to <me>.
Standard_EXPORT void UpdateStructure (const Handle(Graphic3d_AspectLine3d)& CTXL, const Handle(Graphic3d_AspectText3d)& CTXT, const Handle(Graphic3d_AspectMarker3d)& CTXM, const Handle(Graphic3d_AspectFillArea3d)& CTXF);
// function : Update
// purpose :
// ========================================================================
-void Graphic3d_StructureManager::Update (const Aspect_TypeOfUpdate theMode) const
+void Graphic3d_StructureManager::Update (const Aspect_TypeOfUpdate theMode,
+ const Graphic3d_ZLayerId theLayerId) const
{
for (Graphic3d_IndexedMapOfView::Iterator aViewIt (myDefinedViews); aViewIt.More(); aViewIt.Next())
{
- aViewIt.Value()->Update (theMode);
+ aViewIt.Value()->Update (theMode, theLayerId);
}
}
//! TOU_WAIT on demand (Update)
Standard_EXPORT Aspect_TypeOfUpdate UpdateMode() const;
- //! Updates screen in function of modifications of the structures.
- Standard_EXPORT virtual void Update (const Aspect_TypeOfUpdate theMode = Aspect_TOU_ASAP) const;
+ //! Updates screen in function of modifications of the structures
+ //! and invalidates bounding box of specified ZLayerId.
+ Standard_EXPORT virtual void Update (const Aspect_TypeOfUpdate theMode = Aspect_TOU_ASAP,
+ const Graphic3d_ZLayerId theLayerId = Graphic3d_ZLayerId_UNKNOWN) const;
//! Deletes and erases the 3D structure manager.
Standard_EXPORT virtual void Remove();
// purpose :
// =======================================================================
OpenGl_Layer::OpenGl_Layer (const Standard_Integer theNbPriorities)
-: myArray (0, theNbPriorities - 1),
- myNbStructures (0),
+: myArray (0, theNbPriorities - 1),
+ myNbStructures (0),
myBVHIsLeftChildQueuedFirst (Standard_True),
myIsBVHPrimitivesNeedsReset (Standard_False)
{
- //
+ myIsBoundingBoxNeedsReset[0] = myIsBoundingBoxNeedsReset[1] = true;
}
// =======================================================================
// function : InvalidateBVHData
// purpose :
// =======================================================================
-void OpenGl_Layer::InvalidateBVHData()
+void OpenGl_Layer::InvalidateBVHData() const
{
myIsBVHPrimitivesNeedsReset = Standard_True;
}
+// =======================================================================
+// function : BoundingBox
+// purpose :
+// =======================================================================
+const Graphic3d_BndBox4f& OpenGl_Layer::BoundingBox (const Standard_Integer theViewId,
+ const Handle(Graphic3d_Camera)& theCamera,
+ const Standard_Integer theWindowWidth,
+ const Standard_Integer theWindowHeight,
+ const Standard_Boolean theToIgnoreInfiniteFlag) const
+{
+ const Standard_Integer aBoxId = theToIgnoreInfiniteFlag == 0 ? 0 : 1;
+
+ if (myIsBoundingBoxNeedsReset[aBoxId])
+ {
+ // Recompute layer bounding box
+ myBoundingBox[aBoxId].Clear();
+
+ const Standard_Integer aNbPriorities = myArray.Length();
+ for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
+ {
+ const OpenGl_IndexedMapOfStructure& aStructures = myArray (aPriorityIter);
+ for (Standard_Integer aStructIdx = 1; aStructIdx <= aStructures.Size(); ++aStructIdx)
+ {
+ const OpenGl_Structure* aStructure = aStructures.FindKey (aStructIdx);
+ if (!aStructure->IsVisible())
+ {
+ continue;
+ }
+ else if (!aStructure->ViewAffinity.IsNull()
+ && !aStructure->ViewAffinity->IsVisible (theViewId))
+ {
+ continue;
+ }
+
+ // "FitAll" operation ignores object with transform persistence parameter
+ // but adds transform persistence point in a bounding box of layer (only zoom pers. objects).
+ if (aStructure->TransformPersistence.Flags != Graphic3d_TMF_None)
+ {
+ if (!theToIgnoreInfiniteFlag && (aStructure->TransformPersistence.Flags & Graphic3d_TMF_ZoomPers))
+ {
+ if (!theCamera->IsOrthographic())
+ {
+ continue;
+ }
+
+ BVH_Vec4f aTPPoint (static_cast<float> (aStructure->TransformPersistence.Point.x()),
+ static_cast<float> (aStructure->TransformPersistence.Point.y()),
+ static_cast<float> (aStructure->TransformPersistence.Point.z()),
+ 1.0f);
+
+ myBoundingBox[aBoxId].Combine (aTPPoint);
+ continue;
+ }
+ // Panning and 2d persistence apply changes to projection or/and its translation components.
+ // It makes them incompatible with z-fitting algorithm. Ignored by now.
+ else if (!theToIgnoreInfiniteFlag
+ || (aStructure->TransformPersistence.Flags & Graphic3d_TMF_2d)
+ || (aStructure->TransformPersistence.Flags & Graphic3d_TMF_PanPers)
+ || (aStructure->TransformPersistence.Flags & Graphic3d_TMF_TriedronPers))
+ {
+ continue;
+ }
+ }
+
+ Graphic3d_BndBox4f aBox = aStructure->BoundingBox();
+
+ if (aStructure->IsInfinite
+ && !theToIgnoreInfiniteFlag)
+ {
+ const Graphic3d_Vec4 aDiagVec = aBox.CornerMax() - aBox.CornerMin();
+ if (aDiagVec.xyz().SquareModulus() >= 500000.0f * 500000.0f)
+ {
+ // bounding borders of infinite line has been calculated as own point in center of this line
+ aBox = Graphic3d_BndBox4f ((aBox.CornerMin() + aBox.CornerMax()) * 0.5f);
+ }
+ else
+ {
+ aBox = Graphic3d_BndBox4f (Graphic3d_Vec4 (ShortRealFirst(), ShortRealFirst(), ShortRealFirst(), 1.0f),
+ Graphic3d_Vec4 (ShortRealLast(), ShortRealLast(), ShortRealLast(), 1.0f));
+ }
+ }
+
+ if (aStructure->TransformPersistence.Flags != Graphic3d_TMF_None)
+ {
+ const Graphic3d_Mat4& aProjectionMat = theCamera->ProjectionMatrixF();
+ const Graphic3d_Mat4& aWorldViewMat = theCamera->OrientationMatrixF();
+
+ aStructure->TransformPersistence.Apply (aProjectionMat,
+ aWorldViewMat,
+ theWindowWidth,
+ theWindowHeight,
+ aBox);
+ }
+
+ // To prevent float overflow at camera parameters calculation and further
+ // rendering, bounding boxes with at least one vertex coordinate out of
+ // float range are skipped by view fit algorithms
+ if (Abs (aBox.CornerMax().x()) >= ShortRealLast()
+ || Abs (aBox.CornerMax().y()) >= ShortRealLast()
+ || Abs (aBox.CornerMax().z()) >= ShortRealLast()
+ || Abs (aBox.CornerMin().x()) >= ShortRealLast()
+ || Abs (aBox.CornerMin().y()) >= ShortRealLast()
+ || Abs (aBox.CornerMin().z()) >= ShortRealLast())
+ {
+ continue;
+ }
+
+ myBoundingBox[aBoxId].Combine (aBox);
+ }
+ }
+
+ myIsBoundingBoxNeedsReset[aBoxId] = false;
+ }
+
+ return myBoundingBox[aBoxId];
+}
+
+// =======================================================================
+// function : considerZoomPersistenceObjects
+// purpose :
+// =======================================================================
+Standard_Real OpenGl_Layer::considerZoomPersistenceObjects (const Standard_Integer theViewId,
+ const Handle(Graphic3d_Camera)& theCamera,
+ Standard_Integer theWindowWidth,
+ Standard_Integer theWindowHeight,
+ Standard_Boolean /*theToIgnoreInfiniteFlag*/) const
+{
+ if (NbOfTransformPersistenceObjects() == 0)
+ {
+ return 1.0;
+ }
+
+ const Standard_Integer aNbPriorities = myArray.Length();
+ const Graphic3d_Mat4& aProjectionMat = theCamera->ProjectionMatrixF();
+ const Graphic3d_Mat4& aWorldViewMat = theCamera->OrientationMatrixF();
+ Standard_Real aMaxCoef = -std::numeric_limits<double>::max();
+
+ for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
+ {
+ const OpenGl_IndexedMapOfStructure& aStructures = myArray (aPriorityIter);
+ for (Standard_Integer aStructIdx = 1; aStructIdx <= aStructures.Size(); ++aStructIdx)
+ {
+ OpenGl_Structure* aStructure = const_cast<OpenGl_Structure*> (aStructures.FindKey (aStructIdx));
+ if (!aStructure->IsVisible())
+ {
+ continue;
+ }
+ else if (!aStructure->ViewAffinity.IsNull()
+ && !aStructure->ViewAffinity->IsVisible (theViewId))
+ {
+ continue;
+ }
+
+ if (!(aStructure->TransformPersistence.Flags & Graphic3d_TMF_ZoomPers))
+ {
+ continue;
+ }
+
+ Graphic3d_BndBox4f aBox = aStructure->BoundingBox();
+ aStructure->TransformPersistence.Apply (aProjectionMat, aWorldViewMat, theWindowWidth, theWindowHeight, aBox);
+
+ const BVH_Vec4f& aCornerMin = aBox.CornerMin();
+ const BVH_Vec4f& aCornerMax = aBox.CornerMax();
+ const Standard_Integer aNbOfPoints = 8;
+ const gp_Pnt aPoints[aNbOfPoints] = { gp_Pnt (aCornerMin.x(), aCornerMin.y(), aCornerMin.z()),
+ gp_Pnt (aCornerMin.x(), aCornerMin.y(), aCornerMax.z()),
+ gp_Pnt (aCornerMin.x(), aCornerMax.y(), aCornerMin.z()),
+ gp_Pnt (aCornerMin.x(), aCornerMax.y(), aCornerMax.z()),
+ gp_Pnt (aCornerMax.x(), aCornerMin.y(), aCornerMin.z()),
+ gp_Pnt (aCornerMax.x(), aCornerMin.y(), aCornerMax.z()),
+ gp_Pnt (aCornerMax.x(), aCornerMax.y(), aCornerMin.z()),
+ gp_Pnt (aCornerMax.x(), aCornerMax.y(), aCornerMax.z()) };
+ gp_Pnt aConvertedPoints[aNbOfPoints];
+ Standard_Real aConvertedMinX = std::numeric_limits<double>::max();
+ Standard_Real aConvertedMaxX = -std::numeric_limits<double>::max();
+ Standard_Real aConvertedMinY = std::numeric_limits<double>::max();
+ Standard_Real aConvertedMaxY = -std::numeric_limits<double>::max();
+ for (Standard_Integer anIdx = 0; anIdx < aNbOfPoints; ++anIdx)
+ {
+ aConvertedPoints[anIdx] = theCamera->Project (aPoints[anIdx]);
+
+ aConvertedMinX = Min (aConvertedMinX, aConvertedPoints[anIdx].X());
+ aConvertedMaxX = Max (aConvertedMaxX, aConvertedPoints[anIdx].X());
+
+ aConvertedMinY = Min (aConvertedMinY, aConvertedPoints[anIdx].Y());
+ aConvertedMaxY = Max (aConvertedMaxY, aConvertedPoints[anIdx].Y());
+ }
+
+ const Standard_Boolean isBigObject = (Abs (aConvertedMaxX - aConvertedMinX) > 2.0) // width of zoom pers. object greater than width of window
+ || (Abs (aConvertedMaxY - aConvertedMinY) > 2.0); // height of zoom pers. object greater than height of window
+ const Standard_Boolean isAlreadyInScreen = (aConvertedMinX > -1.0 && aConvertedMinX < 1.0)
+ && (aConvertedMaxX > -1.0 && aConvertedMaxX < 1.0)
+ && (aConvertedMinY > -1.0 && aConvertedMinY < 1.0)
+ && (aConvertedMaxY > -1.0 && aConvertedMaxY < 1.0);
+ if (isBigObject || isAlreadyInScreen)
+ {
+ continue;
+ }
+
+ const gp_Pnt aTPPoint (aStructure->TransformPersistence.Point.x(),
+ aStructure->TransformPersistence.Point.y(),
+ aStructure->TransformPersistence.Point.z());
+ gp_Pnt aConvertedTPPoint = theCamera->Project (aTPPoint);
+ aConvertedTPPoint.SetZ (0.0);
+
+ if (aConvertedTPPoint.Coord().Modulus() < Precision::Confusion())
+ {
+ continue;
+ }
+
+ Standard_Real aShiftX = 0.0;
+ if (aConvertedMinX < -1.0)
+ {
+ aShiftX = ((aConvertedMaxX < -1.0) ? (-(1.0 + aConvertedMaxX) + (aConvertedMaxX - aConvertedMinX)) : -(1.0 + aConvertedMinX));
+ }
+ else if (aConvertedMaxX > 1.0)
+ {
+ aShiftX = ((aConvertedMinX > 1.0) ? ((aConvertedMinX - 1.0) + (aConvertedMaxX - aConvertedMinX)) : (aConvertedMaxX - 1.0));
+ }
+
+ Standard_Real aShiftY = 0.0;
+ if (aConvertedMinY < -1.0)
+ {
+ aShiftY = ((aConvertedMaxY < -1.0) ? (-(1.0 + aConvertedMaxY) + (aConvertedMaxY - aConvertedMinY)) : -(1.0 + aConvertedMinY));
+ }
+ else if (aConvertedMaxY > 1.0)
+ {
+ aShiftY = ((aConvertedMinY > 1.0) ? ((aConvertedMinY - 1.0) + (aConvertedMaxY - aConvertedMinY)) : (aConvertedMaxY - 1.0));
+ }
+
+ const Standard_Real aDifX = Abs (aConvertedTPPoint.X()) - aShiftX;
+ const Standard_Real aDifY = Abs (aConvertedTPPoint.Y()) - aShiftY;
+ if (aDifX > Precision::Confusion())
+ {
+ aMaxCoef = Max (aMaxCoef, Abs (aConvertedTPPoint.X()) / aDifX);
+ }
+ if (aDifY > Precision::Confusion())
+ {
+ aMaxCoef = Max (aMaxCoef, Abs (aConvertedTPPoint.Y()) / aDifY);
+ }
+ }
+ }
+
+ return (aMaxCoef > 0.0) ? aMaxCoef : 1.0;
+}
+
// =======================================================================
// function : renderAll
// purpose :
//! Marks BVH tree for given priority list as dirty and
//! marks primitive set for rebuild.
- void InvalidateBVHData();
+ void InvalidateBVHData() const;
+
+ //! Marks cached bounding box as obsolete.
+ void InvalidateBoundingBox() const
+ {
+ myIsBoundingBoxNeedsReset[0] = myIsBoundingBoxNeedsReset[1] = true;
+ }
+
+ //! Returns layer bounding box.
+ const Graphic3d_BndBox4f& BoundingBox (const Standard_Integer theViewId,
+ const Handle(Graphic3d_Camera)& theCamera,
+ const Standard_Integer theWindowWidth,
+ const Standard_Integer theWindowHeight,
+ const Standard_Boolean theToIgnoreInfiniteFlag) const;
+
+ //! Returns zoom-scale factor.
+ Standard_Real considerZoomPersistenceObjects (const Standard_Integer theViewId,
+ const Handle(Graphic3d_Camera)& theCamera,
+ const Standard_Integer theWindowWidth,
+ const Standard_Integer theWindowHeight,
+ const Standard_Boolean theToIgnoreInfiniteFlag) const;
// Render all structures.
void Render (const Handle(OpenGl_Workspace)& theWorkspace,
const OpenGl_GlobalLayerSettings& theDefaultSettings) const;
+ //! Returns number of transform persistence objects.
+ Standard_Integer NbOfTransformPersistenceObjects() const
+ {
+ return myBVHPrimitivesTrsfPers.Size();
+ }
+
protected:
//! Traverses through BVH tree to determine which structures are in view volume.
//! Defines if the primitive set for BVH is outdated.
mutable Standard_Boolean myIsBVHPrimitivesNeedsReset;
+ //! Defines if the cached bounding box is outdated.
+ mutable bool myIsBoundingBoxNeedsReset[2];
+
+ //! Cached layer bounding box.
+ mutable Graphic3d_BndBox4f myBoundingBox[2];
+
public:
DEFINE_STANDARD_ALLOC
//! Returns the set of OpenGL Z-layers.
const OpenGl_SequenceOfLayers& Layers() const { return myLayers; }
+ //! Returns the map of Z-layer IDs to indexes.
+ const OpenGl_LayerSeqIds& LayerIDs() const { return myLayerIds; }
+
//! Marks BVH tree for given priority list as dirty and
//! marks primitive set for rebuild.
void InvalidateBVHData (const Graphic3d_ZLayerId theLayerId);
myZLayers.SetLayerSettings (theLayerId, theSettings);
}
+//=======================================================================
+//function : ZLayerMax
+//purpose :
+//=======================================================================
+Standard_Integer OpenGl_View::ZLayerMax() const
+{
+ Standard_Integer aLayerMax = Graphic3d_ZLayerId_Default;
+ for (OpenGl_LayerSeqIds::Iterator aMapIt(myZLayers.LayerIDs()); aMapIt.More(); aMapIt.Next())
+ {
+ aLayerMax = Max (aLayerMax, aMapIt.Value());
+ }
+
+ return aLayerMax;
+}
+
+//=======================================================================
+//function : InvalidateZLayerBoundingBox
+//purpose :
+//=======================================================================
+void OpenGl_View::InvalidateZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId) const
+{
+ if (myZLayers.LayerIDs().IsBound (theLayerId))
+ {
+ myZLayers.Layer (theLayerId).InvalidateBoundingBox();
+ }
+ else
+ {
+ for (Standard_Integer aLayerId = Graphic3d_ZLayerId_Default; aLayerId < ZLayerMax(); ++aLayerId)
+ {
+ if (myZLayers.LayerIDs().IsBound (aLayerId))
+ {
+ const OpenGl_Layer& aLayer = myZLayers.Layer (aLayerId);
+ if (aLayer.NbOfTransformPersistenceObjects() > 0)
+ {
+ aLayer.InvalidateBoundingBox();
+ }
+ }
+ }
+ }
+}
+
+//=======================================================================
+//function : ZLayerBoundingBox
+//purpose :
+//=======================================================================
+Graphic3d_BndBox4f OpenGl_View::ZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId,
+ const Handle(Graphic3d_Camera)& theCamera,
+ const Standard_Integer theWindowWidth,
+ const Standard_Integer theWindowHeight,
+ const Standard_Boolean theToIgnoreInfiniteFlag) const
+{
+ if (myZLayers.LayerIDs().IsBound (theLayerId))
+ {
+ return myZLayers.Layer (theLayerId).BoundingBox (Identification(),
+ theCamera,
+ theWindowWidth,
+ theWindowHeight,
+ theToIgnoreInfiniteFlag);
+ }
+
+ return Graphic3d_BndBox4f();
+}
+
+//=======================================================================
+//function : considerZoomPersistenceObjects
+//purpose :
+//=======================================================================
+Standard_Real OpenGl_View::considerZoomPersistenceObjects (const Graphic3d_ZLayerId theLayerId,
+ const Handle(Graphic3d_Camera)& theCamera,
+ const Standard_Integer theWindowWidth,
+ const Standard_Integer theWindowHeight,
+ const Standard_Boolean theToIgnoreInfiniteFlag) const
+{
+ if (myZLayers.LayerIDs().IsBound (theLayerId) && theCamera->IsOrthographic())
+ {
+ return myZLayers.Layer (theLayerId).considerZoomPersistenceObjects (Identification(),
+ theCamera,
+ theWindowWidth,
+ theWindowHeight,
+ theToIgnoreInfiniteFlag);
+ }
+
+ return 1.0;
+}
+
//=======================================================================
//function : FBO
//purpose :
const Graphic3d_ZLayerId anOldLayer = theStructure->ZLayer();
const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
myZLayers.ChangeLayer (aStruct, anOldLayer, theNewLayerId);
+ Update (Aspect_TOU_WAIT, anOldLayer);
+ Update (Aspect_TOU_WAIT, theNewLayerId);
}
//=======================================================================
Standard_EXPORT virtual void SetZLayerSettings (const Graphic3d_ZLayerId theLayerId,
const Graphic3d_ZLayerSettings& theSettings) Standard_OVERRIDE;
+ //! Returns the maximum Z layer ID.
+ //! First layer ID is Graphic3d_ZLayerId_Default, last ID is ZLayerMax().
+ Standard_EXPORT virtual Standard_Integer ZLayerMax() const Standard_OVERRIDE;
+
+ //! Returns the bounding box of all structures displayed in the Z layer.
+ //! Never fails. If Z layer does not exist nothing happens.
+ Standard_EXPORT virtual void InvalidateZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId) const Standard_OVERRIDE;
+
+ //! Returns the bounding box of all structures displayed in the Z layer.
+ //! Never fails. If Z layer does not exist the empty box is returned.
+ Standard_EXPORT virtual Graphic3d_BndBox4f ZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId,
+ const Handle(Graphic3d_Camera)& theCamera,
+ const Standard_Integer theWindowWidth,
+ const Standard_Integer theWindowHeight,
+ const Standard_Boolean theToIgnoreInfiniteFlag) const Standard_OVERRIDE;
+
//! Returns pointer to an assigned framebuffer object.
Standard_EXPORT virtual Handle(Standard_Transient) FBO() const Standard_OVERRIDE;
Standard_EXPORT virtual void changePriority (const Handle(Graphic3d_CStructure)& theCStructure,
const Standard_Integer theNewPriority) Standard_OVERRIDE;
+ //! Returns zoom-scale factor.
+ Standard_EXPORT virtual Standard_Real considerZoomPersistenceObjects (const Graphic3d_ZLayerId theLayerId,
+ const Handle(Graphic3d_Camera)& theCamera,
+ const Standard_Integer theWindowWidth,
+ const Standard_Integer theWindowHeight,
+ const Standard_Boolean theToIgnoreInfiniteFlag) const Standard_OVERRIDE;
+
private:
//! Copy content of Back buffer to the Front buffer.
aViewSizeYv = aViewSizeZv;
}
- Scale (theCamera, aViewSizeXv * (1.0 + theMargin), aViewSizeYv * (1.0 + theMargin));
+ Scale (theCamera, aViewSizeXv, aViewSizeYv);
+
+ const Standard_Real aZoomCoef = myView->ConsiderZoomPersistenceObjects();
+
+ Scale (theCamera, theCamera->ViewDimensions().X() * (aZoomCoef + theMargin), theCamera->ViewDimensions().Y() * (aZoomCoef + theMargin));
return Standard_True;
}
--- /dev/null
+puts "========"
+puts "OCC27374"
+puts "========"
+puts ""
+################################################################################
+puts "Visualization - add support zoom persistence objects for FitAll operation"
+################################################################################
+
+vinit
+vclear
+
+box b0 30 0 0 3 3 3
+box b1 -30 -30 30 10 20 30
+box b2 30 0 30 100 100 100
+vdisplay b0
+vdisplay b1 -trsfPers zoom -perspos 10 0 0
+vdisplay b2 -trsfPers zoom -perspos 40 0 30
+vfit
+
+vdump $imagedir/${casename}.png