1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-04 18:06:22 +03:00

0024307: TKOpenGl - efficient culling of large number of presentations

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.
This commit is contained in:
vpa 2014-06-20 11:26:14 +04:00 committed by apn
parent c1c1aefa71
commit b7cd4ba795
53 changed files with 1885 additions and 538 deletions

View File

@ -23,6 +23,8 @@
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:

View File

@ -1,3 +1,5 @@
Graphic3d_BndBox4d.hxx
Graphic3d_BndBox4f.hxx
Graphic3d_Buffer.hxx
Graphic3d_Buffer_Handle.hxx
Graphic3d_BoundBuffer.hxx
@ -18,7 +20,6 @@ Graphic3d_CBitFields4.hxx
Graphic3d_CTexture.hxx
Graphic3d_CLight.hxx
Graphic3d_CPick.hxx
Graphic3d_CBounds.hxx
Graphic3d_CUserDraw.hxx
Graphic3d_CView.hxx
Graphic3d_CGraduatedTrihedron.hxx

View File

@ -347,6 +347,9 @@ is
-- 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;
@ -354,6 +357,7 @@ is
imported IndexBuffer;
imported IndexBuffer_Handle;
imported BndBox4d;
imported BufferType;
imported CBitFields20;
@ -389,9 +393,6 @@ is
imported CPlane;
---Category: Imported types
imported CBounds;
---Category: Imported types
imported CUserDraw;
---Category: Imported types

View File

@ -0,0 +1,23 @@
// 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

View File

@ -0,0 +1,23 @@
// 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

View File

@ -1,27 +0,0 @@
// 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*/

View File

@ -37,6 +37,9 @@ Graphic3d_CStructure::Graphic3d_CStructure (const Handle(Graphic3d_StructureMana
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)

View File

@ -15,6 +15,7 @@
#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>
@ -53,6 +54,19 @@ public:
//! 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
@ -101,19 +115,22 @@ public:
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;
@ -126,6 +143,7 @@ protected:
Handle(Graphic3d_GraphicDriver) myGraphicDriver;
Graphic3d_SequenceOfGroup myGroups;
Graphic3d_BndBox4f myBndBox;
Graphic3d_SequenceOfHClipPlane myClipPlanes;
public:

View File

@ -93,13 +93,14 @@ 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:
@ -134,6 +135,9 @@ public:
//! Specifies rendering parameters and effects.
Graphic3d_RenderingParams RenderParams;
//! Enables/disables frustum culling.
Standard_Boolean IsCullingEnabled;
};
#endif // Graphic3d_CView_HeaderFile

View File

@ -643,6 +643,13 @@ is
-- 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 )
@ -696,6 +703,14 @@ is
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
-----------------------------

View File

@ -90,7 +90,7 @@ deferred class Group from Graphic3d inherits TShared
Buffer_Handle from Graphic3d,
BoundBuffer_Handle from Graphic3d,
TransModeFlags from Graphic3d,
CBounds from Graphic3d,
BndBox4f from Graphic3d,
Ax2 from gp
raises
@ -480,6 +480,22 @@ deferred class Group from Graphic3d inherits TShared
-- 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
@ -534,7 +550,7 @@ deferred class Group from Graphic3d inherits TShared
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;

View File

@ -39,14 +39,6 @@
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
@ -95,12 +87,7 @@ void Graphic3d_Group::Clear (Standard_Boolean theUpdateStructureMgr)
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)
{
@ -148,12 +135,7 @@ void Graphic3d_Group::Remove()
Update();
myBounds.XMin = ShortRealLast();
myBounds.YMin = ShortRealLast();
myBounds.ZMin = ShortRealLast();
myBounds.XMax = ShortRealFirst();
myBounds.YMax = ShortRealFirst();
myBounds.ZMax = ShortRealFirst();
myBounds.Clear();
MyIsEmpty = Standard_True;
}
@ -188,11 +170,7 @@ Standard_Boolean Graphic3d_Group::IsEmpty() const
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);
@ -207,12 +185,14 @@ Standard_Boolean Graphic3d_Group::IsEmpty() const
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);
}
// =======================================================================
@ -248,14 +228,22 @@ void Graphic3d_Group::MinMaxCoord (Standard_Real& theXMin, Standard_Real& theYMi
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();
}
}
@ -1039,10 +1027,7 @@ void Graphic3d_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray th
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;
}
@ -1052,12 +1037,7 @@ void Graphic3d_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray th
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;
}
@ -1130,12 +1110,11 @@ void Graphic3d_Group::Text (const Standard_CString /*theText*/,
{
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();
}
@ -1202,3 +1181,21 @@ Standard_Boolean Graphic3d_Group::IsClosed() const
{
return myIsClosed;
}
//=======================================================================
//function : BoundingBox
//purpose :
//=======================================================================
const Graphic3d_BndBox4f& Graphic3d_Group::BoundingBox() const
{
return myBounds;
}
//=======================================================================
//function : ChangeBoundingBox
//purpose :
//=======================================================================
Graphic3d_BndBox4f& Graphic3d_Group::ChangeBoundingBox()
{
return myBounds;
}

View File

@ -71,7 +71,9 @@ uses
Vertex from Graphic3d,
TransModeFlags from Graphic3d,
Pnt from gp,
SequenceOfHClipPlane from Graphic3d
SequenceOfHClipPlane from Graphic3d,
BndBox4f from Graphic3d,
BndBox4d from Graphic3d
raises
@ -210,6 +212,12 @@ is
-- 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;
@ -358,6 +366,14 @@ is
-- <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
@ -810,6 +826,17 @@ is
---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
----------------------------
@ -878,28 +905,16 @@ is
---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;

View File

@ -114,6 +114,32 @@ void Graphic3d_Structure::Clear (const Standard_Boolean theWithDestruction)
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 :
@ -150,8 +176,6 @@ void Graphic3d_Structure::Remove()
((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);
@ -182,6 +206,15 @@ void Graphic3d_Structure::Display()
myCStructure->visible = 1;
}
//=============================================================================
//function : SetIsForHighlight
//purpose :
//=============================================================================
void Graphic3d_Structure::SetIsForHighlight (const Standard_Boolean isForHighlight)
{
myCStructure->IsForHighlight = isForHighlight;
}
//=============================================================================
//function : Display
//purpose :
@ -1375,6 +1408,7 @@ void Graphic3d_Structure::Connect (const Handle(Graphic3d_Structure)& theStructu
}
myDescendants.Append (theStructure.operator->());
CalculateBoundBox();
theStructure->Connect (this, Graphic3d_TOC_ANCESTOR);
GraphicConnect (theStructure);
@ -1395,6 +1429,7 @@ void Graphic3d_Structure::Connect (const Handle(Graphic3d_Structure)& theStructu
}
myAncestors.Append (theStructure.operator->());
CalculateBoundBox();
theStructure->Connect (this, Graphic3d_TOC_DESCENDANT);
// myGraphicDriver->Connect is called in case if connection between parent and child
@ -1422,6 +1457,8 @@ void Graphic3d_Structure::Disconnect (const Handle(Graphic3d_Structure)& theStru
GraphicDisconnect (theStructure);
myStructureManager->Disconnect (this, theStructure);
CalculateBoundBox();
Update();
return;
}
@ -1434,6 +1471,7 @@ void Graphic3d_Structure::Disconnect (const Handle(Graphic3d_Structure)& theStru
{
myAncestors.Remove (anIter);
theStructure->Disconnect (this);
CalculateBoundBox();
// no call of myGraphicDriver->Disconnect in case of an ancestor
return;
}
@ -1608,6 +1646,7 @@ void Graphic3d_Structure::Transform (TColStd_Array2OfReal& theMatrix) const
}
}
//=============================================================================
//function : MinMaxValues
//purpose :
@ -1620,18 +1659,9 @@ void Graphic3d_Structure::MinMaxValues (Standard_Real& theXMin,
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())
Graphic3d_BndBox4d aBox;
addTransformed (aBox, theToIgnoreInfiniteFlag);
if (!aBox.IsValid())
{
theXMin = RealFirst();
theYMin = RealFirst();
@ -1642,86 +1672,12 @@ void Graphic3d_Structure::MinMaxValues (Standard_Real& theXMin,
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())
{
theXMin = RealFirst();
theYMin = RealFirst();
theZMin = RealFirst();
theXMax = RealLast();
theYMax = RealLast();
theZMax = RealLast();
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();
}
//=============================================================================
@ -1756,6 +1712,7 @@ void Graphic3d_Structure::SetTransformPersistence (const Graphic3d_TransModeFlag
myCStructure->TransformPersistence.Point.y = float (thePoint.Y());
myCStructure->TransformPersistence.Point.z = float (thePoint.Z());
myCStructure->UpdateAspects();
CalculateBoundBox();
myCStructure->TransformPersistence.IsSet = 1;
}
@ -1855,154 +1812,79 @@ Handle(Graphic3d_StructureManager) Graphic3d_Structure::StructureManager() const
}
//=============================================================================
//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);
const Graphic3d_Structure* aStruct = (const Graphic3d_Structure* )myDescendants.Value (aStructIt);
aStruct->addTransformed (aBox, theToIgnoreInfiniteFlag);
}
if (aBox.IsValid())
{
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);
TransformBoundaries (aTrsf, aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z(),
aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z());
theBox.Combine (aBox);
}
// 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;
}
//=============================================================================
@ -2384,27 +2266,10 @@ void Graphic3d_Structure::GraphicHighlight (const Aspect_TypeOfHighlightMethod t
}
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;
}
@ -2531,3 +2396,21 @@ const Graphic3d_SequenceOfHClipPlane& Graphic3d_Structure::GetClipPlanes() const
{
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;
}

View File

@ -16,6 +16,7 @@
#define InterfaceGraphic_Graphic3dHeader
#include <InterfaceGraphic_telem.hxx>
#include <Graphic3d_BndBox4f.hxx>
#include <Standard_Transient.hxx>
/* COULEUR */
@ -34,18 +35,6 @@ typedef struct {
} 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 {
@ -85,26 +74,12 @@ 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;

View File

@ -315,7 +315,7 @@ public:
//! 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;
}

View File

@ -143,3 +143,7 @@ OpenGl_SceneGeometry.cxx
OpenGl_Workspace_Raytrace.cxx
OpenGl_Flipper.hxx
OpenGl_Flipper.cxx
OpenGl_BVHTreeSelector.hxx
OpenGl_BVHTreeSelector.cxx
OpenGl_BVHClipPrimitiveSet.cxx
OpenGl_BVHClipPrimitiveSet.hxx

View File

@ -0,0 +1,143 @@
// 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);
}

View File

@ -0,0 +1,78 @@
// 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

View File

@ -0,0 +1,283 @@
// 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;
}

View File

@ -0,0 +1,117 @@
// 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

View File

@ -279,6 +279,11 @@ public:
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
@ -315,6 +320,10 @@ public:
//! 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)

View File

@ -127,3 +127,21 @@ void OpenGl_GraphicDriver::UnsetZLayer (const Standard_Integer theLayerId)
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);
}

View File

@ -459,6 +459,19 @@ void OpenGl_GraphicDriver::Transparency (const Graphic3d_CView& ACView, const St
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)

View File

@ -156,14 +156,15 @@ void OpenGl_LayerList::RemoveLayer (const Standard_Integer theLayerId)
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
@ -222,6 +223,20 @@ void OpenGl_LayerList::RemoveStructure (const OpenGl_Structure *theStructure,
}
}
//=======================================================================
//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 :
@ -239,10 +254,10 @@ void OpenGl_LayerList::ChangeLayer (const OpenGl_Structure *theStructure,
// 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
{
@ -255,10 +270,47 @@ void OpenGl_LayerList::ChangeLayer (const OpenGl_Structure *theStructure,
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);
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, theLayerId, theNewPriority, Standard_True);
break;
}
}

View File

@ -60,7 +60,8 @@ class OpenGl_LayerList
//! 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,
@ -73,6 +74,11 @@ class OpenGl_LayerList
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);
@ -85,6 +91,10 @@ class OpenGl_LayerList
//! 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; }

View File

@ -15,36 +15,78 @@
#include <OpenGl_PriorityList.hxx>
#include <OpenGl_BVHTreeSelector.hxx>
#include <OpenGl_Structure.hxx>
#include <OpenGl_View.hxx>
/*----------------------------------------------------------------------*/
void OpenGl_PriorityList::Add (const OpenGl_Structure *AStructure,const Standard_Integer APriority)
// =======================================================================
// function : OpenGl_PriorityList
// purpose :
// =======================================================================
OpenGl_PriorityList::OpenGl_PriorityList (const Standard_Integer theNbPriorities)
: myArray (0, theNbPriorities - 1),
myNbStructures (0),
myBVHIsLeftChildQueuedFirst (Standard_True),
myIsBVHPrimitivesNeedsReset (Standard_False)
{
Standard_Integer anIndex = APriority;
if (anIndex < 0) anIndex = 0;
else if (anIndex >= myArray.Length()) anIndex = myArray.Length()-1;
myArray(anIndex).Append(AStructure);
myNbStructures++;
//
}
/*----------------------------------------------------------------------*/
Standard_Integer OpenGl_PriorityList::Remove (const OpenGl_Structure *AStructure)
// =======================================================================
// function : ~OpenGl_PriorityList
// purpose :
// =======================================================================
OpenGl_PriorityList::~OpenGl_PriorityList()
{
const Standard_Integer aNbPr = myArray.Length();
Standard_Integer i = 0;
OpenGl_SequenceOfStructure::Iterator its;
for (; i < aNbPr; i++)
//
}
// =======================================================================
// 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);
myArray (anIndex).Append (theStructure);
if (theStructure->IsAlwaysRendered())
{
OpenGl_SequenceOfStructure &aSeq = myArray(i);
for (its.Init(aSeq); its.More(); its.Next())
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 aNbPriorities = myArray.Length();
OpenGl_SequenceOfStructure::Iterator aStructIter;
for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
{
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;
}
}
}
@ -52,50 +94,177 @@ Standard_Integer OpenGl_PriorityList::Remove (const OpenGl_Structure *AStructure
return -1;
}
/*----------------------------------------------------------------------*/
void OpenGl_PriorityList::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
// =======================================================================
// function : InvalidateBVHData
// purpose :
// =======================================================================
void OpenGl_PriorityList::InvalidateBVHData()
{
const Standard_Integer aNbPr = myArray.Length();
Standard_Integer i = 0;
OpenGl_SequenceOfStructure::Iterator its;
for (; i < aNbPr; i++)
myIsBVHPrimitivesNeedsReset = Standard_True;
}
// =======================================================================
// function : Render
// purpose :
// =======================================================================
void OpenGl_PriorityList::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
{
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();

View File

@ -22,6 +22,8 @@
#include <InterfaceGraphic_telem.hxx>
#include <Handle_OpenGl_Workspace.hxx>
#include <OpenGl_BVHClipPrimitiveSet.hxx>
#include <OpenGl_BVHTreeSelector.hxx>
class OpenGl_Structure;
@ -30,21 +32,27 @@ typedef NCollection_Array1<OpenGl_SequenceOfStructure> OpenGl_ArrayOfStructure;
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;
@ -56,13 +64,33 @@ class OpenGl_PriorityList
//! 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

View File

@ -18,9 +18,9 @@
#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
@ -29,6 +29,9 @@
#include <OpenGl_SceneGeometry.hxx>
#include <OpenGl_PrimitiveArray.hxx>
#include <OpenGl_Structure.hxx>
//! Use this macro to output BVH profiling info
//#define BVH_PRINT_INFO

View File

@ -19,8 +19,11 @@
#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
{

View File

@ -37,14 +37,15 @@ class OpenGl_BndBoxPrs : public OpenGl_Element
public:
//! Main constructor
OpenGl_BndBoxPrs (const CALL_DEF_BOUNDBOX& theBndBox)
OpenGl_BndBoxPrs (const Graphic3d_BndBox4f& 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;
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);
@ -143,7 +144,8 @@ OpenGl_Structure::OpenGl_Structure (const Handle(Graphic3d_StructureManager)& th
myNamedStatus(0),
myZLayer(0),
myIsRaytracable (Standard_False),
myModificationState (0)
myModificationState (0),
myIsCulled (Standard_True)
{
UpdateNamedStatus();
}
@ -212,6 +214,7 @@ void OpenGl_Structure::SetTransformPersistence(const CALL_DEF_TRANSFORM_PERSISTE
myTransPers->pointX = ATransPers.Point.x;
myTransPers->pointY = ATransPers.Point.y;
myTransPers->pointZ = ATransPers.Point.z;
MarkAsNotCulled();
}
// =======================================================================
@ -323,12 +326,12 @@ void OpenGl_Structure::HighlightWithBndBox (const Handle(Graphic3d_Structure)& t
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);
}
@ -598,6 +601,9 @@ void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
UpdateStateWithAncestorStructures();
UpdateRaytracableWithAncestorStructures();
}
Is2dText = Standard_False;
IsForHighlight = Standard_False;
}
// =======================================================================
@ -610,6 +616,8 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
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;
@ -617,8 +625,6 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
// 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;
@ -678,12 +684,6 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
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)
@ -800,6 +800,12 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
}
}
// Apply highlight box
if (!myHighlightBox.IsNull())
{
myHighlightBox->Render (AWorkspace);
}
// Restore named status
AWorkspace->NamedStatus = named_status;
}
@ -872,6 +878,7 @@ Standard_Integer OpenGl_Structure::GetZLayer () const
return myZLayer;
}
//! Dummy structure which just redirects to groups of another structure.
class OpenGl_StructureShadow : public OpenGl_Structure
{
@ -898,6 +905,10 @@ DEFINE_STANDARD_HANDLE(OpenGl_StructureShadow, 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)

View File

@ -27,6 +27,8 @@
#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>
@ -140,6 +142,34 @@ public:
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).
@ -212,6 +242,8 @@ protected:
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

View File

@ -37,6 +37,7 @@
#include <Graphic3d_ZLayerSettings.hxx>
#include <Visual3d_TypeOfSurfaceDetail.hxx>
#include <OpenGl_BVHTreeSelector.hxx>
#include <OpenGl_LayerList.hxx>
#include <OpenGl_Light.hxx>
#include <OpenGl_LineAttributes.hxx>
@ -164,6 +165,10 @@ class OpenGl_View : public MMgt_TShared
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);
@ -190,6 +195,14 @@ class OpenGl_View : public MMgt_TShared
//! 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;
@ -273,6 +286,9 @@ protected:
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:

View File

@ -383,6 +383,19 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
}
}
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())
@ -429,6 +442,12 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
}
}
if (isProjectionMatUpdateNeeded
|| isOrientationMatUpdateNeeded)
{
myBVHSelector.SetViewVolume (myCamera);
}
// ====================================
// Step 2: Redraw background
// ====================================
@ -643,6 +662,15 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
}
}
// =======================================================================
// function : InvalidateBVHData
// purpose :
// =======================================================================
void OpenGl_View::InvalidateBVHData (const Standard_Integer theLayerId)
{
myZLayers.InvalidateBVHData (theLayerId);
}
/*----------------------------------------------------------------------*/
//ExecuteViewDisplay
@ -1033,6 +1061,16 @@ void OpenGl_View::SetZLayerSettings (const Standard_Integer theLayerId,
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

View File

@ -159,6 +159,7 @@ OpenGl_Workspace::OpenGl_Workspace (const Handle(Aspect_DisplayConnection)& theD
myUseZBuffer (Standard_False),
myUseDepthTest (Standard_True),
myUseGLLight (Standard_True),
myIsCullingEnabled (Standard_False),
//
AspectLine_set (&myDefaultAspectLine),
AspectLine_applied (NULL),
@ -560,6 +561,8 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
return;
}
myIsCullingEnabled = theCView.IsCullingEnabled;
// release pending GL resources
Handle(OpenGl_Context) aGlCtx = GetGlContext();
aGlCtx->ReleaseDelayed();

View File

@ -64,6 +64,7 @@ class OpenGl_AspectMarker;
class OpenGl_AspectText;
class OpenGl_FrameBuffer;
class OpenGl_Structure;
class OpenGl_TriangleSet;
class OpenGl_Element;
class Image_PixMap;
@ -224,6 +225,9 @@ public:
//! 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
@ -599,6 +603,7 @@ protected: //! @name protected fields
Standard_Boolean myUseZBuffer;
Standard_Boolean myUseDepthTest;
Standard_Boolean myUseGLLight;
Standard_Boolean myIsCullingEnabled; //!< frustum culling flag
protected: //! @name fields related to status

View File

@ -13,13 +13,15 @@
// 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>

View File

@ -91,6 +91,12 @@ is
---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);

View File

@ -288,6 +288,15 @@ Handle(Graphic3d_Group) Prs3d_Presentation::CurrentGroup () const
}
//=======================================================================
//=======================================================================
//function : SetIsForHighlight
//purpose :
//=======================================================================
void Prs3d_Presentation::SetIsForHighlight (const Standard_Boolean isForHighlight)
{
Graphic3d_Structure::SetIsForHighlight (isForHighlight);
}
//function : Compute
//purpose :
//=======================================================================

View File

@ -277,6 +277,16 @@ is
---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
@ -287,8 +297,8 @@ fields
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,

View File

@ -25,10 +25,11 @@
//=======================================================================
//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;
@ -294,6 +295,7 @@ void PrsMgr_PresentableObject::SetTransformPersistence (const Graphic3d_TransMod
&& !aPrs3d->Presentation().IsNull())
{
aPrs3d->Presentation()->SetTransformPersistence (theFlag, thePoint);
aPrs3d->Presentation()->ReCompute();
}
}
}
@ -414,3 +416,37 @@ void PrsMgr_PresentableObject::UpdateClipping()
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;
}

View File

@ -52,6 +52,7 @@ PrsMgr_Presentation::PrsMgr_Presentation (const Handle(PrsMgr_PresentationManage
myStructure = new PrsMgr_Prs (thePrsMgr->StructureManager(),
this, thePrsObject->TypeOfPresentation3d());
myStructure->SetOwner (myPresentableObject);
myStructure->SetMutable (myPresentableObject->IsMutable());
}
//=======================================================================
@ -68,15 +69,17 @@ void PrsMgr_Presentation::Display()
//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);
}
}

View File

@ -270,6 +270,20 @@ inline Standard_Integer RealToInt (const Standard_Real Value)
: (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
//-------------------------------------------------------------------

View File

@ -1629,6 +1629,14 @@ is
---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;

View File

@ -3392,3 +3392,23 @@ void V3d_View::Translate (const Handle(Graphic3d_Camera)& theCamera,
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;
}

View File

@ -2028,6 +2028,7 @@ int VRemove (Draw_Interpretor& theDI,
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)
@ -2042,6 +2043,10 @@ int VRemove (Draw_Interpretor& theDI,
{
toRemoveAll = Standard_True;
}
else if (anArg == "-noinfo")
{
toPrintInfo = Standard_False;
}
else if (!parseRedrawMode (anArg, aToUpdate))
{
break;
@ -2133,11 +2138,13 @@ int VRemove (Draw_Interpretor& theDI,
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
{
@ -2145,10 +2152,12 @@ int VRemove (Draw_Interpretor& theDI,
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());
@ -2854,19 +2863,31 @@ static int VDisplay2 (Draw_Interpretor& theDI,
}
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);
}
@ -2877,6 +2898,11 @@ static int VDisplay2 (Draw_Interpretor& theDI,
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);
@ -2896,7 +2922,6 @@ static int VDisplay2 (Draw_Interpretor& theDI,
aCtx->Redisplay (aShape, Standard_False);
aCtx->Display (aShape, Standard_False);
}
aShape.Nullify();
}
else if (anObj->IsKind (STANDARD_TYPE (NIS_InteractiveObject)))
{
@ -3088,14 +3113,19 @@ static int VAnimation (Draw_Interpretor& di, Standard_Integer argc, const char**
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 );
@ -4215,9 +4245,10 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands)
__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",
@ -4232,12 +4263,13 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands)
__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",

View File

@ -2923,12 +2923,14 @@ static int VDrawSphere (Draw_Interpretor& /*di*/, Standard_Integer argc, const c
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,
@ -2967,12 +2969,15 @@ static int VDrawSphere (Draw_Interpretor& /*di*/, Standard_Integer argc, const c
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);
@ -5283,7 +5288,7 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
__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",

View File

@ -86,7 +86,7 @@ public:
public:
Element (const Handle(VUserDrawObj)& theIObj,
CALL_DEF_BOUNDS* theBounds)
Graphic3d_BndBox4f* theBounds)
: myIObj( theIObj )
{
if (!myIObj.IsNull())
@ -123,7 +123,7 @@ private:
// 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];
@ -156,16 +156,21 @@ void VUserDrawObj::ComputeSelection (const Handle(SelectMgr_Selection)& theSelec
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;
}
}
}

View File

@ -6603,6 +6603,53 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
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 :
@ -6968,4 +7015,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
"\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);
}

View File

@ -297,25 +297,6 @@ is
---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

View File

@ -1189,8 +1189,7 @@ Standard_Integer Index = IsComputed (AStructure);
<< ", " << 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
{
@ -1201,8 +1200,7 @@ Standard_Integer Index = IsComputed (AStructure);
<< ", " << OldPriority << ", " << NewPriority << ")\n";
cout << flush;
#endif
MyGraphicDriver->EraseStructure (MyCView, *(AStructure->CStructure()));
MyGraphicDriver->DisplayStructure (MyCView, *(AStructure->CStructure()), NewPriority);
MyGraphicDriver->ChangePriority (*(AStructure->CStructure()), MyCView, NewPriority);
}
}
@ -1381,6 +1379,7 @@ Standard_Integer Index = IsComputed (AStructure);
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 ();
@ -1628,6 +1627,14 @@ Standard_Integer Index = IsComputed (AStructure);
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) {
@ -2089,6 +2096,13 @@ Graphic3d_SequenceOfStructure FooSequence;
}
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;

82
tests/bugs/vis/bug24307_1 Normal file
View File

@ -0,0 +1,82 @@
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

86
tests/bugs/vis/bug24307_2 Normal file
View File

@ -0,0 +1,86 @@
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