Implement SAT intersection tests and frustum culling algorithm using BVH trees.
New Draw command vfrustumculling to manage frustum culling.
Add test cases bugs/vis/bug24307_1 and bugs/vis/bug24307_2.
Remove CALL_DEF_BOUNDBOX and CALL_DEF_BOUNDS.
template<class T, int N>
class BVH_PrimitiveSet : public BVH_Object<T, N>, public BVH_Set<T, N>
{
+protected:
+
using BVH_Set<T, N>::Box;
public:
+Graphic3d_BndBox4d.hxx
+Graphic3d_BndBox4f.hxx
Graphic3d_Buffer.hxx
Graphic3d_Buffer_Handle.hxx
Graphic3d_BoundBuffer.hxx
Graphic3d_CTexture.hxx
Graphic3d_CLight.hxx
Graphic3d_CPick.hxx
-Graphic3d_CBounds.hxx
Graphic3d_CUserDraw.hxx
Graphic3d_CView.hxx
Graphic3d_CGraduatedTrihedron.hxx
-- Category: Imported types
---------------------------
+ imported BndBox4f;
+ ---Purpose: Redefines BVH_Box<Standard_ShortReal, 4> for AABB representation
+ ---Category: Imported types
imported Buffer;
imported Buffer_Handle;
imported BoundBuffer;
imported IndexBuffer;
imported IndexBuffer_Handle;
+ imported BndBox4d;
imported BufferType;
imported CBitFields20;
imported CPlane;
---Category: Imported types
- imported CBounds;
- ---Category: Imported types
-
imported CUserDraw;
---Category: Imported types
--- /dev/null
+// Created on: 2014-04-09
+// Created by: Varvara POSKONINA
+// Copyright (c) 2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Graphic3d_BndBox4d_HeaderFile
+#define _Graphic3d_BndBox4d_HeaderFile
+
+#include <BVH_Box.hxx>
+
+typedef BVH_Box<Standard_Real, 4> Graphic3d_BndBox4d;
+
+#endif // _Graphic3d_BndBox4d_HeaderFile
--- /dev/null
+// Created on: 2014-04-09
+// Created by: Varvara POSKONINA
+// Copyright (c) 2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Graphic3d_BndBox4f_HeaderFile
+#define _Graphic3d_BndBox4f_HeaderFile
+
+#include <BVH_Box.hxx>
+
+typedef BVH_Box<Standard_ShortReal, 4> Graphic3d_BndBox4f;
+
+#endif // _Graphic3d_BndBox4f_HeaderFile
+++ /dev/null
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-/*============================================================================*/
-/*==== Titre: Graphic3d_CBounds.hxx */
-/*==== Role : The header file of primitive type "CBounds" from Graphic3d */
-/*==== */
-/*==== Implementation: This is a primitive type implemented with typedef */
-/*============================================================================*/
-
-#ifndef _Graphic3d_CBounds_HeaderFile
-#define _Graphic3d_CBounds_HeaderFile
-
-#include <InterfaceGraphic_Graphic3d.hxx>
-typedef CALL_DEF_BOUNDS Graphic3d_CBounds;
-
-#endif /*Graphic3d_CBounds_HeaderFile*/
visible (1),
pick (1),
HLRValidation (0),
+ IsForHighlight (Standard_False),
+ IsMutable (Standard_False),
+ Is2dText (Standard_False),
myGraphicDriver (theManager->GraphicDriver())
{
for (Standard_Integer i = 0; i <= 3; ++i)
#ifndef _Graphic3d_CStructure_HeaderFile
#define _Graphic3d_CStructure_HeaderFile
+#include <Graphic3d_BndBox4f.hxx>
#include <Graphic3d_CStructure_Handle.hxx>
#include <Graphic3d_Group.hxx>
#include <Graphic3d_SequenceOfGroup.hxx>
//! Pass clip planes to the associated graphic driver structure
void SetClipPlanes (const Graphic3d_SequenceOfHClipPlane& thePlanes) { myClipPlanes = thePlanes; }
+ //! @return bounding box of this presentation
+ const Graphic3d_BndBox4f& BoundingBox() const
+ {
+ return myBndBox;
+ }
+
+ //! @return bounding box of this presentation
+ //! without transformation matrix applied
+ Graphic3d_BndBox4f& ChangeBoundingBox()
+ {
+ return myBndBox;
+ }
+
public:
//! Update structure visibility state
CALL_DEF_CONTEXTMARKER ContextMarker;
CALL_DEF_CONTEXTTEXT ContextText;
- CALL_DEF_BOUNDBOX BoundBox;
+ CALL_DEF_COLOR HighlightColor;
float Transformation[4][4];
Graphic3d_TypeOfComposition Composition;
int ContainsFacet;
- unsigned IsInfinite : 1;
- unsigned stick : 1;
- unsigned highlight : 1;
- unsigned visible : 1;
- unsigned pick : 1;
- unsigned HLRValidation : 1;
+ unsigned IsInfinite : 1;
+ unsigned stick : 1;
+ unsigned highlight : 1;
+ unsigned visible : 1;
+ unsigned pick : 1;
+ unsigned HLRValidation : 1;
+ unsigned IsForHighlight : 1;
+ unsigned IsMutable : 1;
+ unsigned Is2dText : 1;
CALL_DEF_TRANSFORM_PERSISTENCE TransformPersistence;
Handle(Graphic3d_GraphicDriver) myGraphicDriver;
Graphic3d_SequenceOfGroup myGroups;
+ Graphic3d_BndBox4f myBndBox;
Graphic3d_SequenceOfHClipPlane myClipPlanes;
public:
ptrUnderLayer (NULL),
ptrOverLayer (NULL),
Backfacing (0),
- GContext (NULL),
+ GContext (NULL),
GDisplayCB (NULL),
GClientData (NULL),
ptrFBO (NULL),
- WasRedrawnGL (0)
+ WasRedrawnGL (0),
+ IsCullingEnabled (Standard_True)
{
- memset(&DefWindow,0,sizeof(DefWindow));
+ memset (&DefWindow, 0, sizeof(DefWindow));
}
public:
//! Specifies rendering parameters and effects.
Graphic3d_RenderingParams RenderParams;
+ //! Enables/disables frustum culling.
+ Standard_Boolean IsCullingEnabled;
+
};
#endif // Graphic3d_CView_HeaderFile
-- In contrast to Bitmaps, Vector graphics is scalable (so you may got quality benefits on printing to laser printer).
-- Notice however that results may differ a lot and do not contain some elements.
+ InvalidateBVHData( me : mutable;
+ theCView : out CView from Graphic3d;
+ theLayerId : Integer from Standard )
+ is deferred;
+ ---Purpose:
+ -- Marks BVH tree and the set of BVH primitives of correspondent priority list with id theLayerId as outdated.
+
AddZLayer( me : mutable;
theCView : CView from Graphic3d;
theLayerId : Integer from Standard )
is deferred;
---Purpose: Sets the settings for a single Z layer of specified view.
+ ChangePriority( me : mutable;
+ theCStructure : CStructure from Graphic3d;
+ theCView : CView from Graphic3d;
+ theNewPriority : Integer from Standard )
+ is deferred;
+ ---Purpose: Changes the priority of a structure within its Z layer
+ -- in the specified view.
+
-----------------------------
-- Category: Internal methods
-----------------------------
Buffer_Handle from Graphic3d,
BoundBuffer_Handle from Graphic3d,
TransModeFlags from Graphic3d,
- CBounds from Graphic3d,
+ BndBox4f from Graphic3d,
Ax2 from gp
raises
-- XMin = YMin = ZMin = RealFirst ().
-- XMax = YMax = ZMax = RealLast ().
---Category: Inquire methods
+
+ BoundingBox ( me )
+ returns BndBox4f from Graphic3d
+ is static;
+ ---Level: Public
+ ---Purpose: Returns boundary box of the group <me> without transformation applied,
+ ---if it is specified for the structure.
+ ---C++: return const &
+
+ ChangeBoundingBox ( me : mutable )
+ returns BndBox4f from Graphic3d
+ is static;
+ ---Level: Public
+ ---Purpose: Returns non-const boundary box of the group <me> without transformation applied,
+ ---if it is specified for the structure.
+ ---C++: return &
Structure ( me )
returns Structure from Graphic3d
myStructure : StructurePtr from Graphic3d is protected;
-- the min-max
- myBounds : CBounds from Graphic3d is protected;
+ myBounds : BndBox4f from Graphic3d is protected;
-- Identifies group forming closed volume. Used to filter groups for back face culling and capping algorithms.
myIsClosed : Boolean from Standard is protected;
Graphic3d_Group::Graphic3d_Group (const Handle(Graphic3d_Structure)& theStruct)
: myIsClosed (Standard_False)
{
- myBounds.XMin = ShortRealLast();
- myBounds.YMin = ShortRealLast();
- myBounds.ZMin = ShortRealLast();
- myBounds.XMax = ShortRealFirst();
- myBounds.YMax = ShortRealFirst();
- myBounds.ZMax = ShortRealFirst();
-
- //
// A small commentary on the usage of This!
//
// Graphic3d_Group is created in a structure. Graphic3d_Structure is a
ContextMarker.IsDef = 0,
ContextFillArea.IsDef = 0;
- myBounds.XMin = ShortRealLast();
- myBounds.YMin = ShortRealLast();
- myBounds.ZMin = ShortRealLast();
- myBounds.XMax = ShortRealFirst();
- myBounds.YMax = ShortRealFirst();
- myBounds.ZMax = ShortRealFirst();
+ myBounds.Clear();
if (MyContainsFacet)
{
Update();
- myBounds.XMin = ShortRealLast();
- myBounds.YMin = ShortRealLast();
- myBounds.ZMin = ShortRealLast();
- myBounds.XMax = ShortRealFirst();
- myBounds.YMax = ShortRealFirst();
- myBounds.ZMax = ShortRealFirst();
+ myBounds.Clear();
MyIsEmpty = Standard_True;
}
return Standard_True;
}
- const Standard_ShortReal RL = ShortRealLast();
- const Standard_ShortReal RF = ShortRealFirst();
- const Standard_Boolean isEmpty = ((myBounds.XMin == RL) && (myBounds.YMin == RL)
- && (myBounds.ZMin == RL) && (myBounds.XMax == RF)
- && (myBounds.YMax == RF) && (myBounds.ZMax == RF));
+ const Standard_Boolean isEmpty = myStructure->IsInfinite() ? Standard_False : !myBounds.IsValid();
if (isEmpty != MyIsEmpty)
{
::Message::DefaultMessenger()->Send ("Graphic3d_Group: MyIsEmpty != IsEmpty()", Message_Trace);
void Graphic3d_Group::SetMinMaxValues (const Standard_Real theXMin, const Standard_Real theYMin, const Standard_Real theZMin,
const Standard_Real theXMax, const Standard_Real theYMax, const Standard_Real theZMax)
{
- myBounds.XMin = Standard_ShortReal (theXMin);
- myBounds.YMin = Standard_ShortReal (theYMin);
- myBounds.ZMin = Standard_ShortReal (theZMin);
- myBounds.XMax = Standard_ShortReal (theXMax);
- myBounds.YMax = Standard_ShortReal (theYMax);
- myBounds.ZMax = Standard_ShortReal (theZMax);
+ myBounds.CornerMin() = Graphic3d_Vec4 (static_cast<Standard_ShortReal> (theXMin),
+ static_cast<Standard_ShortReal> (theYMin),
+ static_cast<Standard_ShortReal> (theZMin),
+ 1.0f);
+ myBounds.CornerMax() = Graphic3d_Vec4 (static_cast<Standard_ShortReal> (theXMax),
+ static_cast<Standard_ShortReal> (theYMax),
+ static_cast<Standard_ShortReal> (theZMax),
+ 1.0f);
}
// =======================================================================
theXMin = theYMin = theZMin = ShortRealFirst();
theXMax = theYMax = theZMax = ShortRealLast();
}
+ else if (myBounds.IsValid())
+ {
+ const Graphic3d_Vec4& aMinPt = myBounds.CornerMin();
+ const Graphic3d_Vec4& aMaxPt = myBounds.CornerMax();
+ theXMin = Standard_Real (aMinPt.x());
+ theYMin = Standard_Real (aMinPt.y());
+ theZMin = Standard_Real (aMinPt.z());
+ theXMax = Standard_Real (aMaxPt.x());
+ theYMax = Standard_Real (aMaxPt.y());
+ theZMax = Standard_Real (aMaxPt.z());
+ }
else
{
- theXMin = Standard_Real (myBounds.XMin);
- theYMin = Standard_Real (myBounds.YMin);
- theZMin = Standard_Real (myBounds.ZMin);
- theXMax = Standard_Real (myBounds.XMax);
- theYMax = Standard_Real (myBounds.YMax);
- theZMax = Standard_Real (myBounds.ZMax);
+ // for consistency with old API
+ theXMin = theYMin = theZMin = ShortRealLast();
+ theXMax = theYMax = theZMax = ShortRealFirst();
}
}
for (Standard_Integer aVertIter = 0; aVertIter < aNbVerts; ++aVertIter)
{
const Graphic3d_Vec2& aVert = *reinterpret_cast<const Graphic3d_Vec2* >(theAttribs->value (aVertIter) + anOffset);
- if (aVert.x() < myBounds.XMin) myBounds.XMin = aVert.x();
- if (aVert.y() < myBounds.YMin) myBounds.YMin = aVert.y();
- if (aVert.x() > myBounds.XMax) myBounds.XMax = aVert.x();
- if (aVert.y() > myBounds.YMax) myBounds.YMax = aVert.y();
+ myBounds.Add (Graphic3d_Vec4 (aVert.x(), aVert.y(), 0.0f, 1.0f));
}
break;
}
for (Standard_Integer aVertIter = 0; aVertIter < aNbVerts; ++aVertIter)
{
const Graphic3d_Vec3& aVert = *reinterpret_cast<const Graphic3d_Vec3* >(theAttribs->value (aVertIter) + anOffset);
- if (aVert.x() < myBounds.XMin) myBounds.XMin = aVert.x();
- if (aVert.y() < myBounds.YMin) myBounds.YMin = aVert.y();
- if (aVert.z() < myBounds.ZMin) myBounds.ZMin = aVert.z();
- if (aVert.x() > myBounds.XMax) myBounds.XMax = aVert.x();
- if (aVert.y() > myBounds.YMax) myBounds.YMax = aVert.y();
- if (aVert.z() > myBounds.ZMax) myBounds.ZMax = aVert.z();
+ myBounds.Add (Graphic3d_Vec4 (aVert.x(), aVert.y(), aVert.z(), 1.0f));
}
break;
}
{
Standard_ShortReal x, y, z;
thePoint.Coord (x, y, z);
- if (x < myBounds.XMin) myBounds.XMin = x;
- if (y < myBounds.YMin) myBounds.YMin = y;
- if (z < myBounds.ZMin) myBounds.ZMin = z;
- if (x > myBounds.XMax) myBounds.XMax = x;
- if (y > myBounds.YMax) myBounds.YMax = y;
- if (z > myBounds.ZMax) myBounds.ZMax = z;
+ myStructure->CStructure()->Is2dText = Standard_True;
+ myBounds.Add (Graphic3d_Vec4 (static_cast<Standard_ShortReal> (x),
+ static_cast<Standard_ShortReal> (y),
+ static_cast<Standard_ShortReal> (z),
+ 1.0f));
}
Update();
}
{
return myIsClosed;
}
+
+//=======================================================================
+//function : BoundingBox
+//purpose :
+//=======================================================================
+const Graphic3d_BndBox4f& Graphic3d_Group::BoundingBox() const
+{
+ return myBounds;
+}
+
+//=======================================================================
+//function : ChangeBoundingBox
+//purpose :
+//=======================================================================
+Graphic3d_BndBox4f& Graphic3d_Group::ChangeBoundingBox()
+{
+ return myBounds;
+}
Vertex from Graphic3d,
TransModeFlags from Graphic3d,
Pnt from gp,
- SequenceOfHClipPlane from Graphic3d
+ SequenceOfHClipPlane from Graphic3d,
+ BndBox4f from Graphic3d,
+ BndBox4d from Graphic3d
raises
-- Warning: No more graphic operations in <me> after this call.
-- Category: Methods to modify the class definition
+ CalculateBoundBox ( me : mutable )
+ is static;
+ ---Level: Public
+ ---Purpose: Computes axis-aligned bounding box of a structure.
+ -- Category: Methods to modify the class definition
+
SetHighlightColor ( me : mutable;
AColor : Color from Quantity )
is static;
-- <LimitSup> is a negative value.
raises StructureDefinitionError from Graphic3d is static;
+ SetIsForHighlight ( me : mutable;
+ isForHighlight : Boolean from Standard )
+ is static;
+ ---Level: Internal
+ ---Purpose: marks the structure <me> representing wired structure needed for
+ -- highlight only so it won't be added to BVH tree.
+ -- Category: Methods to modify the class definition
+
UnHighlight ( me : mutable )
is static;
---Level: Public
---Purpose: Get the current point of relative modelling transform persistence
is static;
+ SetMutable ( me : mutable;
+ theIsMutable : Boolean from Standard )
+ is static;
+ ---Purpose: Sets if the structure location has mutable nature (content or location will be changed regularly).
+
+ IsMutable ( me )
+ returns Boolean from Standard
+ is static;
+ ---Purpose: Returns true if structure has mutable nature (content or location are be changed regularly).
+ -- Mutable structure will be managed in different way than static onces.
+
----------------------------
-- Category: Private methods
----------------------------
---Purpose: Returns the identification number of the structure <me>.
---Category: Private methods
- MinMaxCoord (me;
- theXMin, theYMin, theZMin : out Real from Standard;
- theXMax, theYMax, theZMax : out Real from Standard)
- is static private;
- ---Level: Internal
- ---Purpose: Returns the extreme coordinates found in the structure <me>.
- -- Warning: If the structure <me> is empty or infinite then :
- -- theXMin = theYMin = theZMin = RealFirst().
- -- theXMax = theYMax = theZMax = RealLast().
- ---Category: Private methods
+ minMaxCoord (me;
+ theToIgnoreInfiniteFlag : Boolean from Standard = Standard_False)
+ returns BndBox4f from Graphic3d
+ is static private;
+ ---Purpose: Returns the extreme coordinates found in the structure <me> without transformation applied.
- MinMaxCoordWithDescendants (me;
- theXMin, theYMin, theZMin : out Real from Standard;
- theXMax, theYMax, theZMax : out Real from Standard)
- is static private;
- ---Level: Internal
- ---Purpose: Returns the extreme coordinates found in the structure <me>
- -- and its descendants with transformation applied.
- -- Warning: If the structure <me> is empty or infinite then :
- -- theXMin = theYMin = theZMin = RealFirst().
- -- theXMax = theYMax = theZMax = RealLast().
- ---Category: Private methods
+ addTransformed (me;
+ theBox : out BndBox4d from Graphic3d;
+ theToIgnoreInfiniteFlag : Boolean from Standard = Standard_False)
+ is static private;
PrintNetwork ( myclass;
AStructure : Structure from Graphic3d;
Update();
}
+//=======================================================================
+//function : CalculateBoundBox
+//purpose : Calculates AABB of a structure.
+//=======================================================================
+void Graphic3d_Structure::CalculateBoundBox()
+{
+ Graphic3d_BndBox4d aBox;
+ addTransformed (aBox, Standard_True);
+ if (aBox.IsValid() && myCStructure->TransformPersistence.Flag == 0)
+ {
+ Graphic3d_Vec4 aMinPt (RealToShortReal (aBox.CornerMin().x()),
+ RealToShortReal (aBox.CornerMin().y()),
+ RealToShortReal (aBox.CornerMin().z()),
+ 1.0f);
+ Graphic3d_Vec4 aMaxPt (RealToShortReal (aBox.CornerMax().x()),
+ RealToShortReal (aBox.CornerMax().y()),
+ RealToShortReal (aBox.CornerMax().z()),
+ 1.0f);
+ myCStructure->ChangeBoundingBox() = Graphic3d_BndBox4f (aMinPt, aMaxPt);
+ }
+ else
+ {
+ myCStructure->ChangeBoundingBox().Clear();
+ }
+}
+
//=============================================================================
//function : Remove
//purpose :
((Graphic3d_Structure *)(myAncestors.ChangeValue (aStructIter)))->Remove (APtr, Graphic3d_TOC_DESCENDANT);
}
- myCStructure->ContainsFacet = 0;
-
// Destruction of me in the graphic library
const Standard_Integer aStructId = myCStructure->Id;
myCStructure->GraphicDriver()->RemoveStructure (myCStructure);
myCStructure->visible = 1;
}
+//=============================================================================
+//function : SetIsForHighlight
+//purpose :
+//=============================================================================
+void Graphic3d_Structure::SetIsForHighlight (const Standard_Boolean isForHighlight)
+{
+ myCStructure->IsForHighlight = isForHighlight;
+}
+
//=============================================================================
//function : Display
//purpose :
}
myDescendants.Append (theStructure.operator->());
+ CalculateBoundBox();
theStructure->Connect (this, Graphic3d_TOC_ANCESTOR);
GraphicConnect (theStructure);
}
myAncestors.Append (theStructure.operator->());
+ CalculateBoundBox();
theStructure->Connect (this, Graphic3d_TOC_DESCENDANT);
// myGraphicDriver->Connect is called in case if connection between parent and child
GraphicDisconnect (theStructure);
myStructureManager->Disconnect (this, theStructure);
+ CalculateBoundBox();
+
Update();
return;
}
{
myAncestors.Remove (anIter);
theStructure->Disconnect (this);
+ CalculateBoundBox();
// no call of myGraphicDriver->Disconnect in case of an ancestor
return;
}
}
}
+
//=============================================================================
//function : MinMaxValues
//purpose :
Standard_Real& theZMax,
const Standard_Boolean theToIgnoreInfiniteFlag) const
{
- if (IsEmpty())
- {
- return;
- }
-
- Standard_Real aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;
- MinMaxCoord (aXMin, aYMin, aZMin, aXMax, aYMax, aZMax);
-
- // Infinite boundaries corresponding to empty structure or
- // non-empty structure, without any primitives specified
- if (aXMin == RealFirst() && aYMin == RealFirst() && aZMin == RealFirst() &&
- aXMax == RealLast() && aYMax == RealLast() && aZMax == RealLast())
- {
- theXMin = RealFirst();
- theYMin = RealFirst();
- theZMin = RealFirst();
- theXMax = RealLast();
- theYMax = RealLast();
- theZMax = RealLast();
- return;
- }
-
- // Handle flag, which specifies that structure should be considered as infinite
- if (IsInfinite() && !theToIgnoreInfiniteFlag)
- {
- Graphic3d_Vertex aVertexMin (aXMin, aYMin, aZMin);
- Graphic3d_Vertex aVertexMax (aXMax, aYMax, aZMax);
- const Standard_Real aDistance = aVertexMin.Distance (aVertexMax);
-
- // Special case for infinite line:
- // Bounding borders of infinite line has been
- // calculated as own point in center of this line
- if (aDistance >= 500000.0)
- {
- theXMin = theXMax = 0.5 * (aXMin + aXMax);
- theYMin = theYMax = 0.5 * (aYMin + aYMax);
- theZMin = theZMax = 0.5 * (aZMin + aZMax);
- return;
- }
-
- theXMin = RealFirst();
- theYMin = RealFirst();
- theZMin = RealFirst();
- theXMax = RealLast();
- theYMax = RealLast();
- theZMax = RealLast();
- return;
- }
-
- // Min-Max values of the descendant structures
- Standard_Real aDescXMin = RealLast();
- Standard_Real aDescYMin = RealLast();
- Standard_Real aDescZMin = RealLast();
- Standard_Real aDescXMax = RealFirst();
- Standard_Real aDescYMax = RealFirst();
- Standard_Real aDescZMax = RealFirst();
- for (Standard_Integer aStructIt = 1; aStructIt <= myDescendants.Length(); aStructIt++)
- {
- Graphic3d_Structure* aStructure = (Graphic3d_Structure*) myDescendants.Value (aStructIt);
- aStructure->MinMaxValues (aXMin, aYMin, aZMin, aXMax, aYMax, aZMax);
- aDescXMin = Min (aXMin, aDescXMin);
- aDescYMin = Min (aYMin, aDescYMin);
- aDescZMin = Min (aZMin, aDescZMin);
- aDescXMax = Max (aXMax, aDescXMax);
- aDescYMax = Max (aYMax, aDescYMax);
- aDescZMax = Max (aZMax, aDescZMax);
- }
-
- if (aDescXMin != RealLast() || aDescYMin != RealLast() ||
- aDescZMin != RealLast() || aDescXMax != RealFirst() ||
- aDescYMax != RealFirst() || aDescZMax != RealFirst())
- {
- aXMin = Min (aDescXMin, aXMin);
- aYMin = Min (aDescYMin, aYMin);
- aZMin = Min (aDescZMin, aZMin);
- aXMax = Max (aDescXMax, aXMax);
- aYMax = Max (aDescYMax, aYMax);
- aZMax = Max (aDescZMax, aZMax);
- }
-
- // Case impossible as it would mean that the structure is empty or infinite
- if (aXMin == RealFirst() && aYMin == RealFirst() && aZMin == RealFirst() &&
- aXMax == RealLast() && aYMax == RealLast() && aZMax == RealLast())
+ Graphic3d_BndBox4d aBox;
+ addTransformed (aBox, theToIgnoreInfiniteFlag);
+ if (!aBox.IsValid())
{
theXMin = RealFirst();
theYMin = RealFirst();
return;
}
- TColStd_Array2OfReal aTrsf(0, 3, 0, 3);
- Transform (aTrsf);
- TransformBoundaries (aTrsf, aXMin, aYMin, aZMin, aXMax, aYMax, aZMax);
- theXMin = aXMin;
- theYMin = aYMin;
- theZMin = aZMin;
- theXMax = aXMax;
- theYMax = aYMax;
- theZMax = aZMax;
+ theXMin = aBox.CornerMin().x();
+ theYMin = aBox.CornerMin().y();
+ theZMin = aBox.CornerMin().z();
+ theXMax = aBox.CornerMax().x();
+ theYMax = aBox.CornerMax().y();
+ theZMax = aBox.CornerMax().z();
}
//=============================================================================
myCStructure->TransformPersistence.Point.y = float (thePoint.Y());
myCStructure->TransformPersistence.Point.z = float (thePoint.Z());
myCStructure->UpdateAspects();
+ CalculateBoundBox();
myCStructure->TransformPersistence.IsSet = 1;
}
}
//=============================================================================
-//function : MinMaxCoord
+//function : minMaxCoord
//purpose :
//=============================================================================
-void Graphic3d_Structure::MinMaxCoord (Standard_Real& theXMin,
- Standard_Real& theYMin,
- Standard_Real& theZMin,
- Standard_Real& theXMax,
- Standard_Real& theYMax,
- Standard_Real& theZMax) const
+Graphic3d_BndBox4f Graphic3d_Structure::minMaxCoord (const Standard_Boolean theToIgnoreInfiniteFlag) const
{
- if (IsEmpty())
- {
- theXMin = RealFirst();
- theYMin = RealFirst();
- theZMin = RealFirst();
- theXMax = RealLast();
- theYMax = RealLast();
- theZMax = RealLast();
- return;
- }
-
- Standard_Real aXMin = RealLast();
- Standard_Real aYMin = RealLast();
- Standard_Real aZMin = RealLast();
- Standard_Real aXMax = RealFirst();
- Standard_Real aYMax = RealFirst();
- Standard_Real aZMax = RealFirst();
- Standard_Real aGroupXMin, aGroupYMin, aGroupZMin, aGroupXMax, aGroupYMax, aGroupZMax;
+ Graphic3d_BndBox4f aBnd;
for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myCStructure->Groups()); aGroupIter.More(); aGroupIter.Next())
{
- const Handle(Graphic3d_Group)& aGroup = aGroupIter.Value();
- if (aGroup->IsEmpty())
+ if (!theToIgnoreInfiniteFlag)
{
- continue;
+ aBnd.Combine (aGroupIter.Value()->BoundingBox());
+ }
+ else
+ {
+ Graphic3d_BndBox4f aValidBnd (aGroupIter.Value()->BoundingBox().CornerMin(),
+ aGroupIter.Value()->BoundingBox().CornerMax());
+ aBnd.Combine (aValidBnd);
}
-
- aGroup->MinMaxValues (aGroupXMin, aGroupYMin, aGroupZMin, aGroupXMax, aGroupYMax, aGroupZMax);
- aXMin = Min (aXMin, aGroupXMin);
- aYMin = Min (aYMin, aGroupYMin);
- aZMin = Min (aZMin, aGroupZMin);
- aXMax = Max (aXMax, aGroupXMax);
- aYMax = Max (aYMax, aGroupYMax);
- aZMax = Max (aZMax, aGroupZMax);
- }
-
- // Case impossible as it would mean that the structure is empty
- if (aXMin == RealLast() && aYMin == RealLast() && aZMin == RealLast() &&
- aXMax == RealFirst() && aYMax == RealFirst() && aZMax == RealFirst())
- {
- theXMin = RealFirst();
- theYMin = RealFirst();
- theZMin = RealFirst();
- theXMax = RealLast();
- theYMax = RealLast();
- theZMax = RealLast();
}
-
- theXMin = aXMin;
- theYMin = aYMin;
- theZMin = aZMin;
- theXMax = aXMax;
- theYMax = aYMax;
- theZMax = aZMax;
+ return aBnd;
}
//=============================================================================
-//function : MinMaxCoordWithDescendants
+//function : addTransformed
//purpose :
//=============================================================================
-void Graphic3d_Structure::MinMaxCoordWithDescendants (Standard_Real& theXMin,
- Standard_Real& theYMin,
- Standard_Real& theZMin,
- Standard_Real& theXMax,
- Standard_Real& theYMax,
- Standard_Real& theZMax) const
+void Graphic3d_Structure::addTransformed (Graphic3d_BndBox4d& theBox,
+ const Standard_Boolean theToIgnoreInfiniteFlag) const
{
- if (IsEmpty())
+ Graphic3d_BndBox4d aBox;
+ Graphic3d_BndBox4f aBoxF = minMaxCoord (theToIgnoreInfiniteFlag);
+ if (aBoxF.IsValid())
{
- theXMin = RealFirst();
- theYMin = RealFirst();
- theZMin = RealFirst();
- theXMax = RealLast();
- theYMax = RealLast();
- theZMax = RealLast();
- return;
- }
-
- Standard_Real aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;
- MinMaxCoord (aXMin, aYMin, aZMin, aXMax, aYMax, aZMax);
-
- // Min-Max of the descendant structures
- Standard_Real aDescXMin = RealLast();
- Standard_Real aDescYMin = RealLast();
- Standard_Real aDescZMin = RealLast();
- Standard_Real aDescXMax = RealFirst();
- Standard_Real aDescYMax = RealFirst();
- Standard_Real aDescZMax = RealFirst();
- for (Standard_Integer aStructIt = 1; aStructIt <= myDescendants.Length(); aStructIt++)
- {
- Graphic3d_Structure* aStructure = (Graphic3d_Structure*) myDescendants.Value (aStructIt);
- if (aStructure->IsEmpty())
+ aBox = Graphic3d_BndBox4d (Graphic3d_Vec4d ((Standard_Real )aBoxF.CornerMin().x(),
+ (Standard_Real )aBoxF.CornerMin().y(),
+ (Standard_Real )aBoxF.CornerMin().z(),
+ (Standard_Real )aBoxF.CornerMin().w()),
+ Graphic3d_Vec4d ((Standard_Real )aBoxF.CornerMax().x(),
+ (Standard_Real )aBoxF.CornerMax().y(),
+ (Standard_Real )aBoxF.CornerMax().z(),
+ (Standard_Real )aBoxF.CornerMax().w()));
+ if (IsInfinite()
+ && !theToIgnoreInfiniteFlag)
{
- continue;
+ const Graphic3d_Vec4d aDiagVec = aBox.CornerMax() - aBox.CornerMin();
+ if (aDiagVec.xyz().SquareModulus() >= 500000.0 * 500000.0)
+ {
+ // bounding borders of infinite line has been calculated as own point in center of this line
+ aBox = Graphic3d_BndBox4d ((aBox.CornerMin() + aBox.CornerMax()) * 0.5);
+ }
+ else
+ {
+ theBox = Graphic3d_BndBox4d (Graphic3d_Vec4d (RealFirst(), RealFirst(), RealFirst(), 1.0),
+ Graphic3d_Vec4d (RealLast(), RealLast(), RealLast(), 1.0));
+ return;
+ }
}
-
- aStructure->MinMaxCoordWithDescendants (aXMin, aYMin, aZMin, aXMax, aYMax, aZMax);
- aDescXMin = Min (aXMin, aDescXMin);
- aDescYMin = Min (aYMin, aDescYMin);
- aDescZMin = Min (aZMin, aDescZMin);
- aDescXMax = Max (aXMax, aDescXMax);
- aDescYMax = Max (aYMax, aDescYMax);
- aDescZMax = Max (aZMax, aDescZMax);
}
- if (aDescXMin != RealLast() || aDescYMin != RealLast() ||
- aDescZMin != RealLast() || aDescXMax != RealFirst() ||
- aDescYMax != RealFirst() || aDescZMax != RealFirst())
+ for (Standard_Integer aStructIt = 1; aStructIt <= myDescendants.Length(); ++aStructIt)
{
- TColStd_Array2OfReal aTrsf(0, 3, 0, 3);
- Transform (aTrsf);
- TransformBoundaries (aTrsf, aDescXMin, aDescYMin, aDescZMin, aDescXMax, aDescYMax, aDescZMax);
-
- aXMin = Min (aDescXMin, aXMin);
- aYMin = Min (aDescYMin, aYMin);
- aZMin = Min (aDescZMin, aZMin);
- aXMax = Max (aDescXMax, aXMax);
- aYMax = Max (aDescYMax, aYMax);
- aZMax = Max (aDescZMax, aZMax);
+ const Graphic3d_Structure* aStruct = (const Graphic3d_Structure* )myDescendants.Value (aStructIt);
+ aStruct->addTransformed (aBox, theToIgnoreInfiniteFlag);
}
- // Case impossible as it would mean that the structure is empty
- if (aXMin == RealLast() && aYMin == RealLast() && aZMin == RealLast() &&
- aXMax == RealFirst() && aYMax == RealFirst() && aZMax == RealFirst())
+ if (aBox.IsValid())
{
- theXMin = RealFirst();
- theYMin = RealFirst();
- theZMin = RealFirst();
- theXMax = RealLast();
- theYMax = RealLast();
- theZMax = RealLast();
+ TColStd_Array2OfReal aTrsf (0, 3, 0, 3);
+ Transform (aTrsf);
+ TransformBoundaries (aTrsf, aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z(),
+ aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z());
+ theBox.Combine (aBox);
}
-
- theXMin = aXMin;
- theYMin = aYMin;
- theZMin = aZMin;
- theXMax = aXMax;
- theYMax = aYMax;
- theZMax = aZMax;
}
//=============================================================================
}
case Aspect_TOHM_BOUNDBOX:
{
- Standard_Real XMin, YMin, ZMin, XMax, YMax, ZMax;
- if (IsEmpty() || IsInfinite())
- {
- // Empty or infinite structure
- XMin = YMin = ZMin = 0.0;
- XMax = YMax = ZMax = 0.0;
- }
- else
- {
- MinMaxCoordWithDescendants (XMin, YMin, ZMin, XMax, YMax, ZMax);
- }
- myCStructure->BoundBox.Pmin.x = float (XMin);
- myCStructure->BoundBox.Pmin.y = float (YMin);
- myCStructure->BoundBox.Pmin.z = float (ZMin);
- myCStructure->BoundBox.Pmax.x = float (XMax);
- myCStructure->BoundBox.Pmax.y = float (YMax);
- myCStructure->BoundBox.Pmax.z = float (ZMax);
myHighlightColor.Values (anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB);
- myCStructure->BoundBox.Color.r = float (anRGB[0]);
- myCStructure->BoundBox.Color.g = float (anRGB[1]);
- myCStructure->BoundBox.Color.b = float (anRGB[2]);
+ myCStructure->HighlightColor.r = float (anRGB[0]);
+ myCStructure->HighlightColor.g = float (anRGB[1]);
+ myCStructure->HighlightColor.b = float (anRGB[2]);
myCStructure->HighlightWithBndBox (this, Standard_True);
break;
}
{
return myCStructure->ClipPlanes();
}
+
+//=======================================================================
+//function : SetMutable
+//purpose :
+//=======================================================================
+void Graphic3d_Structure::SetMutable (const Standard_Boolean theIsMutable)
+{
+ myCStructure->IsMutable = theIsMutable;
+}
+
+//=======================================================================
+//function : IsMutable
+//purpose :
+//=======================================================================
+Standard_Boolean Graphic3d_Structure::IsMutable() const
+{
+ return myCStructure->IsMutable;
+}
#define InterfaceGraphic_Graphic3dHeader
#include <InterfaceGraphic_telem.hxx>
+#include <Graphic3d_BndBox4f.hxx>
#include <Standard_Transient.hxx>
/* COULEUR */
} CALL_DEF_POINT;
-/* BOITE ENGLOBANTE */
-
-typedef struct {
-
- CALL_DEF_COLOR Color;
-
- CALL_DEF_POINT Pmin;
-
- CALL_DEF_POINT Pmax;
-
-} CALL_DEF_BOUNDBOX;
-
/* MATERIAL */
typedef struct {
CALL_DEF_POINT Point;
} CALL_DEF_TRANSFORM_PERSISTENCE;
-/* BOUNDING BOX */
-
-typedef struct {
-
- float XMin;
- float YMin;
- float ZMin;
-
- float XMax;
- float YMax;
- float ZMax;
-
-} CALL_DEF_BOUNDS;
-
/* USERDRAW DATA */
typedef struct {
void *Data;
- CALL_DEF_BOUNDS *Bounds;
+ Graphic3d_BndBox4f *Bounds;
} CALL_DEF_USERDRAW;
//! Compute per-component division by scale factor.
NCollection_Vec4 operator/ (const Element_t theInvFactor)
{
- NCollection_Vec4 aResult(this);
+ NCollection_Vec4 aResult(*this);
return aResult /= theInvFactor;
}
OpenGl_Workspace_Raytrace.cxx
OpenGl_Flipper.hxx
OpenGl_Flipper.cxx
+OpenGl_BVHTreeSelector.hxx
+OpenGl_BVHTreeSelector.cxx
+OpenGl_BVHClipPrimitiveSet.cxx
+OpenGl_BVHClipPrimitiveSet.hxx
--- /dev/null
+// Created on: 2013-12-25
+// Created by: Varvara POSKONINA
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <OpenGl_BVHClipPrimitiveSet.hxx>
+
+#include <BVH_BinnedBuilder.hxx>
+
+// =======================================================================
+// function : OpenGl_BVHClipPrimitiveSet
+// purpose :
+// =======================================================================
+OpenGl_BVHClipPrimitiveSet::OpenGl_BVHClipPrimitiveSet()
+{
+ myBuilder = new BVH_BinnedBuilder<Standard_ShortReal, 4> (1, 32);
+}
+
+// =======================================================================
+// function : Size
+// purpose :
+// =======================================================================
+Standard_Integer OpenGl_BVHClipPrimitiveSet::Size() const
+{
+ return myStructs.Size();
+}
+
+// =======================================================================
+// function : Box
+// purpose :
+// =======================================================================
+Graphic3d_BndBox4f OpenGl_BVHClipPrimitiveSet::Box (const Standard_Integer theIdx) const
+{
+ return myStructs (theIdx + 1)->BoundingBox();
+}
+
+// =======================================================================
+// function : Center
+// purpose :
+// =======================================================================
+Standard_ShortReal OpenGl_BVHClipPrimitiveSet::Center (const Standard_Integer theIdx,
+ const Standard_Integer theAxis) const
+{
+ Graphic3d_BndBox4f aBndBox = myStructs (theIdx + 1)->BoundingBox();
+ Standard_ShortReal aCenter = theAxis == 0 ? (aBndBox.CornerMin().x() + aBndBox.CornerMax().x()) * 0.5f
+ : (theAxis == 1 ? (aBndBox.CornerMin().y() + aBndBox.CornerMax().y()) * 0.5f
+ : (theAxis == 2 ? (aBndBox.CornerMin().z() + aBndBox.CornerMax().z()) * 0.5f
+ : (aBndBox.CornerMin().w() + aBndBox.CornerMax().w()) * 0.5f));
+ return aCenter;
+}
+
+// =======================================================================
+// function : Swap
+// purpose :
+// =======================================================================
+void OpenGl_BVHClipPrimitiveSet::Swap (const Standard_Integer theIdx1,
+ const Standard_Integer theIdx2)
+{
+ const OpenGl_Structure* aStruct1 = myStructs (theIdx1 + 1);
+ const OpenGl_Structure* aStruct2 = myStructs (theIdx2 + 1);
+ myStructs.ChangeValue (theIdx1 + 1) = aStruct2;
+ myStructs.ChangeValue (theIdx2 + 1) = aStruct1;
+}
+
+// =======================================================================
+// function : Assign
+// purpose :
+// =======================================================================
+void OpenGl_BVHClipPrimitiveSet::Assign (const OpenGl_ArrayOfStructure& theStructs)
+{
+ myStructs.Clear();
+
+ const Standard_Integer aNbPriorities = theStructs.Length();
+ OpenGl_SequenceOfStructure::Iterator aStructIter;
+ for (Standard_Integer aPriorityIdx = 0; aPriorityIdx < aNbPriorities; ++aPriorityIdx)
+ {
+ const OpenGl_SequenceOfStructure& aSeq = theStructs (aPriorityIdx);
+ for (aStructIter.Init (aSeq); aStructIter.More(); aStructIter.Next())
+ {
+ const OpenGl_Structure* aStruct = aStructIter.Value();
+ if (!aStruct->IsAlwaysRendered())
+ myStructs.Append (aStruct);
+ }
+ }
+
+ MarkDirty();
+}
+
+// =======================================================================
+// function : Add
+// purpose :
+// =======================================================================
+void OpenGl_BVHClipPrimitiveSet::Add (const OpenGl_Structure* theStruct)
+{
+ myStructs.Append (theStruct);
+ MarkDirty();
+}
+
+// =======================================================================
+// function : Remove
+// purpose :
+// =======================================================================
+void OpenGl_BVHClipPrimitiveSet::Remove (const OpenGl_Structure* theStruct)
+{
+ for (Standard_Integer anIdx = 1; anIdx <= myStructs.Size(); ++anIdx)
+ {
+ if (myStructs (anIdx) == theStruct)
+ {
+ myStructs.Remove (anIdx);
+ MarkDirty();
+ break;
+ }
+ }
+}
+
+// =======================================================================
+// function : Clear
+// purpose :
+// =======================================================================
+void OpenGl_BVHClipPrimitiveSet::Clear()
+{
+ myStructs.Clear();
+ MarkDirty();
+}
+
+// =======================================================================
+// function : GetStructureById
+// purpose :
+// =======================================================================
+const OpenGl_Structure* OpenGl_BVHClipPrimitiveSet::GetStructureById (Standard_Integer theId)
+{
+ return myStructs (theId + 1);
+}
--- /dev/null
+// Created on: 2013-12-25
+// Created by: Varvara POSKONINA
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _OpenGl_BVHClipPrimitiveSet_HeaderFile
+#define _OpenGl_BVHClipPrimitiveSet_HeaderFile
+
+#include <BVH_PrimitiveSet.hxx>
+
+#include <NCollection_Array1.hxx>
+#include <NCollection_Sequence.hxx>
+
+#include <OpenGl_Vec.hxx>
+#include <OpenGl_Structure.hxx>
+
+typedef NCollection_Sequence<const OpenGl_Structure*> OpenGl_SequenceOfStructure;
+typedef NCollection_Array1<OpenGl_SequenceOfStructure> OpenGl_ArrayOfStructure;
+
+//! Set of OpenGl_Structures for building BVH tree.
+class OpenGl_BVHClipPrimitiveSet : public BVH_PrimitiveSet<Standard_ShortReal, 4>
+{
+protected:
+
+ using BVH_PrimitiveSet<Standard_ShortReal, 4>::Box;
+
+public:
+
+ //! Creates an empty primitive set for BVH clipping.
+ OpenGl_BVHClipPrimitiveSet();
+
+ //! Returns total number of structures.
+ virtual Standard_Integer Size() const;
+
+ //! Returns AABB of a structure.
+ virtual Graphic3d_BndBox4f Box (const Standard_Integer theIdx) const;
+
+ //! Calculates center of the AABB projection onto given axis.
+ virtual Standard_ShortReal Center (const Standard_Integer theIdx,
+ const Standard_Integer theAxis) const;
+
+ //! Swaps given AABBs.
+ virtual void Swap (const Standard_Integer theIdx1,
+ const Standard_Integer theIdx2);
+
+ //! Replaces the set by the given array taking into account
+ //! if each structure is cullable or not.
+ void Assign (const OpenGl_ArrayOfStructure& theStructs);
+
+ //! Adds structure theStruct to the set.
+ void Add (const OpenGl_Structure* theStruct);
+
+ //! Removes the given OpenGl_Structure from the set.
+ void Remove (const OpenGl_Structure* theStruct);
+
+ //! Cleans the whole primitive set.
+ void Clear();
+
+ //! Returns the structure corresponding to the given id.
+ const OpenGl_Structure* GetStructureById (Standard_Integer theId);
+
+private:
+
+ NCollection_Sequence<const OpenGl_Structure*> myStructs; //!< Sequence of structures
+
+};
+
+#endif // _OpenGl_BVHClipPrimitiveSet_HeaderFile
--- /dev/null
+// Created on: 2013-12-25
+// Created by: Varvara POSKONINA
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <OpenGl_BVHTreeSelector.hxx>
+#include <OpenGl_BVHClipPrimitiveSet.hxx>
+
+#include <vector>
+#include <algorithm>
+
+// =======================================================================
+// function : DotProduct
+// purpose : Calculates a dot product of 4-dimensional vectors in homogeneous coordinates
+// =======================================================================
+static Standard_ShortReal DotProduct (const OpenGl_Vec4& theA,
+ const OpenGl_Vec4& theB)
+{
+ return theA.x() * theB.x() + theA.y() * theB.y() + theA.z() * theB.z();
+}
+
+// =======================================================================
+// function : BinarySign
+// purpose :
+// =======================================================================
+static OpenGl_Vec4 BinarySign (const OpenGl_Vec4& theVec)
+{
+ return OpenGl_Vec4 (theVec.x() > 0.0f ? 1.0f : 0.0f,
+ theVec.y() > 0.0f ? 1.0f : 0.0f,
+ theVec.z() > 0.0f ? 1.0f : 0.0f,
+ theVec.w() > 0.0f ? 1.0f : 0.0f);
+}
+
+// =======================================================================
+// function : InversedBinarySign
+// purpose :
+// =======================================================================
+static OpenGl_Vec4 InversedBinarySign (const OpenGl_Vec4& theVec)
+{
+ return OpenGl_Vec4 (theVec.x() > 0.0f ? 0.0f : 1.0f,
+ theVec.y() > 0.0f ? 0.0f : 1.0f,
+ theVec.z() > 0.0f ? 0.0f : 1.0f,
+ theVec.w() > 0.0f ? 0.0f : 1.0f);
+}
+
+// =======================================================================
+// function : OpenGl_BVHTreeSelector
+// purpose :
+// =======================================================================
+OpenGl_BVHTreeSelector::OpenGl_BVHTreeSelector()
+: myIsProjectionParallel (Standard_True),
+ myProjectionState (0),
+ myModelViewState (0)
+{
+ //
+}
+
+// =======================================================================
+// function : SetClipVolume
+// purpose : Retrieves view volume's planes equations and its vertices from projection and modelview matrices.
+// =======================================================================
+void OpenGl_BVHTreeSelector::SetViewVolume (const Handle(Graphic3d_Camera)& theCamera)
+{
+ myIsProjectionParallel = theCamera->IsOrthographic();
+ const OpenGl_Mat4& aProjMat = theCamera->ProjectionMatrixF();
+ const OpenGl_Mat4& aModelMat = theCamera->OrientationMatrixF();
+
+ Standard_ShortReal nLeft = 0.0f, nRight = 0.0f, nTop = 0.0f, nBottom = 0.0f;
+ Standard_ShortReal fLeft = 0.0f, fRight = 0.0f, fTop = 0.0f, fBottom = 0.0f;
+ Standard_ShortReal aNear = 0.0f, aFar = 0.0f;
+ if (!myIsProjectionParallel)
+ {
+ // handle perspective projection
+ aNear = aProjMat.GetValue (2, 3) / (- 1.0f + aProjMat.GetValue (2, 2));
+ aFar = aProjMat.GetValue (2, 3) / ( 1.0f + aProjMat.GetValue (2, 2));
+ // Near plane
+ nLeft = aNear * (aProjMat.GetValue (0, 2) - 1.0f) / aProjMat.GetValue (0, 0);
+ nRight = aNear * (aProjMat.GetValue (0, 2) + 1.0f) / aProjMat.GetValue (0, 0);
+ nTop = aNear * (aProjMat.GetValue (1, 2) + 1.0f) / aProjMat.GetValue (1, 1);
+ nBottom = aNear * (aProjMat.GetValue (1, 2) - 1.0f) / aProjMat.GetValue (1, 1);
+ // Far plane
+ fLeft = aFar * (aProjMat.GetValue (0, 2) - 1.0f) / aProjMat.GetValue (0, 0);
+ fRight = aFar * (aProjMat.GetValue (0, 2) + 1.0f) / aProjMat.GetValue (0, 0);
+ fTop = aFar * (aProjMat.GetValue (1, 2) + 1.0f) / aProjMat.GetValue (1, 1);
+ fBottom = aFar * (aProjMat.GetValue (1, 2) - 1.0f) / aProjMat.GetValue (1, 1);
+ }
+ else
+ {
+ // handle orthographic projection
+ aNear = (1.0f / aProjMat.GetValue (2, 2)) * (aProjMat.GetValue (2, 3) + 1.0f);
+ aFar = (1.0f / aProjMat.GetValue (2, 2)) * (aProjMat.GetValue (2, 3) - 1.0f);
+ // Near plane
+ nLeft = ( 1.0f + aProjMat.GetValue (0, 3)) / (-aProjMat.GetValue (0, 0));
+ fLeft = nLeft;
+ nRight = ( 1.0f - aProjMat.GetValue (0, 3)) / aProjMat.GetValue (0, 0);
+ fRight = nRight;
+ nTop = ( 1.0f - aProjMat.GetValue (1, 3)) / aProjMat.GetValue (1, 1);
+ fTop = nTop;
+ nBottom = (-1.0f - aProjMat.GetValue (1, 3)) / aProjMat.GetValue (1, 1);
+ fBottom = nBottom;
+ }
+
+ OpenGl_Vec4 aLeftTopNear (nLeft, nTop, -aNear, 1.0f), aRightBottomFar (fRight, fBottom, -aFar, 1.0f);
+ OpenGl_Vec4 aLeftBottomNear (nLeft, nBottom, -aNear, 1.0f), aRightTopFar (fRight, fTop, -aFar, 1.0f);
+ OpenGl_Vec4 aRightBottomNear (nRight, nBottom, -aNear, 1.0f), aLeftTopFar (fLeft, fTop, -aFar, 1.0f);
+ OpenGl_Vec4 aRightTopNear (nRight, nTop, -aNear, 1.0f), aLeftBottomFar (fLeft, fBottom, -aFar, 1.0f);
+
+ const OpenGl_Mat4 aViewProj = aModelMat * aProjMat;
+ OpenGl_Mat4 anInvModelView;
+ aModelMat.Inverted(anInvModelView);
+
+ myClipVerts[ClipVert_LeftTopNear] = anInvModelView * aLeftTopNear;
+ myClipVerts[ClipVert_RightBottomFar] = anInvModelView * aRightBottomFar;
+ myClipVerts[ClipVert_LeftBottomNear] = anInvModelView * aLeftBottomNear;
+ myClipVerts[ClipVert_RightTopFar] = anInvModelView * aRightTopFar;
+ myClipVerts[ClipVert_RightBottomNear] = anInvModelView * aRightBottomNear;
+ myClipVerts[ClipVert_LeftTopFar] = anInvModelView * aLeftTopFar;
+ myClipVerts[ClipVert_RightTopNear] = anInvModelView * aRightTopNear;
+ myClipVerts[ClipVert_LeftBottomFar] = anInvModelView * aLeftBottomFar;
+
+ // UNNORMALIZED!
+ myClipPlanes[Plane_Left] = aViewProj.GetRow (3) + aViewProj.GetRow (0);
+ myClipPlanes[Plane_Right] = aViewProj.GetRow (3) - aViewProj.GetRow (0);
+ myClipPlanes[Plane_Top] = aViewProj.GetRow (3) - aViewProj.GetRow (1);
+ myClipPlanes[Plane_Bottom] = aViewProj.GetRow (3) + aViewProj.GetRow (1);
+ myClipPlanes[Plane_Near] = aViewProj.GetRow (3) + aViewProj.GetRow (2);
+ myClipPlanes[Plane_Far] = aViewProj.GetRow (3) - aViewProj.GetRow (2);
+
+ gp_Pnt aPtCenter = theCamera->Center();
+ OpenGl_Vec4 aCenter (static_cast<Standard_ShortReal> (aPtCenter.X()),
+ static_cast<Standard_ShortReal> (aPtCenter.Y()),
+ static_cast<Standard_ShortReal> (aPtCenter.Z()),
+ 1.0f);
+
+ for (Standard_Integer aPlaneIter = 0; aPlaneIter < PlanesNB; ++aPlaneIter)
+ {
+ OpenGl_Vec4 anEq = myClipPlanes[aPlaneIter];
+ if (SignedPlanePointDistance (anEq, aCenter) > 0)
+ {
+ anEq *= -1.0f;
+ myClipPlanes[aPlaneIter] = anEq;
+ }
+ }
+}
+
+// =======================================================================
+// function : SignedPlanePointDistance
+// purpose :
+// =======================================================================
+Standard_ShortReal OpenGl_BVHTreeSelector::SignedPlanePointDistance (const OpenGl_Vec4& theNormal,
+ const OpenGl_Vec4& thePnt)
+{
+ const Standard_ShortReal aNormLength = std::sqrt (theNormal.x() * theNormal.x()
+ + theNormal.y() * theNormal.y()
+ + theNormal.z() * theNormal.z());
+ const Standard_ShortReal anInvNormLength = 1.0f / aNormLength;
+ const Standard_ShortReal aD = theNormal.w() * anInvNormLength;
+ const Standard_ShortReal anA = theNormal.x() * anInvNormLength;
+ const Standard_ShortReal aB = theNormal.y() * anInvNormLength;
+ const Standard_ShortReal aC = theNormal.z() * anInvNormLength;
+ return aD + (anA * thePnt.x() + aB * thePnt.y() + aC * thePnt.z());
+}
+
+// =======================================================================
+// function : CacheClipPtsProjections
+// purpose : Caches view volume's vertices projections along its normals and AABBs dimensions
+// Must be called at the beginning of each BVH tree traverse loop
+// =======================================================================
+void OpenGl_BVHTreeSelector::CacheClipPtsProjections()
+{
+ Standard_ShortReal aProjectedVerts[ClipVerticesNB];
+ for (Standard_Integer aPlaneIter = 0; aPlaneIter < PlanesNB; ++aPlaneIter)
+ {
+ const OpenGl_Vec4 aPlane = myClipPlanes[aPlaneIter];
+ for (Standard_Integer aCornerIter = 0; aCornerIter < ClipVerticesNB; ++aCornerIter)
+ {
+ Standard_ShortReal aProjection = DotProduct (aPlane, myClipVerts[aCornerIter]);
+ aProjectedVerts[aCornerIter] = aProjection;
+ }
+ myMaxClipProjectionPts[aPlaneIter] = *std::max_element (aProjectedVerts, aProjectedVerts + ClipVerticesNB);
+ myMinClipProjectionPts[aPlaneIter] = *std::min_element (aProjectedVerts, aProjectedVerts + ClipVerticesNB);
+ }
+
+ OpenGl_Vec4 aDimensions[3] =
+ {
+ OpenGl_Vec4 (1.0f, 0.0f, 0.0f, 1.0f),
+ OpenGl_Vec4 (0.0f, 1.0f, 0.0f, 1.0f),
+ OpenGl_Vec4 (0.0f, 0.0f, 1.0f, 1.0f)
+ };
+
+ for (Standard_Integer aDim = 0; aDim < 3; ++aDim)
+ {
+ for (Standard_Integer aCornerIter = 0; aCornerIter < ClipVerticesNB; ++aCornerIter)
+ {
+ Standard_ShortReal aProjection = DotProduct (aDimensions[aDim], myClipVerts[aCornerIter]);
+ aProjectedVerts[aCornerIter] = aProjection;
+ }
+ myMaxOrthoProjectionPts[aDim] = *std::max_element (aProjectedVerts, aProjectedVerts + ClipVerticesNB);
+ myMinOrthoProjectionPts[aDim] = *std::min_element (aProjectedVerts, aProjectedVerts + ClipVerticesNB);
+ }
+}
+
+// =======================================================================
+// function : Intersect
+// purpose : Detects if AABB overlaps view volume using separating axis theorem (SAT)
+// =======================================================================
+Standard_Boolean OpenGl_BVHTreeSelector::Intersect (const OpenGl_Vec4& theMinPt,
+ const OpenGl_Vec4& theMaxPt) const
+{
+ // E1
+ // |_ E0
+ // /
+ // E2
+ const OpenGl_Vec4 aShiftedBoxMax = theMaxPt - theMinPt;
+ Standard_ShortReal aBoxProjMax = 0.0f, aBoxProjMin = 0.0f;
+ Standard_ShortReal aFrustumProjMax = 0.0f, aFrustumProjMin = 0.0f;
+
+ // E0 test
+ aBoxProjMax = aShiftedBoxMax.x();
+ aFrustumProjMax = myMaxOrthoProjectionPts[0] - DotProduct (OpenGl_Vec4 (1.0f, 0.0f, 0.0f, 1.0f), theMinPt);
+ aFrustumProjMin = myMinOrthoProjectionPts[0] - DotProduct (OpenGl_Vec4 (1.0f, 0.0f, 0.0f, 1.0f), theMinPt);
+ if (aBoxProjMin > aFrustumProjMax
+ || aBoxProjMax < aFrustumProjMin)
+ {
+ return Standard_False;
+ }
+
+ // E1 test
+ aBoxProjMax = aShiftedBoxMax.y();
+ aFrustumProjMax = myMaxOrthoProjectionPts[1] - DotProduct (OpenGl_Vec4 (0.0f, 1.0f, 0.0f, 1.0f), theMinPt);
+ aFrustumProjMin = myMinOrthoProjectionPts[1] - DotProduct (OpenGl_Vec4 (0.0f, 1.0f, 0.0f, 1.0f), theMinPt);
+ if (aBoxProjMin > aFrustumProjMax
+ || aBoxProjMax < aFrustumProjMin)
+ {
+ return Standard_False;
+ }
+
+ // E2 test
+ aBoxProjMax = aShiftedBoxMax.z();
+ aFrustumProjMax = myMaxOrthoProjectionPts[2] - DotProduct (OpenGl_Vec4 (0.0f, 0.0f, 1.0f, 1.0f), theMinPt);
+ aFrustumProjMin = myMinOrthoProjectionPts[2] - DotProduct (OpenGl_Vec4 (0.0f, 0.0f, 1.0f, 1.0f), theMinPt);
+ if (aBoxProjMin > aFrustumProjMax
+ || aBoxProjMax < aFrustumProjMin)
+ {
+ return Standard_False;
+ }
+
+ const Standard_Integer anIncFactor = myIsProjectionParallel ? 2 : 1;
+ for (Standard_Integer aPlaneIter = 0; aPlaneIter < 5; aPlaneIter += anIncFactor)
+ {
+ OpenGl_Vec4 aPlane = myClipPlanes[aPlaneIter];
+ OpenGl_Vec4 aPt1 (0.0f), aPt2 (0.0f);
+ aPt1 = BinarySign (aPlane) * aShiftedBoxMax;
+ aBoxProjMax = DotProduct (aPlane, aPt1);
+ aFrustumProjMax = myMaxClipProjectionPts[aPlaneIter] - DotProduct (aPlane, theMinPt);
+ aFrustumProjMin = myMinClipProjectionPts[aPlaneIter] - DotProduct (aPlane, theMinPt);
+ if (aFrustumProjMin < aBoxProjMax
+ && aBoxProjMax < aFrustumProjMax)
+ {
+ continue;
+ }
+
+ aPt2 = InversedBinarySign (aPlane) * aShiftedBoxMax;
+ aBoxProjMin = DotProduct (aPlane, aPt2);
+ if (aBoxProjMin > aFrustumProjMax
+ || aBoxProjMax < aFrustumProjMin)
+ {
+ return Standard_False;
+ }
+ }
+
+ return Standard_True;
+}
--- /dev/null
+// Created on: 2013-12-25
+// Created by: Varvara POSKONINA
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _OpenGl_BVHTreeSelector_HeaderFile
+#define _OpenGl_BVHTreeSelector_HeaderFile
+
+#include <Graphic3d_Camera.hxx>
+
+#include <OpenGl_Vec.hxx>
+
+//! BVHTreeSelector class provides a possibility to store parameters of view volume,
+//! such as its vertices and equations, and contains methods detecting if given AABB overlaps
+//! view volume.
+class OpenGl_BVHTreeSelector
+{
+public:
+
+ //! Creates an empty selector object with parallel projection type by default.
+ Standard_EXPORT OpenGl_BVHTreeSelector();
+
+ //! Retrieves view volume's planes equations and its vertices from projection and modelview matrices.
+ Standard_EXPORT void SetViewVolume (const Handle(Graphic3d_Camera)& theCamera);
+
+ //! Detects if AABB overlaps view volume using separating axis theorem (SAT).
+ //! @param theMinPt [in] maximum point of AABB.
+ //! @param theMaxPt [in] minimum point of AABB.
+ //! @return Standard_True, if AABB is in viewing area, Standard_False otherwise.
+ Standard_EXPORT Standard_Boolean Intersect (const OpenGl_Vec4& theMinPt,
+ const OpenGl_Vec4& theMaxPt) const;
+
+ //! Caches view volume's vertices projections along its normals and AABBs dimensions.
+ //! Must be called at the beginning of each BVH tree traverse loop.
+ Standard_EXPORT void CacheClipPtsProjections();
+
+ //! Returnes the state of projection matrix previously saved in selector.
+ Standard_EXPORT const Standard_Size ProjectionState() { return myProjectionState; }
+
+ //! Returnes the link for changing the state of projection matrix.
+ Standard_EXPORT Standard_Size& ChangeProjectionState() { return myProjectionState; }
+
+ //! Returnes the state of model view matrix previously saved in selector.
+ Standard_EXPORT const Standard_Size ModelViewState() { return myModelViewState; }
+
+ //! Returnes the link for changing the state of model view matrix.
+ Standard_EXPORT Standard_Size& ChangeModelViewState() { return myModelViewState; }
+
+protected:
+
+ //! Calculates signed distance from plane to point.
+ //! @param theNormal [in] the plane's normal.
+ //! @param thePnt [in]
+ Standard_EXPORT Standard_ShortReal SignedPlanePointDistance (const OpenGl_Vec4& theNormal,
+ const OpenGl_Vec4& thePnt);
+
+protected:
+
+ //! Enumerates planes of view volume.
+ enum
+ {
+ Plane_Top,
+ Plane_Bottom,
+ Plane_Left,
+ Plane_Right,
+ Plane_Near,
+ Plane_Far,
+ PlanesNB
+ };
+
+ //! Enumerates vertices of view volume.
+ enum
+ {
+ ClipVert_LeftTopNear,
+ ClipVert_LeftBottomNear,
+ ClipVert_RightTopNear,
+ ClipVert_RightBottomNear,
+ ClipVert_LeftTopFar,
+ ClipVert_LeftBottomFar,
+ ClipVert_RightTopFar,
+ ClipVert_RightBottomFar,
+ ClipVerticesNB
+ };
+
+protected:
+
+ OpenGl_Vec4 myClipPlanes[PlanesNB]; //!< Plane equations
+ OpenGl_Vec4 myClipVerts[ClipVerticesNB]; //!< Vertices
+
+ // for caching clip points projections onto viewing area normals once per traverse
+ // ORDER: TOP, BOTTOM, LEFT, RIGHT, NEAR, FAR
+ Standard_ShortReal myMaxClipProjectionPts[PlanesNB]; //!< Max view volume's vertices projections onto its normals
+ Standard_ShortReal myMinClipProjectionPts[PlanesNB]; //!< Min view volume's vertices projections onto its normals
+
+ // for caching clip points projections onto AABB normals once per traverse
+ // ORDER: E0, E1, E2
+ Standard_ShortReal myMaxOrthoProjectionPts[3]; //!< Max view volume's vertices projections onto normalized dimensions of AABB
+ Standard_ShortReal myMinOrthoProjectionPts[3]; //!< Min view volume's vertices projections onto normalized dimensions of AABB
+
+ Standard_Boolean myIsProjectionParallel;
+
+ Standard_Size myProjectionState; //! Caches the state of projection matrix to prevent unnecessary updates.
+ Standard_Size myModelViewState; //! Caches the state of model view matrix to prevent unnecessary updates.
+
+};
+
+#endif // _OpenGl_BVHTreeSelector_HeaderFile
const Standard_Integer theLayerId,
const Graphic3d_ZLayerSettings& theSettings);
+ //! Changes priority of a structure within its Z layer for the specified view.
+ Standard_EXPORT void ChangePriority (const Graphic3d_CStructure& theCStructure,
+ const Graphic3d_CView& theCView,
+ const Standard_Integer theNewPriority);
+
public:
//! @return the visualization options
//! Could return NULL-handle if no window created by this driver.
Standard_EXPORT const Handle(OpenGl_Context)& GetSharedContext() const;
+ //! Marks BVH tree for given priority list as dirty and
+ //! marks primitive set for rebuild.
+ Standard_EXPORT void InvalidateBVHData (Graphic3d_CView& theCView, const Standard_Integer theLayerId);
+
public:
DEFINE_STANDARD_RTTI(OpenGl_GraphicDriver)
aStruct->SetZLayer (0);
}
}
+
+//=======================================================================
+//function : ChangePriority
+//purpose :
+//=======================================================================
+void OpenGl_GraphicDriver::ChangePriority (const Graphic3d_CStructure& theCStructure,
+ const Graphic3d_CView& theCView,
+ const Standard_Integer theNewPriority)
+{
+ const OpenGl_CView *aCView = (const OpenGl_CView *)theCView.ptrView;
+
+ if (!myMapOfStructure.IsBound (theCStructure.Id) || !aCView)
+ return;
+
+ OpenGl_Structure* aStructure = myMapOfStructure.Find (theCStructure.Id);
+
+ aCView->View->ChangePriority (aStructure, theNewPriority);
+}
aCView->WS->UseTransparency(AFlag);
}
+// =======================================================================
+// function : InvalidateBVHData
+// purpose :
+// =======================================================================
+void OpenGl_GraphicDriver::InvalidateBVHData (Graphic3d_CView& theCView, const Standard_Integer theLayerId)
+{
+ OpenGl_CView *aCView = (OpenGl_CView *)theCView.ptrView;
+ if(aCView)
+ {
+ aCView->View->InvalidateBVHData (theLayerId);
+ }
+}
+
Standard_Boolean OpenGl_GraphicDriver::View (Graphic3d_CView& theCView)
{
if (myMapOfView.IsBound (theCView.ViewId)
void OpenGl_LayerList::AddStructure (const OpenGl_Structure *theStructure,
const Standard_Integer theLayerId,
- const Standard_Integer thePriority)
+ const Standard_Integer thePriority,
+ Standard_Boolean isForChangePriority)
{
// add structure to associated layer,
// if layer doesn't exists, display structure in default layer
OpenGl_PriorityList& aList = !HasLayer (theLayerId) ? defaultLayer ().PriorityList() :
myLayers.ChangeValue (myLayerIds.Find (theLayerId)).PriorityList();
- aList.Add (theStructure, thePriority);
+ aList.Add (theStructure, thePriority, isForChangePriority);
myNbStructures++;
// Note: In ray-tracing mode we don't modify modification
}
}
+//=======================================================================
+//function : InvalidateBVHData
+//purpose :
+//=======================================================================
+void OpenGl_LayerList::InvalidateBVHData (const Standard_Integer theLayerId)
+{
+ Standard_Integer aSeqPos = !HasLayer (theLayerId) ?
+ 1 : myLayerIds.Find (theLayerId);
+
+ OpenGl_PriorityList& aList = myLayers.ChangeValue (aSeqPos).PriorityList();
+
+ aList.InvalidateBVHData();
+}
+
//=======================================================================
//function : ChangeLayer
//purpose :
// take priority and remove structure from list found by <theOldLayerId>
// if the structure is not found there, scan through all other layers
- if ((aPriority = aList.Remove (theStructure)) >= 0)
+ if ((aPriority = aList.Remove (theStructure, Standard_True)) >= 0)
{
myNbStructures--;
- AddStructure (theStructure, theNewLayerId, aPriority);
+ AddStructure (theStructure, theNewLayerId, aPriority, Standard_True);
}
else
{
continue;
// try to remove structure and get priority value from this layer
- if ((aPriority = aList.Remove (theStructure)) >= 0)
+ if ((aPriority = aList.Remove (theStructure, Standard_True)) >= 0)
+ {
+ myNbStructures--;
+ AddStructure (theStructure, theNewLayerId, aPriority, Standard_True);
+ break;
+ }
+ }
+ }
+}
+
+//=======================================================================
+//function : ChangePriority
+//purpose :
+//=======================================================================
+void OpenGl_LayerList::ChangePriority (const OpenGl_Structure *theStructure,
+ const Standard_Integer theLayerId,
+ const Standard_Integer theNewPriority)
+{
+ Standard_Integer aSeqPos = !HasLayer (theLayerId) ?
+ 1 : myLayerIds.Find (theLayerId);
+
+ OpenGl_PriorityList& aList = myLayers.ChangeValue (aSeqPos).PriorityList();
+
+ if (aList.Remove (theStructure, Standard_True) >= 0)
+ {
+ myNbStructures--;
+ AddStructure (theStructure, theLayerId, theNewPriority, Standard_True);
+ }
+ else
+ {
+ Standard_Integer aSeqId = 1;
+ OpenGl_SequenceOfLayers::Iterator anIts;
+ for (anIts.Init (myLayers); anIts.More (); anIts.Next (), aSeqId++)
+ {
+ if (aSeqPos == aSeqId)
+ continue;
+
+ if (aList.Remove (theStructure, Standard_True) >= 0)
{
myNbStructures--;
- AddStructure (theStructure, theNewLayerId, aPriority);
+ AddStructure (theStructure, theLayerId, theNewPriority, Standard_True);
break;
}
}
//! to default bottom-level layer.
void AddStructure (const OpenGl_Structure *theStructure,
const Standard_Integer theLayerId,
- const Standard_Integer thePriority);
+ const Standard_Integer thePriority,
+ Standard_Boolean isForChangePriority = Standard_False);
//! Remove structure from structure list and return its previous priority
void RemoveStructure (const OpenGl_Structure *theStructure,
const Standard_Integer theOldLayerId,
const Standard_Integer theNewLayerId);
+ //! Changes structure priority within its ZLayer
+ void ChangePriority (const OpenGl_Structure *theStructure,
+ const Standard_Integer theLayerId,
+ const Standard_Integer theNewPriority);
+
//! Returns reference to the layer with given ID.
OpenGl_Layer& Layer (const Standard_Integer theLayerId);
//! Returns the set of OpenGL Z-layers.
const OpenGl_SequenceOfLayers& Layers() const { return myLayers; }
+ //! Marks BVH tree for given priority list as dirty and
+ //! marks primitive set for rebuild.
+ void InvalidateBVHData (const Standard_Integer theLayerId);
+
//! Returns structure modification state (for ray-tracing).
Standard_Size ModificationState() const { return myModificationState; }
#include <OpenGl_PriorityList.hxx>
+#include <OpenGl_BVHTreeSelector.hxx>
#include <OpenGl_Structure.hxx>
+#include <OpenGl_View.hxx>
-/*----------------------------------------------------------------------*/
+// =======================================================================
+// function : OpenGl_PriorityList
+// purpose :
+// =======================================================================
+OpenGl_PriorityList::OpenGl_PriorityList (const Standard_Integer theNbPriorities)
+: myArray (0, theNbPriorities - 1),
+ myNbStructures (0),
+ myBVHIsLeftChildQueuedFirst (Standard_True),
+ myIsBVHPrimitivesNeedsReset (Standard_False)
+{
+ //
+}
-void OpenGl_PriorityList::Add (const OpenGl_Structure *AStructure,const Standard_Integer APriority)
+// =======================================================================
+// function : ~OpenGl_PriorityList
+// purpose :
+// =======================================================================
+OpenGl_PriorityList::~OpenGl_PriorityList()
{
- Standard_Integer anIndex = APriority;
- if (anIndex < 0) anIndex = 0;
- else if (anIndex >= myArray.Length()) anIndex = myArray.Length()-1;
- myArray(anIndex).Append(AStructure);
- myNbStructures++;
+ //
}
-/*----------------------------------------------------------------------*/
+// =======================================================================
+// function : Add
+// purpose :
+// =======================================================================
+void OpenGl_PriorityList::Add (const OpenGl_Structure* theStructure,
+ const Standard_Integer thePriority,
+ Standard_Boolean isForChangePriority)
+{
+ const Standard_Integer anIndex = Min (Max (thePriority, 0), myArray.Length() - 1);
-Standard_Integer OpenGl_PriorityList::Remove (const OpenGl_Structure *AStructure)
+ myArray (anIndex).Append (theStructure);
+ if (theStructure->IsAlwaysRendered())
+ {
+ theStructure->MarkAsNotCulled();
+ }
+ else if (!isForChangePriority)
+ {
+ myBVHPrimitives.Add (theStructure);
+ }
+ ++myNbStructures;
+}
+
+// =======================================================================
+// function : Remove
+// purpose :
+// =======================================================================
+Standard_Integer OpenGl_PriorityList::Remove (const OpenGl_Structure* theStructure,
+ Standard_Boolean isForChangePriority)
{
- const Standard_Integer aNbPr = myArray.Length();
- Standard_Integer i = 0;
- OpenGl_SequenceOfStructure::Iterator its;
- for (; i < aNbPr; i++)
+ const Standard_Integer aNbPriorities = myArray.Length();
+ OpenGl_SequenceOfStructure::Iterator aStructIter;
+ for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
{
- OpenGl_SequenceOfStructure &aSeq = myArray(i);
- for (its.Init(aSeq); its.More(); its.Next())
+ OpenGl_SequenceOfStructure& aSeq = myArray (aPriorityIter);
+ for (aStructIter.Init (aSeq); aStructIter.More(); aStructIter.Next())
{
- if (its.Value() == AStructure)
+ if (aStructIter.Value() == theStructure)
{
- aSeq.Remove(its);
- myNbStructures--;
- return i;
+ aSeq.Remove (aStructIter);
+ if (!theStructure->IsAlwaysRendered()
+ && !isForChangePriority)
+ {
+ myBVHPrimitives.Remove (theStructure);
+ }
+ --myNbStructures;
+ return aPriorityIter;
}
}
}
return -1;
}
-/*----------------------------------------------------------------------*/
+// =======================================================================
+// function : InvalidateBVHData
+// purpose :
+// =======================================================================
+void OpenGl_PriorityList::InvalidateBVHData()
+{
+ myIsBVHPrimitivesNeedsReset = Standard_True;
+}
-void OpenGl_PriorityList::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
+// =======================================================================
+// function : Render
+// purpose :
+// =======================================================================
+void OpenGl_PriorityList::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
{
- const Standard_Integer aNbPr = myArray.Length();
- Standard_Integer i = 0;
- OpenGl_SequenceOfStructure::Iterator its;
- for (; i < aNbPr; i++)
+ theWorkspace->IsCullingEnabled() ? renderTraverse (theWorkspace) : renderAll (theWorkspace);
+}
+
+// =======================================================================
+// function : renderAll
+// purpose :
+// =======================================================================
+void OpenGl_PriorityList::renderAll (const Handle(OpenGl_Workspace)& theWorkspace) const
+{
+ const Standard_Integer aNbPriorities = myArray.Length();
+ OpenGl_SequenceOfStructure::Iterator aStructIter;
+ for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
{
- for (its.Init(myArray(i)); its.More(); its.Next())
- its.Value()->Render(AWorkspace);
+ for (aStructIter.Init (myArray (aPriorityIter)); aStructIter.More(); aStructIter.Next())
+ {
+ aStructIter.Value()->Render (theWorkspace);
+ }
}
}
-//=======================================================================
-//function : Append
-//purpose :
-//=======================================================================
+// =======================================================================
+// function : renderTraverse
+// purpose :
+// =======================================================================
+void OpenGl_PriorityList::renderTraverse (const Handle(OpenGl_Workspace)& theWorkspace) const
+{
+ if (myIsBVHPrimitivesNeedsReset)
+ {
+ myBVHPrimitives.Assign (myArray);
+ myIsBVHPrimitivesNeedsReset = Standard_False;
+ }
+
+ OpenGl_BVHTreeSelector& aSelector = theWorkspace->ActiveView()->BVHTreeSelector();
+ traverse (aSelector);
+
+ const Standard_Integer aNbPriorities = myArray.Length();
+ OpenGl_SequenceOfStructure::Iterator aStructIter;
+ for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
+ {
+ for (aStructIter.Init (myArray (aPriorityIter)); aStructIter.More(); aStructIter.Next())
+ {
+ if (!aStructIter.Value()->IsCulled())
+ {
+ aStructIter.Value()->Render (theWorkspace);
+ aStructIter.Value()->ResetCullingStatus();
+ }
+ }
+ }
+}
+// =======================================================================
+// function : traverse
+// purpose :
+// =======================================================================
+void OpenGl_PriorityList::traverse (OpenGl_BVHTreeSelector& theSelector) const
+{
+ // handle a case when all objects are infinite
+ if (myBVHPrimitives.Size() == 0)
+ return;
+
+ const NCollection_Handle<BVH_Tree<Standard_ShortReal, 4> >& aBVHTree = myBVHPrimitives.BVH();
+
+ Standard_Integer aNode = 0; // a root node
+ theSelector.CacheClipPtsProjections();
+ if (!theSelector.Intersect (aBVHTree->MinPoint (0),
+ aBVHTree->MaxPoint (0)))
+ {
+ return;
+ }
+
+ Standard_Integer aStack[32];
+ Standard_Integer aHead = -1;
+ for (;;)
+ {
+ if (!aBVHTree->IsOuter (aNode))
+ {
+ const Standard_Integer aLeftChildIdx = aBVHTree->LeftChild (aNode);
+ const Standard_Integer aRightChildIdx = aBVHTree->RightChild (aNode);
+ const Standard_Boolean isLeftChildIn = theSelector.Intersect (aBVHTree->MinPoint (aLeftChildIdx),
+ aBVHTree->MaxPoint (aLeftChildIdx));
+ const Standard_Boolean isRightChildIn = theSelector.Intersect (aBVHTree->MinPoint (aRightChildIdx),
+ aBVHTree->MaxPoint (aRightChildIdx));
+ if (isLeftChildIn
+ && isRightChildIn)
+ {
+ aNode = myBVHIsLeftChildQueuedFirst ? aLeftChildIdx : aRightChildIdx;
+ ++aHead;
+ aStack[aHead] = myBVHIsLeftChildQueuedFirst ? aRightChildIdx : aLeftChildIdx;
+ myBVHIsLeftChildQueuedFirst = !myBVHIsLeftChildQueuedFirst;
+ }
+ else if (isLeftChildIn
+ || isRightChildIn)
+ {
+ aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
+ }
+ else
+ {
+ if (aHead < 0)
+ {
+ return;
+ }
+
+ aNode = aStack[aHead];
+ --aHead;
+ }
+ }
+ else
+ {
+ if (theSelector.Intersect (aBVHTree->MinPoint (aNode),
+ aBVHTree->MaxPoint (aNode)))
+ {
+ Standard_Integer aIdx = aBVHTree->BegPrimitive (aNode);
+ myBVHPrimitives.GetStructureById (aIdx)->MarkAsNotCulled();
+ if (aHead < 0)
+ {
+ return;
+ }
+
+ aNode = aStack[aHead];
+ --aHead;
+ }
+ }
+ }
+}
+
+// =======================================================================
+// function : Append
+// purpose :
+// =======================================================================
Standard_Boolean OpenGl_PriorityList::Append (const OpenGl_PriorityList& theOther)
{
// the source priority list shouldn't have more priorities
const Standard_Integer aNbPriorities = theOther.NbPriorities ();
- if (aNbPriorities > NbPriorities ())
+ if (aNbPriorities > NbPriorities())
+ {
return Standard_False;
+ }
// add all structures to destination priority list
- Standard_Integer aIdx = 0;
- OpenGl_SequenceOfStructure::Iterator anIts;
- for (; aIdx < aNbPriorities; aIdx++)
+ OpenGl_SequenceOfStructure::Iterator aStructIter;
+ for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
{
- const OpenGl_SequenceOfStructure& aSeq = theOther.myArray (aIdx);
- for (anIts.Init (aSeq); anIts.More (); anIts.Next ())
- Add (anIts.Value (), aIdx);
+ const OpenGl_SequenceOfStructure& aSeq = theOther.myArray (aPriorityIter);
+ for (aStructIter.Init (aSeq); aStructIter.More(); aStructIter.Next())
+ {
+ Add (aStructIter.Value(), aPriorityIter);
+ }
}
return Standard_True;
}
-//=======================================================================
-//function : NbPriorities
-//purpose :
-//=======================================================================
-
+// =======================================================================
+// function : NbPriorities
+// purpose :
+// =======================================================================
Standard_Integer OpenGl_PriorityList::NbPriorities() const
{
return myArray.Length();
#include <InterfaceGraphic_telem.hxx>
#include <Handle_OpenGl_Workspace.hxx>
+#include <OpenGl_BVHClipPrimitiveSet.hxx>
+#include <OpenGl_BVHTreeSelector.hxx>
class OpenGl_Structure;
class OpenGl_PriorityList
{
- public:
+public:
- OpenGl_PriorityList (const Standard_Integer ANbPriorities = 11) : myArray(0,(ANbPriorities-1)), myNbStructures(0) {}
+ // Empty constructor.
+ OpenGl_PriorityList (const Standard_Integer theNbPriorities = 11);
- virtual ~OpenGl_PriorityList () {}
+ //! Destructor.
+ virtual ~OpenGl_PriorityList();
- void Add (const OpenGl_Structure *AStructure, const Standard_Integer APriority);
+ void Add (const OpenGl_Structure* theStructure,
+ const Standard_Integer thePriority,
+ Standard_Boolean isForChangePriority = Standard_False);
- //! Remove structure and returns its priority, if the structure is not found,
- //! method returns negative value
- Standard_Integer Remove (const OpenGl_Structure *AStructure);
+ //! Remove structure and returns its priority, if the structure is not found, method returns negative value
+ Standard_Integer Remove (const OpenGl_Structure* theStructure,
+ Standard_Boolean isForChangePriority = Standard_False);
- Standard_Integer NbStructures () const { return myNbStructures; }
+ //! @return the number of structures
+ Standard_Integer NbStructures() const { return myNbStructures; }
- void Render (const Handle(OpenGl_Workspace) &AWorkspace) const;
+ // Render all structures.
+ void Render (const Handle(OpenGl_Workspace)& theWorkspace) const;
//! Returns the number of available priority levels
Standard_Integer NbPriorities() const;
//! Returns array of OpenGL structures.
const OpenGl_ArrayOfStructure& ArrayOfStructures() const { return myArray; }
- protected:
+ //! Marks BVH tree for given priority list as dirty and
+ //! marks primitive set for rebuild.
+ void InvalidateBVHData();
- OpenGl_ArrayOfStructure myArray;
- Standard_Integer myNbStructures;
+protected:
+
+ //! Traverses through BVH tree to determine which structures are in view volume.
+ void traverse (OpenGl_BVHTreeSelector& theSelector) const;
+
+ //! Iterates through the hierarchical list of existing structures and renders them all.
+ void renderAll (const Handle(OpenGl_Workspace)& theWorkspace) const;
+
+ //! Iterates through the hierarchical list of existing structures and renders only overlapping ones.
+ void renderTraverse (const Handle(OpenGl_Workspace)& theWorkspace) const;
+
+protected:
+
+ OpenGl_ArrayOfStructure myArray;
+ Standard_Integer myNbStructures;
+ mutable OpenGl_BVHClipPrimitiveSet myBVHPrimitives; //<! Set of OpenGl_Structures for building BVH tree
+ mutable Standard_Boolean myBVHIsLeftChildQueuedFirst; //<! Is needed for implementation of stochastic order of BVH traverse
+ mutable Standard_Boolean myIsBVHPrimitivesNeedsReset; //<! Defines if the primitive set for BVH is outdated
+
+public:
- public:
DEFINE_STANDARD_ALLOC
+
};
-#endif //_OpenGl_PriorityList_Header
+#endif // _OpenGl_PriorityList_Header
#ifdef HAVE_TBB
// On Windows, function TryEnterCriticalSection has appeared in Windows NT
// and is surrounded by #ifdef in MS VC++ 7.1 headers.
- // Thus to use it we need to define appropriate macro saying that we wil
+ // Thus to use it we need to define appropriate macro saying that we will
// run on Windows NT 4.0 at least
- #if ((defined(_WIN32) || defined(__WIN32__)) && !defined(_WIN32_WINNT))
+ #if defined(_WIN32) && !defined(_WIN32_WINNT)
#define _WIN32_WINNT 0x0501
#endif
#include <OpenGl_SceneGeometry.hxx>
+#include <OpenGl_PrimitiveArray.hxx>
+#include <OpenGl_Structure.hxx>
+
//! Use this macro to output BVH profiling info
//#define BVH_PRINT_INFO
#include <BVH_Geometry.hxx>
#include <BVH_Triangulation.hxx>
#include <NCollection_StdAllocator.hxx>
-#include <OpenGl_PrimitiveArray.hxx>
-#include <OpenGl_Structure.hxx>
+
+struct OpenGl_ElementNode;
+class OpenGl_Group;
+class OpenGl_Structure;
+class OpenGl_PrimitiveArray;
namespace OpenGl_Raytrace
{
public:
//! Main constructor
- OpenGl_BndBoxPrs (const CALL_DEF_BOUNDBOX& theBndBox)
- {
- const float Xm = theBndBox.Pmin.x;
- const float Ym = theBndBox.Pmin.y;
- const float Zm = theBndBox.Pmin.z;
- const float XM = theBndBox.Pmax.x;
- const float YM = theBndBox.Pmax.y;
- const float ZM = theBndBox.Pmax.z;
+ OpenGl_BndBoxPrs (const Graphic3d_BndBox4f& theBndBox)
+ {
+ const float Xm = theBndBox.CornerMin().x();
+ const float Ym = theBndBox.CornerMin().y();
+ const float Zm = theBndBox.CornerMin().z();
+ const float XM = theBndBox.CornerMax().x();
+ const float YM = theBndBox.CornerMax().y();
+ const float ZM = theBndBox.CornerMax().z();
+
myVerts[0] = OpenGl_Vec3 (Xm, Ym, Zm);
myVerts[1] = OpenGl_Vec3 (Xm, Ym, ZM);
myVerts[2] = OpenGl_Vec3 (Xm, YM, ZM);
myNamedStatus(0),
myZLayer(0),
myIsRaytracable (Standard_False),
- myModificationState (0)
+ myModificationState (0),
+ myIsCulled (Standard_True)
{
UpdateNamedStatus();
}
myTransPers->pointX = ATransPers.Point.x;
myTransPers->pointY = ATransPers.Point.y;
myTransPers->pointZ = ATransPers.Point.z;
+ MarkAsNotCulled();
}
// =======================================================================
CALL_DEF_CONTEXTLINE& aContextLine = myHighlightBox->ChangeContextLine();
aContextLine.IsDef = 1;
- aContextLine.Color = BoundBox.Color;
+ aContextLine.Color = HighlightColor;
aContextLine.LineType = Aspect_TOL_SOLID;
aContextLine.Width = 1.0f;
myHighlightBox->UpdateAspectLine (Standard_True);
- OpenGl_BndBoxPrs* aBndBoxPrs = new OpenGl_BndBoxPrs (BoundBox);
+ OpenGl_BndBoxPrs* aBndBoxPrs = new OpenGl_BndBoxPrs (myBndBox);
myHighlightBox->AddElement (aBndBoxPrs);
}
UpdateStateWithAncestorStructures();
UpdateRaytracableWithAncestorStructures();
}
+
+ Is2dText = Standard_False;
+ IsForHighlight = Standard_False;
}
// =======================================================================
if ( myNamedStatus & OPENGL_NS_HIDE )
return;
+ const Handle(OpenGl_Context)& aCtx = AWorkspace->GetGlContext();
+
// Render named status
const Standard_Integer named_status = AWorkspace->NamedStatus;
AWorkspace->NamedStatus |= myNamedStatus;
// Is rendering in ADD or IMMEDIATE mode?
const Standard_Boolean isImmediate = (AWorkspace->NamedStatus & OPENGL_NS_IMMEDIATE) != 0;
- const Handle(OpenGl_Context)& aCtx = AWorkspace->GetGlContext();
-
// Apply local transformation
GLint matrix_mode = 0;
const OpenGl_Matrix *local_trsf = NULL;
if (myAspectText)
AWorkspace->SetAspectText(myAspectText);
- // Apply highlight box
- if (!myHighlightBox.IsNull())
- {
- myHighlightBox->Render (AWorkspace);
- }
-
// Apply highlight color
const TEL_COLOUR *highlight_color = AWorkspace->HighlightColor;
if (myHighlightColor)
}
}
+ // Apply highlight box
+ if (!myHighlightBox.IsNull())
+ {
+ myHighlightBox->Render (AWorkspace);
+ }
+
// Restore named status
AWorkspace->NamedStatus = named_status;
}
return myZLayer;
}
+//! Dummy structure which just redirects to groups of another structure.
class OpenGl_StructureShadow : public OpenGl_Structure
{
IMPLEMENT_STANDARD_HANDLE (OpenGl_StructureShadow, OpenGl_Structure)
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_StructureShadow, OpenGl_Structure)
+//=======================================================================
+//function : OpenGl_StructureShadow
+//purpose :
+//=======================================================================
OpenGl_StructureShadow::OpenGl_StructureShadow (const Handle(Graphic3d_StructureManager)& theManager,
const Handle(OpenGl_Structure)& theStructure)
: OpenGl_Structure (theManager)
#include <OpenGl_Group.hxx>
#include <OpenGl_Matrix.hxx>
#include <OpenGl_NamedStatus.hxx>
+#include <OpenGl_Vec.hxx>
+#include <OpenGl_Workspace.hxx>
#include <NCollection_List.hxx>
#include <InterfaceGraphic_Graphic3d.hxx>
virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const;
virtual void Release (const Handle(OpenGl_Context)& theGlCtx);
+ //! Marks structure as not overlapping view volume (as it is by default).
+ void ResetCullingStatus() const
+ {
+ if (!IsAlwaysRendered())
+ {
+ myIsCulled = Standard_True;
+ }
+ }
+
+ //! Marks structure as overlapping the current view volume one.
+ //! The method is called during traverse of BVH tree.
+ void MarkAsNotCulled() const { myIsCulled = Standard_False; }
+
+ //! Returns Standard_False if the structure hits the current view volume, otherwise
+ //! returns Standard_True. The default value for all structures before each traverse
+ //! of BVH tree is Standard_True.
+ Standard_Boolean IsCulled() const { return myIsCulled; }
+
+ //! Checks if the structure should be included into BVH tree or not.
+ const Standard_Boolean IsAlwaysRendered() const
+ {
+ return IsInfinite
+ || IsForHighlight
+ || IsMutable
+ || Is2dText
+ || TransformPersistence.Flag != 0;
+ }
+
//! This method releases GL resources without actual elements destruction.
//! As result structure could be correctly destroyed layer without GL context
//! (after last window was closed for example).
mutable Standard_Boolean myIsRaytracable;
mutable Standard_Size myModificationState;
+ mutable Standard_Boolean myIsCulled; //!< A status specifying is structure needs to be rendered after BVH tree traverse.
+
public:
DEFINE_STANDARD_RTTI(OpenGl_Structure) // Type definition
#include <Graphic3d_ZLayerSettings.hxx>
#include <Visual3d_TypeOfSurfaceDetail.hxx>
+#include <OpenGl_BVHTreeSelector.hxx>
#include <OpenGl_LayerList.hxx>
#include <OpenGl_Light.hxx>
#include <OpenGl_LineAttributes.hxx>
void SetZLayerSettings (const Standard_Integer theLayerId,
const Graphic3d_ZLayerSettings theSettings);
+ //! Changes the priority of a structure within its ZLayer
+ void ChangePriority (const OpenGl_Structure *theStructure,
+ const Standard_Integer theNewPriority);
+
void CreateBackgroundTexture (const Standard_CString AFileName, const Aspect_FillMethod AFillStyle);
void SetBackgroundTextureStyle (const Aspect_FillMethod FillStyle);
void SetBackgroundGradient (const Quantity_Color& AColor1, const Quantity_Color& AColor2, const Aspect_GradientFillMethod AType);
//! Returns visualization mode for objects in the view.
Visual3d_TypeOfSurfaceDetail SurfaceDetail() const { return mySurfaceDetail; }
+ //! Returns selector for BVH tree, providing a possibility to store information
+ //! about current view volume and to detect which objects are overlapping it.
+ OpenGl_BVHTreeSelector& BVHTreeSelector() { return myBVHSelector; }
+
+ //! Marks BVH tree for given priority list as dirty and
+ //! marks primitive set for rebuild.
+ void InvalidateBVHData (const Standard_Integer theLayerId);
+
void GetMatrices (TColStd_Array2OfReal& theMatOrient,
TColStd_Array2OfReal& theMatMapping) const;
StateInfo myLastViewMappingState;
StateInfo myLastLightSourceState;
+ //! Is needed for selection of overlapping objects and storage of the current view volume
+ OpenGl_BVHTreeSelector myBVHSelector;
+
Standard_Size myModificationState;
public:
}
}
+ Standard_Boolean isProjectionMatUpdateNeeded = Standard_False;
+ Standard_Boolean isOrientationMatUpdateNeeded = Standard_False;
+ if (myBVHSelector.ProjectionState() != myCamera->ProjectionState())
+ {
+ isProjectionMatUpdateNeeded = Standard_True;
+ myBVHSelector.ChangeProjectionState() = myCamera->ProjectionState();
+ }
+ if (myBVHSelector.ModelViewState() != myCamera->ModelViewState())
+ {
+ isOrientationMatUpdateNeeded = Standard_True;
+ myBVHSelector.ChangeModelViewState() = myCamera->ModelViewState();
+ }
+
// Set OCCT state uniform variables
const Handle(OpenGl_ShaderManager) aManager = aContext->ShaderManager();
if (!aManager->IsEmpty())
}
}
+ if (isProjectionMatUpdateNeeded
+ || isOrientationMatUpdateNeeded)
+ {
+ myBVHSelector.SetViewVolume (myCamera);
+ }
+
// ====================================
// Step 2: Redraw background
// ====================================
}
}
+// =======================================================================
+// function : InvalidateBVHData
+// purpose :
+// =======================================================================
+void OpenGl_View::InvalidateBVHData (const Standard_Integer theLayerId)
+{
+ myZLayers.InvalidateBVHData (theLayerId);
+}
+
/*----------------------------------------------------------------------*/
//ExecuteViewDisplay
myZLayers.Layer (theLayerId).SetLayerSettings (theSettings);
}
+//=======================================================================
+//function : ChangePriority
+//purpose :
+//=======================================================================
+void OpenGl_View::ChangePriority (const OpenGl_Structure *theStructure,
+ const Standard_Integer theNewPriority)
+{
+ Standard_Integer aLayerId = theStructure->GetZLayer();
+ myZLayers.ChangePriority (theStructure, aLayerId, theNewPriority);
+}
//=======================================================================
//function : RedrawScene
myUseZBuffer (Standard_False),
myUseDepthTest (Standard_True),
myUseGLLight (Standard_True),
+ myIsCullingEnabled (Standard_False),
//
AspectLine_set (&myDefaultAspectLine),
AspectLine_applied (NULL),
return;
}
+ myIsCullingEnabled = theCView.IsCullingEnabled;
+
// release pending GL resources
Handle(OpenGl_Context) aGlCtx = GetGlContext();
aGlCtx->ReleaseDelayed();
class OpenGl_AspectText;
class OpenGl_FrameBuffer;
class OpenGl_Structure;
+class OpenGl_TriangleSet;
class OpenGl_Element;
class Image_PixMap;
//! Returns currently applied polygon offset params.
const TEL_POFFSET_PARAM& AppliedPolygonOffset() { return PolygonOffset_applied; }
+ //! @return true if clipping algorithm enabled
+ inline Standard_Boolean IsCullingEnabled() const { return myIsCullingEnabled; }
+
protected:
//! Copy content of Back buffer to the Front buffer
Standard_Boolean myUseZBuffer;
Standard_Boolean myUseDepthTest;
Standard_Boolean myUseGLLight;
+ Standard_Boolean myIsCullingEnabled; //!< frustum culling flag
protected: //! @name fields related to status
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
+#include <OpenGl_Workspace.hxx>
+
#include <NCollection_Mat4.hxx>
#include <OpenGl_ArbFBO.hxx>
#include <OpenGl_FrameBuffer.hxx>
+#include <OpenGl_PrimitiveArray.hxx>
#include <OpenGl_Texture.hxx>
#include <OpenGl_VertexBuffer.hxx>
#include <OpenGl_View.hxx>
-#include <OpenGl_Workspace.hxx>
#include <OSD_File.hxx>
#include <OSD_Protection.hxx>
#include <Standard_Assert.hxx>
---Purpose: displays the whole content of the presentation in the specified color.
BoundBox(me: mutable) is static;
+ SetIsForHighlight (me : mutable;
+ isForHighlight : Boolean from Standard)
+ is virtual;
+ ---Purpose: marks the structure <me> representing wired structure needed for
+ -- highlight only so it won't be added to BVH tree.
+
---Category: Global modification methods.
SetShadingAspect(me: mutable; aShadingAspect: ShadingAspect from Prs3d);
}
//=======================================================================
+//=======================================================================
+//function : SetIsForHighlight
+//purpose :
+//=======================================================================
+void Prs3d_Presentation::SetIsForHighlight (const Standard_Boolean isForHighlight)
+{
+ Graphic3d_Structure::SetIsForHighlight (isForHighlight);
+}
+
//function : Compute
//purpose :
//=======================================================================
---Purpose: Get clip planes.
-- @return set of previously added clip planes for all display mode presentations.
+ SetMutable ( me : mutable;
+ theIsMutable : Boolean from Standard ) is virtual;
+ ---Purpose: Sets if the object has mutable nature (content or location will be changed regularly).
+ -- This method should be called before object displaying to take effect.
+
+ IsMutable (me) returns Boolean from Standard;
+ ---C++: return const
+ ---Purpose: Returns true if object has mutable nature (content or location are be changed regularly).
+ -- Mutable object will be managed in different way than static onces (another optimizations).
+
UpdateClipping (me : mutable) is virtual protected;
---Purpose: General virtual method for internal update of presentation state
-- when some modifications on list of clip planes occurs. Base
myTypeOfPresentation3d: TypeOfPresentation3d from PrsMgr is protected;
myLocation : Location from TopLoc is protected;
myClipPlanes : SequenceOfHClipPlane from Graphic3d is protected;
- --myTransformPersistence : TransModeFlags from Graphic3d;
myTransformPersistence : CTransPersStruct from Graphic3d;
+ myIsMutable : Boolean from Standard is protected;
friends
class Presentation from PrsMgr,
//=======================================================================
//function : PrsMgr_PresentableObject
-//purpose :
+//purpose :
//=======================================================================
-PrsMgr_PresentableObject::PrsMgr_PresentableObject(const PrsMgr_TypeOfPresentation3d aTypeOfPresentation3d)
- :myPresentations(),myTypeOfPresentation3d(aTypeOfPresentation3d)
+PrsMgr_PresentableObject::PrsMgr_PresentableObject (const PrsMgr_TypeOfPresentation3d theType)
+: myTypeOfPresentation3d (theType),
+ myIsMutable (Standard_False)
{
myTransformPersistence.Flag = 0;
myTransformPersistence.Point.x = 0.0;
&& !aPrs3d->Presentation().IsNull())
{
aPrs3d->Presentation()->SetTransformPersistence (theFlag, thePoint);
+ aPrs3d->Presentation()->ReCompute();
}
}
}
aModedPrs.Presentation()->Presentation()->SetClipPlanes (myClipPlanes);
}
}
+
+// =======================================================================
+// function : SetMutable
+// purpose :
+// =======================================================================
+void PrsMgr_PresentableObject::SetMutable (const Standard_Boolean theIsMutable)
+{
+ if (myIsMutable == theIsMutable)
+ {
+ return;
+ }
+
+ myIsMutable = theIsMutable;
+ for (Standard_Integer aPrsIter = 1; aPrsIter <= myPresentations.Length(); ++aPrsIter)
+ {
+ const PrsMgr_ModedPresentation& aModedPrs = myPresentations (aPrsIter);
+ if (aModedPrs.Presentation().IsNull()
+ || aModedPrs.Presentation()->Presentation().IsNull())
+ {
+ continue;
+ }
+
+ aModedPrs.Presentation()->Presentation()->SetMutable (theIsMutable);
+ }
+}
+
+// =======================================================================
+// function : IsMutable
+// purpose :
+// =======================================================================
+const Standard_Boolean PrsMgr_PresentableObject::IsMutable() const
+{
+ return myIsMutable;
+}
myStructure = new PrsMgr_Prs (thePrsMgr->StructureManager(),
this, thePrsObject->TypeOfPresentation3d());
myStructure->SetOwner (myPresentableObject);
+ myStructure->SetMutable (myPresentableObject->IsMutable());
}
//=======================================================================
//function : Display
//purpose :
//=======================================================================
-void PrsMgr_Presentation::Display (const Standard_Boolean /*theIsHighlight*/)
+void PrsMgr_Presentation::Display (const Standard_Boolean theIsHighlight)
{
if (!myStructure->IsDisplayed())
{
+ myStructure->SetIsForHighlight (theIsHighlight);
myStructure->Display();
}
else if (!myStructure->IsVisible())
{
SetVisible (Standard_True);
+ myStructure->SetIsForHighlight (theIsHighlight);
}
}
: (Standard_Integer)Value;
}
+// =======================================================================
+// function : RealToShortReal
+// purpose : Converts Standard_Real value to the nearest valid
+// Standard_ShortReal. If input value is out of valid range
+// for Standard_ShortReal, minimal or maximal
+// Standard_ShortReal is returned.
+// =======================================================================
+inline Standard_ShortReal RealToShortReal (const Standard_Real theVal)
+{
+ return theVal < -FLT_MAX ? -FLT_MAX
+ : theVal > FLT_MAX ? FLT_MAX
+ : (Standard_ShortReal)theVal;
+}
+
//-------------------------------------------------------------------
// Round : Returns the nearest integer of a real
//-------------------------------------------------------------------
---Level: Public
---Purpose: Returns reference to current rendering parameters and effect settings.
+ IsCullingEnabled (me) returns Boolean from Standard is static;
+ ---Level: Public
+ ---Purpose: @return flag value of objects culling mechanism
+
+ SetFrustumCulling (me : mutable; theMode : Boolean from Standard) is static;
+ ---Level: Public
+ ---Purpose: Turn on/off automatic culling of objects outside frustrum (ON by default)
+
fields
myOldMouseX : Real is protected;
theCamera->Transform (aPanTrsf);
}
+
+// =======================================================================
+// function : IsCullingEnabled
+// purpose :
+// =======================================================================
+Standard_Boolean V3d_View::IsCullingEnabled() const
+{
+ Graphic3d_CView* aView = (Graphic3d_CView* )MyView->CView();
+ return aView->IsCullingEnabled;
+}
+
+// =======================================================================
+// function : SetFrustumCulling
+// purpose :
+// =======================================================================
+void V3d_View::SetFrustumCulling (const Standard_Boolean theToClip)
+{
+ Graphic3d_CView* aView = (Graphic3d_CView* )MyView->CView();
+ aView->IsCullingEnabled = theToClip;
+}
ViewerTest_RedrawMode aToUpdate = ViewerTest_RM_Auto;
Standard_Boolean isContextOnly = Standard_False;
Standard_Boolean toRemoveAll = Standard_False;
+ Standard_Boolean toPrintInfo = Standard_True;
Standard_Integer anArgIter = 1;
for (; anArgIter < theArgNb; ++anArgIter)
{
toRemoveAll = Standard_True;
}
+ else if (anArg == "-noinfo")
+ {
+ toPrintInfo = Standard_False;
+ }
else if (!parseRedrawMode (anArg, aToUpdate))
{
break;
anIter.More(); anIter.Next())
{
const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (anIter.Value()));
-
if (!anIO.IsNull())
{
TheAISContext()->Remove (anIO, Standard_False);
- theDI << anIter.Value().ToCString() << " was removed\n";
+ if (toPrintInfo)
+ {
+ theDI << anIter.Value().ToCString() << " was removed\n";
+ }
}
else
{
if (!aNisIO.IsNull())
{
TheNISContext()->Remove (aNisIO);
- theDI << anIter.Value().ToCString() << " was removed\n";
+ if (toPrintInfo)
+ {
+ theDI << anIter.Value().ToCString() << " was removed\n";
+ }
}
}
-
if (!isContextOnly)
{
GetMapOfAIS().UnBind2 (anIter.Value());
}
ViewerTest_RedrawMode aToUpdate = ViewerTest_RM_Auto;
+ Standard_Integer isMutable = -1;
for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
{
- const TCollection_AsciiString aName = theArgVec[anArgIter];
+ const TCollection_AsciiString aName = theArgVec[anArgIter];
+ TCollection_AsciiString aNameCase = aName;
+ aNameCase.LowerCase();
if (parseRedrawMode (aName, aToUpdate))
{
continue;
}
+ else if (aNameCase == "-mutable")
+ {
+ isMutable = 1;
+ continue;
+ }
else if (!GetMapOfAIS().IsBound2 (aName))
{
// create the AIS_Shape from a name
const Handle(AIS_InteractiveObject) aShape = GetAISShapeFromName (aName.ToCString());
if (!aShape.IsNull())
{
+ if (isMutable != -1)
+ {
+ aShape->SetMutable (isMutable == 1);
+ }
GetMapOfAIS().Bind (aShape, aName);
aCtx->Display (aShape, Standard_False);
}
if (anObj->IsKind (STANDARD_TYPE (AIS_InteractiveObject)))
{
Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (anObj);
+ if (isMutable != -1)
+ {
+ aShape->SetMutable (isMutable == 1);
+ }
+
if (aShape->Type() == AIS_KOI_Datum)
{
aCtx->Display (aShape, Standard_False);
aCtx->Redisplay (aShape, Standard_False);
aCtx->Display (aShape, Standard_False);
}
- aShape.Nullify();
}
else if (anObj->IsKind (STANDARD_TYPE (NIS_InteractiveObject)))
{
GetMapOfAIS().Bind(myAisCrankArm,"c");
GetMapOfAIS().Bind(myAisPropeller,"d");
- TheAISContext()->SetColor(myAisCylinderHead, Quantity_NOC_INDIANRED);
- TheAISContext()->SetColor(myAisEngineBlock , Quantity_NOC_RED);
- TheAISContext()->SetColor(myAisPropeller , Quantity_NOC_GREEN);
+ myAisCylinderHead->SetMutable (Standard_True);
+ myAisEngineBlock ->SetMutable (Standard_True);
+ myAisCrankArm ->SetMutable (Standard_True);
+ myAisPropeller ->SetMutable (Standard_True);
- TheAISContext()->Display(myAisCylinderHead,Standard_False);
- TheAISContext()->Display(myAisEngineBlock,Standard_False );
- TheAISContext()->Display(myAisCrankArm,Standard_False );
- TheAISContext()->Display(myAisPropeller,Standard_False);
+ TheAISContext()->SetColor (myAisCylinderHead, Quantity_NOC_INDIANRED);
+ TheAISContext()->SetColor (myAisEngineBlock, Quantity_NOC_RED);
+ TheAISContext()->SetColor (myAisPropeller, Quantity_NOC_GREEN);
+
+ TheAISContext()->Display (myAisCylinderHead, Standard_False);
+ TheAISContext()->Display (myAisEngineBlock, Standard_False);
+ TheAISContext()->Display (myAisCrankArm, Standard_False);
+ TheAISContext()->Display (myAisPropeller, Standard_False);
TheAISContext()->Deactivate(myAisCylinderHead);
TheAISContext()->Deactivate(myAisEngineBlock );
__FILE__, visos, group);
theCommands.Add("vdisplay",
- "vdisplay [-noupdate|-update] name1 [name2] ... [name n]"
+ "vdisplay [-noupdate|-update] [-mutable] name1 [name2] ... [name n]"
"\n\t\t: Displays named objects."
"\n\t\t: Option -noupdate suppresses viewer redraw call."
+ "\n\t\t: Option -mutable enables optimizations for mutable objects."
__FILE__,VDisplay2,group);
theCommands.Add ("vupdate",
__FILE__, VErase, group);
theCommands.Add("vremove",
- "vremove [-noupdate|-update] [-context] [-all] [name1] ... [name n]"
+ "vremove [-noupdate|-update] [-context] [-all] [-noinfo] [name1] ... [name n]"
"or vremove [-context] -all to remove all objects"
"\n\t\t: Removes selected or named objects."
"\n\t\t If -context is in arguments, the objects are not deleted"
"\n\t\t from the map of objects and names."
- "\n\t\t: Option -noupdate suppresses viewer redraw call.",
+ "\n\t\t: Option -noupdate suppresses viewer redraw call."
+ "\n\t\t: Option -noinfo suppresses displaying the list of removed objects.",
__FILE__, VRemove, group);
theCommands.Add("vdonly",
Standard_Real aCenterY = (argc > 5) ? Draw::Atof (argv[4]) : 0.0;
Standard_Real aCenterZ = (argc > 5) ? Draw::Atof (argv[5]) : 0.0;
Standard_Real aRadius = (argc > 6) ? Draw::Atof (argv[6]) : 100.0;
- Standard_Boolean toShowEdges = (argc > 7) ? Draw::Atoi (argv[7]) : Standard_False;
+ Standard_Boolean toShowEdges = (argc > 7) ? Draw::Atoi (argv[7]) == 1 : Standard_False;
+ Standard_Boolean toPrintInfo = (argc > 8) ? Draw::Atoi (argv[8]) == 1 : Standard_True;
// remove AIS object with given name from map
VDisplayAISObject (aShapeName, Handle(AIS_InteractiveObject)());
- std::cout << "Compute Triangulation...\n";
+ if (toPrintInfo)
+ std::cout << "Compute Triangulation...\n";
Handle(AIS_Triangulation) aShape
= new AIS_Triangulation (CalculationOfSphere (aCenterX, aCenterY, aCenterZ,
aResolution,
aColorsSize >>= 20;
aTrianglesSize >>= 20;
aPolyConnectSize >>= 20;
- std::cout << "NumberOfPoints: " << aNumberPoints << "\n"
- << "NumberOfTriangles: " << aNumberTriangles << "\n"
- << "Amount of memory required for PolyTriangulation without Normals: " << (aTotalSize - aNormalsSize) << " Mb\n"
- << "Amount of memory for colors: " << aColorsSize << " Mb\n"
- << "Amount of memory for PolyConnect: " << aPolyConnectSize << " Mb\n"
- << "Amount of graphic card memory required: " << aTotalSize << " Mb\n";
+ if (toPrintInfo)
+ {
+ std::cout << "NumberOfPoints: " << aNumberPoints << "\n"
+ << "NumberOfTriangles: " << aNumberTriangles << "\n"
+ << "Amount of memory required for PolyTriangulation without Normals: " << (aTotalSize - aNormalsSize) << " Mb\n"
+ << "Amount of memory for colors: " << aColorsSize << " Mb\n"
+ << "Amount of memory for PolyConnect: " << aPolyConnectSize << " Mb\n"
+ << "Amount of graphic card memory required: " << aTotalSize << " Mb\n";
+ }
// Setting material properties, very important for desirable visual result!
Graphic3d_MaterialAspect aMat (Graphic3d_NOM_PLASTIC);
__FILE__,VDrawText,group);
theCommands.Add("vdrawsphere",
- "vdrawsphere: vdrawsphere shapeName Fineness [X=0.0 Y=0.0 Z=0.0] [Radius=100.0] [ToShowEdges=0]\n",
+ "vdrawsphere: vdrawsphere shapeName Fineness [X=0.0 Y=0.0 Z=0.0] [Radius=100.0] [ToShowEdges=0] [ToPrintInfo=1]\n",
__FILE__,VDrawSphere,group);
theCommands.Add ("vsetlocation",
public:
Element (const Handle(VUserDrawObj)& theIObj,
- CALL_DEF_BOUNDS* theBounds)
+ Graphic3d_BndBox4f* theBounds)
: myIObj( theIObj )
{
if (!myIObj.IsNull())
// Called by VUserDrawElement
void Render(const Handle(OpenGl_Workspace)& theWorkspace) const;
- void GetBounds(CALL_DEF_BOUNDS* theBounds);
+ void GetBounds(Graphic3d_BndBox4f* theBounds);
GLfloat myCoords[6];
theSelection->Add(aSensitive);
}
-void VUserDrawObj::GetBounds(CALL_DEF_BOUNDS* theBounds)
+void VUserDrawObj::GetBounds(Graphic3d_BndBox4f* theBounds)
{
if (theBounds)
{
- theBounds->XMin = myCoords[0];
- theBounds->YMin = myCoords[1];
- theBounds->ZMin = myCoords[2];
- theBounds->XMax = myCoords[3];
- theBounds->YMax = myCoords[4];
- theBounds->ZMax = myCoords[5];
+ Graphic3d_Vec4 aMinPt (myCoords[0], myCoords[1], myCoords[2], 1.0f);
+ Graphic3d_Vec4 aMaxPt (myCoords[3], myCoords[4], myCoords[5], 1.0f);
+ if (!theBounds->IsValid())
+ {
+ theBounds->Combine (Graphic3d_BndBox4f (aMinPt, aMaxPt));
+ }
+ else
+ {
+ theBounds->CornerMin() = aMinPt;
+ theBounds->CornerMax() = aMaxPt;
+ }
}
}
return 0;
}
+//=======================================================================
+//function : VFrustumCulling
+//purpose : enables/disables view volume's culling.
+//=======================================================================
+static int VFrustumCulling (Draw_Interpretor& theDI,
+ Standard_Integer theArgNb,
+ const char** theArgVec)
+{
+ Handle(V3d_View) aView = ViewerTest::CurrentView();
+ if (aView.IsNull())
+ {
+ std::cout << theArgVec[0] << " Error: Use 'vinit' command before\n";
+ return 1;
+ }
+
+ if (theArgNb < 2)
+ {
+ theDI << (aView->IsCullingEnabled() ? "on" : "off");
+ return 0;
+ }
+ else if (theArgNb != 2)
+ {
+ std::cout << theArgVec[0] << " Syntax error: Specify the mode\n";
+ return 1;
+ }
+
+ TCollection_AsciiString aModeStr (theArgVec[1]);
+ aModeStr.LowerCase();
+ Standard_Boolean toEnable = 0;
+ if (aModeStr == "on")
+ {
+ toEnable = 1;
+ }
+ else if (aModeStr == "off")
+ {
+ toEnable = 0;
+ }
+ else
+ {
+ toEnable = Draw::Atoi (theArgVec[1]) != 0;
+ }
+
+ aView->SetFrustumCulling (toEnable);
+ aView->Redraw();
+ return 0;
+}
+
//=======================================================================
//function : ViewerCommands
//purpose :
"\n '-fsaa on|off' Enables/disables adaptive anti-aliasing"
"\n '-gleam on|off' Enables/disables transparency shadow effects",
__FILE__, VRenderParams, group);
+ theCommands.Add("vfrustumculling",
+ "vfrustumculling [toEnable]: enables/disables objects clipping",
+ __FILE__,VFrustumCulling,group);
}
---Purpose: Sets the context <CTX> in the view <me>.
---Category: Methods to modify the class definition
- SetTransform ( me : mutable;
- AMatrix : Array2OfReal from TColStd )
- ---Level: Internal
- ---Purpose: Sets the transformation matrix that is applied
- -- to <MyViewOrientation> field of the view <me>.
- --
- -- <AMatrix> is defined as a 4*4 real matrix.
- --
- -- -------------------
- -- | a11 a12 a13 t1 |
- -- | a21 a22 a23 t2 |
- -- | a31 a32 a33 t3 |
- -- | 0 0 0 1 |
- -- -------------------
- --
- -- Category: Methods to modify the class definition
- -- Warning: Raises TransformError if the matrix isn't a 4x4 matrix.
- raises TransformError from Visual3d is static;
-
SetViewMappingDefault ( me : mutable )
is static;
---Level: Public
<< ", " << OldPriority << ", " << NewPriority << ")\n";
cout << flush;
#endif
- MyGraphicDriver->EraseStructure (MyCView, *(MyCOMPUTEDSequence.Value (Index)->CStructure()));
- MyGraphicDriver->DisplayStructure (MyCView, *(MyCOMPUTEDSequence.Value (Index)->CStructure()), NewPriority);
+ MyGraphicDriver->ChangePriority (*(MyCOMPUTEDSequence.Value (Index)->CStructure()), MyCView, NewPriority);
}
else
{
<< ", " << OldPriority << ", " << NewPriority << ")\n";
cout << flush;
#endif
- MyGraphicDriver->EraseStructure (MyCView, *(AStructure->CStructure()));
- MyGraphicDriver->DisplayStructure (MyCView, *(AStructure->CStructure()), NewPriority);
+ MyGraphicDriver->ChangePriority (*(AStructure->CStructure()), MyCView, NewPriority);
}
}
if (Answer == Visual3d_TOA_YES ) {
if (IsDisplayed (AStructure)) return;
+ AStructure->CalculateBoundBox();
MyGraphicDriver->DisplayStructure (MyCView, *(AStructure->CStructure()), AStructure->DisplayPriority());
MyDisplayedStructure.Add (AStructure);
if (AnUpdateMode == Aspect_TOU_ASAP) Update ();
MyCOMPUTEDSequence.Value (Index)->GraphicTransform (ATrsf);
}
+ Standard_Integer aLayerId = AStructure->GetZLayer();
+ if (!AStructure->IsMutable()
+ && !AStructure->CStructure()->IsForHighlight
+ && !AStructure->CStructure()->IsInfinite)
+ {
+ AStructure->CalculateBoundBox();
+ MyGraphicDriver->InvalidateBVHData (MyCView, aLayerId);
+ }
}
void Visual3d_View::UnHighlight (const Handle(Graphic3d_Structure)& AStructure) {
}
void Visual3d_View::ReCompute (const Handle(Graphic3d_Structure)& AStructure) {
+ if (MyCView.IsCullingEnabled)
+ {
+ AStructure->CalculateBoundBox();
+ Standard_Integer aLayerId = AStructure->DisplayPriority();
+ MyGraphicDriver->InvalidateBVHData(MyCView, aLayerId);
+ }
+
if (!ComputedMode()) return;
if (IsDeleted ()) return;
--- /dev/null
+puts "========"
+puts "OCC24307 Objects clipping algorithm using BVH performance test: Solid spheres test"
+puts "========"
+
+# define objects' location parameters and their characteristics
+set SPHERES_NUM 10
+set SPERE_RADIUS 100
+set SPHERE_FINENESS 10
+set PERCENT_OF_INNER_SPHERES 30
+
+# window parameters
+set SMALL_WIN_WIDTH 512
+set SMALL_WIN_HEIGHT 512
+
+# other
+array set aSphereNames {}
+
+set aWithoutClippingSnapshot $imagedir/${casename}_without.png
+set aWithClippingSnapshot $imagedir/${casename}_with.png
+set aDiffImage $imagedir/${casename}_diff.png
+
+pload VISUALIZATION MODELING
+vinit name=small_wnd l=32 t=32 w=$SMALL_WIN_WIDTH h=$SMALL_WIN_HEIGHT
+vactivate small_wnd
+vfrustumculling 0
+vautozfit 0
+vviewparams -scale 1.953125 -eye 0.57735026918962573 -0.57735026918962573 0.57735026918962573
+vzrange 1 512
+vclear
+vremove -all -noinfo
+
+puts [vdrawsphere tmp_sph $SPHERE_FINENESS]
+vremove -noinfo tmp_sph
+
+set aInnerSpheresNum [expr $SPHERES_NUM * $PERCENT_OF_INNER_SPHERES / 100]
+puts ""
+set aDebugInfo "Total number of visible objects: "
+append aDebugInfo $aInnerSpheresNum
+puts $aDebugInfo
+puts ""
+
+puts "Start displaying spheres without clipping..."
+set aInnerWidthStep [expr $SMALL_WIN_WIDTH / ($aInnerSpheresNum + 1)]
+set aInnerHeightStep [expr $SMALL_WIN_HEIGHT / ($aInnerSpheresNum + 1)]
+set aOuterStep [expr $SPERE_RADIUS * 3 / ($SPHERES_NUM - $aInnerSpheresNum + 1)]
+for {set i 0} {$i < $aInnerSpheresNum} {incr i} {
+ set aCurrName "inner_sph"
+ append aCurrName $i
+ set aX [expr - $SMALL_WIN_WIDTH / 2 + ($i + 1) * $aInnerWidthStep ]
+ set aY [expr - $SMALL_WIN_HEIGHT / 2 + ($i + 1) * $aInnerHeightStep ]
+ vdrawsphere $aCurrName $SPHERE_FINENESS $aX $aY 0 $SPERE_RADIUS 0 0
+ set aSphereNames($i) $aCurrName
+}
+for {set i $aInnerSpheresNum} {$i < $SPHERES_NUM} {incr i} {
+ set aCurrName "outer_sph"
+ append aCurrName $i
+ set aX [expr - $SMALL_WIN_WIDTH - $SPERE_RADIUS * 3 + ($i - $aInnerSpheresNum + 1) * $aOuterStep ]
+ set aY [expr - $SMALL_WIN_HEIGHT - $SPERE_RADIUS * 3 + ($i - $aInnerSpheresNum + 1) * $aOuterStep ]
+ vdrawsphere $aCurrName $SPHERE_FINENESS $aX $aY 0 $SPERE_RADIUS 0 0
+ set aSphereNames($i) $aCurrName
+}
+puts [vfps]
+vdump $aWithoutClippingSnapshot
+puts "All spheres were displayed."
+puts ""
+
+verase
+
+puts "Start displaying spheres with clipping..."
+vfrustumculling 1
+vdisplayall
+puts [vfps]
+vdump $aWithClippingSnapshot
+puts "All spheres were displayed."
+puts ""
+
+set aDiffImageResult [diffimage $aWithClippingSnapshot $aWithoutClippingSnapshot 0.1 0 0 $aDiffImage]
+if {$aDiffImageResult != 0} {
+ puts "ERROR : Test failed: there is a difference between images rendered with and without clipping"
+}
+
+verase
--- /dev/null
+puts "========"
+puts "OCC24307 Objects clipping algorithm using BVH performance test: Simple boxes test"
+puts "========"
+
+# object characteristics
+set BOXES_NUM 10
+set BOX_SIZE 100
+set PERCENT_OF_INNER_BOXES 30
+
+# window parameters
+set SMALL_WIN_WIDTH 512
+set SMALL_WIN_HEIGHT 512
+
+# other
+array set aBoxNames {}
+
+set aWithoutClippingSnapshot $imagedir/${casename}_without.png
+set aWithClippingSnapshot $imagedir/${casename}_with.png
+set aDiffImage $imagedir/${casename}_diff.png
+
+pload VISUALIZATION MODELING
+vinit name=small_wnd l=32 t=32 w=$SMALL_WIN_WIDTH h=$SMALL_WIN_HEIGHT
+vactivate small_wnd
+vfrustumculling 0
+vautozfit 0
+vviewparams -scale 1.953125 -eye 0.57735026918962573 -0.57735026918962573 0.57735026918962573
+vzrange 1 512
+vclear
+vremove -all -noinfo
+
+set aInnerBoxesNum [expr $BOXES_NUM * $PERCENT_OF_INNER_BOXES / 100]
+puts ""
+set aDebugInfo "Total number of visible objects: "
+append aDebugInfo $aInnerBoxesNum
+puts $aDebugInfo
+puts ""
+
+puts "Start boxes generation..."
+set aInnerWidthStep [expr $SMALL_WIN_WIDTH / (2 * ($aInnerBoxesNum + 1))]
+set aInnerHeightStep [expr $SMALL_WIN_HEIGHT / (2 * ($aInnerBoxesNum + 1))]
+set aOuterStep [expr $BOX_SIZE * 3 / ($BOXES_NUM - $aInnerBoxesNum + 1)]
+for {set i 0} {$i < $aInnerBoxesNum} {incr i} {
+ set aCurrName "inner_box"
+ append aCurrName $i
+ set aX [expr - $SMALL_WIN_WIDTH / 4 + ($i + 1) * $aInnerWidthStep ]
+ set aY [expr - $SMALL_WIN_HEIGHT / 4 + ($i + 1) * $aInnerHeightStep ]
+ box $aCurrName $aX $aY 0 $BOX_SIZE $BOX_SIZE $BOX_SIZE
+ set aBoxNames($i) $aCurrName
+}
+for {set i $aInnerBoxesNum} {$i < $BOXES_NUM} {incr i} {
+ set aCurrName "outer_box"
+ append aCurrName $i
+ set aX [expr - $SMALL_WIN_WIDTH - $BOX_SIZE * 3 + ($i - $aInnerBoxesNum + 1) * $aOuterStep]
+ set aY [expr - $SMALL_WIN_HEIGHT - $BOX_SIZE * 3 + ($i - $aInnerBoxesNum + 1) * $aOuterStep]
+ box $aCurrName $aX $aY 0 $BOX_SIZE $BOX_SIZE $BOX_SIZE
+ set aBoxNames($i) $aCurrName
+}
+puts "$BOXES_NUM boxes generated."
+puts ""
+
+puts "Start displaying boxes without clipping..."
+for {set i 0} {$i < $BOXES_NUM} {incr i} {
+ vdisplay -noupdate $aBoxNames($i)
+}
+puts [vfps]
+vdump $aWithoutClippingSnapshot
+puts "All boxes were displayed."
+puts ""
+
+verase
+
+vfrustumculling 1
+puts "Start displaying boxes with clipping..."
+for {set i 0} {$i < $BOXES_NUM} {incr i} {
+ vdisplay -noupdate $aBoxNames($i)
+}
+puts [vfps]
+vdump $aWithClippingSnapshot
+puts "All boxes were displayed."
+
+set aDiffImageResult [diffimage $aWithClippingSnapshot $aWithoutClippingSnapshot 0.1 0 0 $aDiffImage]
+if {$aDiffImageResult != 0} {
+ puts "ERROR : Test failed: there is a difference between images rendered with and without clipping"
+}
+
+verase