1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +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> template<class T, int N>
class BVH_PrimitiveSet : public BVH_Object<T, N>, public BVH_Set<T, N> class BVH_PrimitiveSet : public BVH_Object<T, N>, public BVH_Set<T, N>
{ {
protected:
using BVH_Set<T, N>::Box; using BVH_Set<T, N>::Box;
public: public:

View File

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

View File

@ -347,6 +347,9 @@ is
-- Category: Imported types -- Category: Imported types
--------------------------- ---------------------------
imported BndBox4f;
---Purpose: Redefines BVH_Box<Standard_ShortReal, 4> for AABB representation
---Category: Imported types
imported Buffer; imported Buffer;
imported Buffer_Handle; imported Buffer_Handle;
imported BoundBuffer; imported BoundBuffer;
@ -354,6 +357,7 @@ is
imported IndexBuffer; imported IndexBuffer;
imported IndexBuffer_Handle; imported IndexBuffer_Handle;
imported BndBox4d;
imported BufferType; imported BufferType;
imported CBitFields20; imported CBitFields20;
@ -389,9 +393,6 @@ is
imported CPlane; imported CPlane;
---Category: Imported types ---Category: Imported types
imported CBounds;
---Category: Imported types
imported CUserDraw; imported CUserDraw;
---Category: Imported types ---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), visible (1),
pick (1), pick (1),
HLRValidation (0), HLRValidation (0),
IsForHighlight (Standard_False),
IsMutable (Standard_False),
Is2dText (Standard_False),
myGraphicDriver (theManager->GraphicDriver()) myGraphicDriver (theManager->GraphicDriver())
{ {
for (Standard_Integer i = 0; i <= 3; ++i) for (Standard_Integer i = 0; i <= 3; ++i)

View File

@ -15,6 +15,7 @@
#ifndef _Graphic3d_CStructure_HeaderFile #ifndef _Graphic3d_CStructure_HeaderFile
#define _Graphic3d_CStructure_HeaderFile #define _Graphic3d_CStructure_HeaderFile
#include <Graphic3d_BndBox4f.hxx>
#include <Graphic3d_CStructure_Handle.hxx> #include <Graphic3d_CStructure_Handle.hxx>
#include <Graphic3d_Group.hxx> #include <Graphic3d_Group.hxx>
#include <Graphic3d_SequenceOfGroup.hxx> #include <Graphic3d_SequenceOfGroup.hxx>
@ -53,6 +54,19 @@ public:
//! Pass clip planes to the associated graphic driver structure //! Pass clip planes to the associated graphic driver structure
void SetClipPlanes (const Graphic3d_SequenceOfHClipPlane& thePlanes) { myClipPlanes = thePlanes; } 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: public:
//! Update structure visibility state //! Update structure visibility state
@ -101,19 +115,22 @@ public:
CALL_DEF_CONTEXTMARKER ContextMarker; CALL_DEF_CONTEXTMARKER ContextMarker;
CALL_DEF_CONTEXTTEXT ContextText; CALL_DEF_CONTEXTTEXT ContextText;
CALL_DEF_BOUNDBOX BoundBox; CALL_DEF_COLOR HighlightColor;
float Transformation[4][4]; float Transformation[4][4];
Graphic3d_TypeOfComposition Composition; Graphic3d_TypeOfComposition Composition;
int ContainsFacet; int ContainsFacet;
unsigned IsInfinite : 1; unsigned IsInfinite : 1;
unsigned stick : 1; unsigned stick : 1;
unsigned highlight : 1; unsigned highlight : 1;
unsigned visible : 1; unsigned visible : 1;
unsigned pick : 1; unsigned pick : 1;
unsigned HLRValidation : 1; unsigned HLRValidation : 1;
unsigned IsForHighlight : 1;
unsigned IsMutable : 1;
unsigned Is2dText : 1;
CALL_DEF_TRANSFORM_PERSISTENCE TransformPersistence; CALL_DEF_TRANSFORM_PERSISTENCE TransformPersistence;
@ -126,6 +143,7 @@ protected:
Handle(Graphic3d_GraphicDriver) myGraphicDriver; Handle(Graphic3d_GraphicDriver) myGraphicDriver;
Graphic3d_SequenceOfGroup myGroups; Graphic3d_SequenceOfGroup myGroups;
Graphic3d_BndBox4f myBndBox;
Graphic3d_SequenceOfHClipPlane myClipPlanes; Graphic3d_SequenceOfHClipPlane myClipPlanes;
public: public:

View File

@ -93,13 +93,14 @@ public:
ptrUnderLayer (NULL), ptrUnderLayer (NULL),
ptrOverLayer (NULL), ptrOverLayer (NULL),
Backfacing (0), Backfacing (0),
GContext (NULL), GContext (NULL),
GDisplayCB (NULL), GDisplayCB (NULL),
GClientData (NULL), GClientData (NULL),
ptrFBO (NULL), ptrFBO (NULL),
WasRedrawnGL (0) WasRedrawnGL (0),
IsCullingEnabled (Standard_True)
{ {
memset(&DefWindow,0,sizeof(DefWindow)); memset (&DefWindow, 0, sizeof(DefWindow));
} }
public: public:
@ -134,6 +135,9 @@ public:
//! Specifies rendering parameters and effects. //! Specifies rendering parameters and effects.
Graphic3d_RenderingParams RenderParams; Graphic3d_RenderingParams RenderParams;
//! Enables/disables frustum culling.
Standard_Boolean IsCullingEnabled;
}; };
#endif // Graphic3d_CView_HeaderFile #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). -- 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. -- 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; AddZLayer( me : mutable;
theCView : CView from Graphic3d; theCView : CView from Graphic3d;
theLayerId : Integer from Standard ) theLayerId : Integer from Standard )
@ -696,6 +703,14 @@ is
is deferred; is deferred;
---Purpose: Sets the settings for a single Z layer of specified view. ---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 -- Category: Internal methods
----------------------------- -----------------------------

View File

@ -90,7 +90,7 @@ deferred class Group from Graphic3d inherits TShared
Buffer_Handle from Graphic3d, Buffer_Handle from Graphic3d,
BoundBuffer_Handle from Graphic3d, BoundBuffer_Handle from Graphic3d,
TransModeFlags from Graphic3d, TransModeFlags from Graphic3d,
CBounds from Graphic3d, BndBox4f from Graphic3d,
Ax2 from gp Ax2 from gp
raises raises
@ -481,6 +481,22 @@ deferred class Group from Graphic3d inherits TShared
-- XMax = YMax = ZMax = RealLast (). -- XMax = YMax = ZMax = RealLast ().
---Category: Inquire methods ---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 ) Structure ( me )
returns Structure from Graphic3d returns Structure from Graphic3d
is static; is static;
@ -534,7 +550,7 @@ deferred class Group from Graphic3d inherits TShared
myStructure : StructurePtr from Graphic3d is protected; myStructure : StructurePtr from Graphic3d is protected;
-- the min-max -- 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. -- Identifies group forming closed volume. Used to filter groups for back face culling and capping algorithms.
myIsClosed : Boolean from Standard is protected; myIsClosed : Boolean from Standard is protected;

View File

@ -39,14 +39,6 @@
Graphic3d_Group::Graphic3d_Group (const Handle(Graphic3d_Structure)& theStruct) Graphic3d_Group::Graphic3d_Group (const Handle(Graphic3d_Structure)& theStruct)
: myIsClosed (Standard_False) : 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! // A small commentary on the usage of This!
// //
// Graphic3d_Group is created in a structure. Graphic3d_Structure is a // 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, ContextMarker.IsDef = 0,
ContextFillArea.IsDef = 0; ContextFillArea.IsDef = 0;
myBounds.XMin = ShortRealLast(); myBounds.Clear();
myBounds.YMin = ShortRealLast();
myBounds.ZMin = ShortRealLast();
myBounds.XMax = ShortRealFirst();
myBounds.YMax = ShortRealFirst();
myBounds.ZMax = ShortRealFirst();
if (MyContainsFacet) if (MyContainsFacet)
{ {
@ -148,12 +135,7 @@ void Graphic3d_Group::Remove()
Update(); Update();
myBounds.XMin = ShortRealLast(); myBounds.Clear();
myBounds.YMin = ShortRealLast();
myBounds.ZMin = ShortRealLast();
myBounds.XMax = ShortRealFirst();
myBounds.YMax = ShortRealFirst();
myBounds.ZMax = ShortRealFirst();
MyIsEmpty = Standard_True; MyIsEmpty = Standard_True;
} }
@ -188,11 +170,7 @@ Standard_Boolean Graphic3d_Group::IsEmpty() const
return Standard_True; return Standard_True;
} }
const Standard_ShortReal RL = ShortRealLast(); const Standard_Boolean isEmpty = myStructure->IsInfinite() ? Standard_False : !myBounds.IsValid();
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));
if (isEmpty != MyIsEmpty) if (isEmpty != MyIsEmpty)
{ {
::Message::DefaultMessenger()->Send ("Graphic3d_Group: MyIsEmpty != IsEmpty()", Message_Trace); ::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, 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) const Standard_Real theXMax, const Standard_Real theYMax, const Standard_Real theZMax)
{ {
myBounds.XMin = Standard_ShortReal (theXMin); myBounds.CornerMin() = Graphic3d_Vec4 (static_cast<Standard_ShortReal> (theXMin),
myBounds.YMin = Standard_ShortReal (theYMin); static_cast<Standard_ShortReal> (theYMin),
myBounds.ZMin = Standard_ShortReal (theZMin); static_cast<Standard_ShortReal> (theZMin),
myBounds.XMax = Standard_ShortReal (theXMax); 1.0f);
myBounds.YMax = Standard_ShortReal (theYMax); myBounds.CornerMax() = Graphic3d_Vec4 (static_cast<Standard_ShortReal> (theXMax),
myBounds.ZMax = Standard_ShortReal (theZMax); 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(); theXMin = theYMin = theZMin = ShortRealFirst();
theXMax = theYMax = theZMax = ShortRealLast(); 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 else
{ {
theXMin = Standard_Real (myBounds.XMin); // for consistency with old API
theYMin = Standard_Real (myBounds.YMin); theXMin = theYMin = theZMin = ShortRealLast();
theZMin = Standard_Real (myBounds.ZMin); theXMax = theYMax = theZMax = ShortRealFirst();
theXMax = Standard_Real (myBounds.XMax);
theYMax = Standard_Real (myBounds.YMax);
theZMax = Standard_Real (myBounds.ZMax);
} }
} }
@ -1039,10 +1027,7 @@ void Graphic3d_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray th
for (Standard_Integer aVertIter = 0; aVertIter < aNbVerts; ++aVertIter) for (Standard_Integer aVertIter = 0; aVertIter < aNbVerts; ++aVertIter)
{ {
const Graphic3d_Vec2& aVert = *reinterpret_cast<const Graphic3d_Vec2* >(theAttribs->value (aVertIter) + anOffset); const Graphic3d_Vec2& aVert = *reinterpret_cast<const Graphic3d_Vec2* >(theAttribs->value (aVertIter) + anOffset);
if (aVert.x() < myBounds.XMin) myBounds.XMin = aVert.x(); myBounds.Add (Graphic3d_Vec4 (aVert.x(), aVert.y(), 0.0f, 1.0f));
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();
} }
break; break;
} }
@ -1052,12 +1037,7 @@ void Graphic3d_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray th
for (Standard_Integer aVertIter = 0; aVertIter < aNbVerts; ++aVertIter) for (Standard_Integer aVertIter = 0; aVertIter < aNbVerts; ++aVertIter)
{ {
const Graphic3d_Vec3& aVert = *reinterpret_cast<const Graphic3d_Vec3* >(theAttribs->value (aVertIter) + anOffset); const Graphic3d_Vec3& aVert = *reinterpret_cast<const Graphic3d_Vec3* >(theAttribs->value (aVertIter) + anOffset);
if (aVert.x() < myBounds.XMin) myBounds.XMin = aVert.x(); myBounds.Add (Graphic3d_Vec4 (aVert.x(), aVert.y(), aVert.z(), 1.0f));
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();
} }
break; break;
} }
@ -1130,12 +1110,11 @@ void Graphic3d_Group::Text (const Standard_CString /*theText*/,
{ {
Standard_ShortReal x, y, z; Standard_ShortReal x, y, z;
thePoint.Coord (x, y, z); thePoint.Coord (x, y, z);
if (x < myBounds.XMin) myBounds.XMin = x; myStructure->CStructure()->Is2dText = Standard_True;
if (y < myBounds.YMin) myBounds.YMin = y; myBounds.Add (Graphic3d_Vec4 (static_cast<Standard_ShortReal> (x),
if (z < myBounds.ZMin) myBounds.ZMin = z; static_cast<Standard_ShortReal> (y),
if (x > myBounds.XMax) myBounds.XMax = x; static_cast<Standard_ShortReal> (z),
if (y > myBounds.YMax) myBounds.YMax = y; 1.0f));
if (z > myBounds.ZMax) myBounds.ZMax = z;
} }
Update(); Update();
} }
@ -1202,3 +1181,21 @@ Standard_Boolean Graphic3d_Group::IsClosed() const
{ {
return myIsClosed; 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, Vertex from Graphic3d,
TransModeFlags from Graphic3d, TransModeFlags from Graphic3d,
Pnt from gp, Pnt from gp,
SequenceOfHClipPlane from Graphic3d SequenceOfHClipPlane from Graphic3d,
BndBox4f from Graphic3d,
BndBox4d from Graphic3d
raises raises
@ -210,6 +212,12 @@ is
-- Warning: No more graphic operations in <me> after this call. -- Warning: No more graphic operations in <me> after this call.
-- Category: Methods to modify the class definition -- 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; SetHighlightColor ( me : mutable;
AColor : Color from Quantity ) AColor : Color from Quantity )
is static; is static;
@ -358,6 +366,14 @@ is
-- <LimitSup> is a negative value. -- <LimitSup> is a negative value.
raises StructureDefinitionError from Graphic3d is static; 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 ) UnHighlight ( me : mutable )
is static; is static;
---Level: Public ---Level: Public
@ -810,6 +826,17 @@ is
---Purpose: Get the current point of relative modelling transform persistence ---Purpose: Get the current point of relative modelling transform persistence
is static; 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 -- Category: Private methods
---------------------------- ----------------------------
@ -878,28 +905,16 @@ is
---Purpose: Returns the identification number of the structure <me>. ---Purpose: Returns the identification number of the structure <me>.
---Category: Private methods ---Category: Private methods
MinMaxCoord (me; minMaxCoord (me;
theXMin, theYMin, theZMin : out Real from Standard; theToIgnoreInfiniteFlag : Boolean from Standard = Standard_False)
theXMax, theYMax, theZMax : out Real from Standard) returns BndBox4f from Graphic3d
is static private; is static private;
---Level: Internal ---Purpose: Returns the extreme coordinates found in the structure <me> without transformation applied.
---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
MinMaxCoordWithDescendants (me; addTransformed (me;
theXMin, theYMin, theZMin : out Real from Standard; theBox : out BndBox4d from Graphic3d;
theXMax, theYMax, theZMax : out Real from Standard) theToIgnoreInfiniteFlag : Boolean from Standard = Standard_False)
is static private; 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
PrintNetwork ( myclass; PrintNetwork ( myclass;
AStructure : Structure from Graphic3d; AStructure : Structure from Graphic3d;

View File

@ -114,6 +114,32 @@ void Graphic3d_Structure::Clear (const Standard_Boolean theWithDestruction)
Update(); 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 //function : Remove
//purpose : //purpose :
@ -150,8 +176,6 @@ void Graphic3d_Structure::Remove()
((Graphic3d_Structure *)(myAncestors.ChangeValue (aStructIter)))->Remove (APtr, Graphic3d_TOC_DESCENDANT); ((Graphic3d_Structure *)(myAncestors.ChangeValue (aStructIter)))->Remove (APtr, Graphic3d_TOC_DESCENDANT);
} }
myCStructure->ContainsFacet = 0;
// Destruction of me in the graphic library // Destruction of me in the graphic library
const Standard_Integer aStructId = myCStructure->Id; const Standard_Integer aStructId = myCStructure->Id;
myCStructure->GraphicDriver()->RemoveStructure (myCStructure); myCStructure->GraphicDriver()->RemoveStructure (myCStructure);
@ -182,6 +206,15 @@ void Graphic3d_Structure::Display()
myCStructure->visible = 1; myCStructure->visible = 1;
} }
//=============================================================================
//function : SetIsForHighlight
//purpose :
//=============================================================================
void Graphic3d_Structure::SetIsForHighlight (const Standard_Boolean isForHighlight)
{
myCStructure->IsForHighlight = isForHighlight;
}
//============================================================================= //=============================================================================
//function : Display //function : Display
//purpose : //purpose :
@ -1375,6 +1408,7 @@ void Graphic3d_Structure::Connect (const Handle(Graphic3d_Structure)& theStructu
} }
myDescendants.Append (theStructure.operator->()); myDescendants.Append (theStructure.operator->());
CalculateBoundBox();
theStructure->Connect (this, Graphic3d_TOC_ANCESTOR); theStructure->Connect (this, Graphic3d_TOC_ANCESTOR);
GraphicConnect (theStructure); GraphicConnect (theStructure);
@ -1395,6 +1429,7 @@ void Graphic3d_Structure::Connect (const Handle(Graphic3d_Structure)& theStructu
} }
myAncestors.Append (theStructure.operator->()); myAncestors.Append (theStructure.operator->());
CalculateBoundBox();
theStructure->Connect (this, Graphic3d_TOC_DESCENDANT); theStructure->Connect (this, Graphic3d_TOC_DESCENDANT);
// myGraphicDriver->Connect is called in case if connection between parent and child // 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); GraphicDisconnect (theStructure);
myStructureManager->Disconnect (this, theStructure); myStructureManager->Disconnect (this, theStructure);
CalculateBoundBox();
Update(); Update();
return; return;
} }
@ -1434,6 +1471,7 @@ void Graphic3d_Structure::Disconnect (const Handle(Graphic3d_Structure)& theStru
{ {
myAncestors.Remove (anIter); myAncestors.Remove (anIter);
theStructure->Disconnect (this); theStructure->Disconnect (this);
CalculateBoundBox();
// no call of myGraphicDriver->Disconnect in case of an ancestor // no call of myGraphicDriver->Disconnect in case of an ancestor
return; return;
} }
@ -1608,6 +1646,7 @@ void Graphic3d_Structure::Transform (TColStd_Array2OfReal& theMatrix) const
} }
} }
//============================================================================= //=============================================================================
//function : MinMaxValues //function : MinMaxValues
//purpose : //purpose :
@ -1620,18 +1659,9 @@ void Graphic3d_Structure::MinMaxValues (Standard_Real& theXMin,
Standard_Real& theZMax, Standard_Real& theZMax,
const Standard_Boolean theToIgnoreInfiniteFlag) const const Standard_Boolean theToIgnoreInfiniteFlag) const
{ {
if (IsEmpty()) Graphic3d_BndBox4d aBox;
{ addTransformed (aBox, theToIgnoreInfiniteFlag);
return; if (!aBox.IsValid())
}
Standard_Real aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;
MinMaxCoord (aXMin, aYMin, aZMin, aXMax, aYMax, aZMax);
// Infinite boundaries corresponding to empty structure or
// non-empty structure, without any primitives specified
if (aXMin == RealFirst() && aYMin == RealFirst() && aZMin == RealFirst() &&
aXMax == RealLast() && aYMax == RealLast() && aZMax == RealLast())
{ {
theXMin = RealFirst(); theXMin = RealFirst();
theYMin = RealFirst(); theYMin = RealFirst();
@ -1642,86 +1672,12 @@ void Graphic3d_Structure::MinMaxValues (Standard_Real& theXMin,
return; return;
} }
// Handle flag, which specifies that structure should be considered as infinite theXMin = aBox.CornerMin().x();
if (IsInfinite() && !theToIgnoreInfiniteFlag) theYMin = aBox.CornerMin().y();
{ theZMin = aBox.CornerMin().z();
Graphic3d_Vertex aVertexMin (aXMin, aYMin, aZMin); theXMax = aBox.CornerMax().x();
Graphic3d_Vertex aVertexMax (aXMax, aYMax, aZMax); theYMax = aBox.CornerMax().y();
const Standard_Real aDistance = aVertexMin.Distance (aVertexMax); theZMax = aBox.CornerMax().z();
// 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;
} }
//============================================================================= //=============================================================================
@ -1756,6 +1712,7 @@ void Graphic3d_Structure::SetTransformPersistence (const Graphic3d_TransModeFlag
myCStructure->TransformPersistence.Point.y = float (thePoint.Y()); myCStructure->TransformPersistence.Point.y = float (thePoint.Y());
myCStructure->TransformPersistence.Point.z = float (thePoint.Z()); myCStructure->TransformPersistence.Point.z = float (thePoint.Z());
myCStructure->UpdateAspects(); myCStructure->UpdateAspects();
CalculateBoundBox();
myCStructure->TransformPersistence.IsSet = 1; myCStructure->TransformPersistence.IsSet = 1;
} }
@ -1855,154 +1812,79 @@ Handle(Graphic3d_StructureManager) Graphic3d_Structure::StructureManager() const
} }
//============================================================================= //=============================================================================
//function : MinMaxCoord //function : minMaxCoord
//purpose : //purpose :
//============================================================================= //=============================================================================
void Graphic3d_Structure::MinMaxCoord (Standard_Real& theXMin, Graphic3d_BndBox4f Graphic3d_Structure::minMaxCoord (const Standard_Boolean theToIgnoreInfiniteFlag) const
Standard_Real& theYMin,
Standard_Real& theZMin,
Standard_Real& theXMax,
Standard_Real& theYMax,
Standard_Real& theZMax) const
{ {
if (IsEmpty()) Graphic3d_BndBox4f aBnd;
{
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;
for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myCStructure->Groups()); aGroupIter.More(); aGroupIter.Next()) for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myCStructure->Groups()); aGroupIter.More(); aGroupIter.Next())
{ {
const Handle(Graphic3d_Group)& aGroup = aGroupIter.Value(); if (!theToIgnoreInfiniteFlag)
if (aGroup->IsEmpty())
{ {
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);
} }
return aBnd;
// 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;
} }
//============================================================================= //=============================================================================
//function : MinMaxCoordWithDescendants //function : addTransformed
//purpose : //purpose :
//============================================================================= //=============================================================================
void Graphic3d_Structure::MinMaxCoordWithDescendants (Standard_Real& theXMin, void Graphic3d_Structure::addTransformed (Graphic3d_BndBox4d& theBox,
Standard_Real& theYMin, const Standard_Boolean theToIgnoreInfiniteFlag) const
Standard_Real& theZMin,
Standard_Real& theXMax,
Standard_Real& theYMax,
Standard_Real& theZMax) const
{ {
if (IsEmpty()) Graphic3d_BndBox4d aBox;
Graphic3d_BndBox4f aBoxF = minMaxCoord (theToIgnoreInfiniteFlag);
if (aBoxF.IsValid())
{ {
theXMin = RealFirst(); aBox = Graphic3d_BndBox4d (Graphic3d_Vec4d ((Standard_Real )aBoxF.CornerMin().x(),
theYMin = RealFirst(); (Standard_Real )aBoxF.CornerMin().y(),
theZMin = RealFirst(); (Standard_Real )aBoxF.CornerMin().z(),
theXMax = RealLast(); (Standard_Real )aBoxF.CornerMin().w()),
theYMax = RealLast(); Graphic3d_Vec4d ((Standard_Real )aBoxF.CornerMax().x(),
theZMax = RealLast(); (Standard_Real )aBoxF.CornerMax().y(),
return; (Standard_Real )aBoxF.CornerMax().z(),
} (Standard_Real )aBoxF.CornerMax().w()));
if (IsInfinite()
Standard_Real aXMin, aYMin, aZMin, aXMax, aYMax, aZMax; && !theToIgnoreInfiniteFlag)
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())
{ {
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() || for (Standard_Integer aStructIt = 1; aStructIt <= myDescendants.Length(); ++aStructIt)
aDescZMin != RealLast() || aDescXMax != RealFirst() ||
aDescYMax != RealFirst() || aDescZMax != RealFirst())
{ {
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); Transform (aTrsf);
TransformBoundaries (aTrsf, aDescXMin, aDescYMin, aDescZMin, aDescXMax, aDescYMax, aDescZMax); TransformBoundaries (aTrsf, aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z(),
aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z());
aXMin = Min (aDescXMin, aXMin); theBox.Combine (aBox);
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
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: 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); myHighlightColor.Values (anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB);
myCStructure->BoundBox.Color.r = float (anRGB[0]); myCStructure->HighlightColor.r = float (anRGB[0]);
myCStructure->BoundBox.Color.g = float (anRGB[1]); myCStructure->HighlightColor.g = float (anRGB[1]);
myCStructure->BoundBox.Color.b = float (anRGB[2]); myCStructure->HighlightColor.b = float (anRGB[2]);
myCStructure->HighlightWithBndBox (this, Standard_True); myCStructure->HighlightWithBndBox (this, Standard_True);
break; break;
} }
@ -2531,3 +2396,21 @@ const Graphic3d_SequenceOfHClipPlane& Graphic3d_Structure::GetClipPlanes() const
{ {
return myCStructure->ClipPlanes(); 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 #define InterfaceGraphic_Graphic3dHeader
#include <InterfaceGraphic_telem.hxx> #include <InterfaceGraphic_telem.hxx>
#include <Graphic3d_BndBox4f.hxx>
#include <Standard_Transient.hxx> #include <Standard_Transient.hxx>
/* COULEUR */ /* COULEUR */
@ -34,18 +35,6 @@ typedef struct {
} CALL_DEF_POINT; } CALL_DEF_POINT;
/* BOITE ENGLOBANTE */
typedef struct {
CALL_DEF_COLOR Color;
CALL_DEF_POINT Pmin;
CALL_DEF_POINT Pmax;
} CALL_DEF_BOUNDBOX;
/* MATERIAL */ /* MATERIAL */
typedef struct { typedef struct {
@ -85,26 +74,12 @@ typedef struct
CALL_DEF_POINT Point; CALL_DEF_POINT Point;
} CALL_DEF_TRANSFORM_PERSISTENCE; } 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 */ /* USERDRAW DATA */
typedef struct { typedef struct {
void *Data; void *Data;
CALL_DEF_BOUNDS *Bounds; Graphic3d_BndBox4f *Bounds;
} CALL_DEF_USERDRAW; } CALL_DEF_USERDRAW;

View File

@ -315,7 +315,7 @@ public:
//! Compute per-component division by scale factor. //! Compute per-component division by scale factor.
NCollection_Vec4 operator/ (const Element_t theInvFactor) NCollection_Vec4 operator/ (const Element_t theInvFactor)
{ {
NCollection_Vec4 aResult(this); NCollection_Vec4 aResult(*this);
return aResult /= theInvFactor; return aResult /= theInvFactor;
} }

View File

@ -143,3 +143,7 @@ OpenGl_SceneGeometry.cxx
OpenGl_Workspace_Raytrace.cxx OpenGl_Workspace_Raytrace.cxx
OpenGl_Flipper.hxx OpenGl_Flipper.hxx
OpenGl_Flipper.cxx 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 Standard_Integer theLayerId,
const Graphic3d_ZLayerSettings& theSettings); 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: public:
//! @return the visualization options //! @return the visualization options
@ -315,6 +320,10 @@ public:
//! Could return NULL-handle if no window created by this driver. //! Could return NULL-handle if no window created by this driver.
Standard_EXPORT const Handle(OpenGl_Context)& GetSharedContext() const; 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: public:
DEFINE_STANDARD_RTTI(OpenGl_GraphicDriver) DEFINE_STANDARD_RTTI(OpenGl_GraphicDriver)

View File

@ -127,3 +127,21 @@ void OpenGl_GraphicDriver::UnsetZLayer (const Standard_Integer theLayerId)
aStruct->SetZLayer (0); 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); 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) Standard_Boolean OpenGl_GraphicDriver::View (Graphic3d_CView& theCView)
{ {
if (myMapOfView.IsBound (theCView.ViewId) 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, void OpenGl_LayerList::AddStructure (const OpenGl_Structure *theStructure,
const Standard_Integer theLayerId, const Standard_Integer theLayerId,
const Standard_Integer thePriority) const Standard_Integer thePriority,
Standard_Boolean isForChangePriority)
{ {
// add structure to associated layer, // add structure to associated layer,
// if layer doesn't exists, display structure in default layer // if layer doesn't exists, display structure in default layer
OpenGl_PriorityList& aList = !HasLayer (theLayerId) ? defaultLayer ().PriorityList() : OpenGl_PriorityList& aList = !HasLayer (theLayerId) ? defaultLayer ().PriorityList() :
myLayers.ChangeValue (myLayerIds.Find (theLayerId)).PriorityList(); myLayers.ChangeValue (myLayerIds.Find (theLayerId)).PriorityList();
aList.Add (theStructure, thePriority); aList.Add (theStructure, thePriority, isForChangePriority);
myNbStructures++; myNbStructures++;
// Note: In ray-tracing mode we don't modify modification // 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 //function : ChangeLayer
//purpose : //purpose :
@ -239,10 +254,10 @@ void OpenGl_LayerList::ChangeLayer (const OpenGl_Structure *theStructure,
// take priority and remove structure from list found by <theOldLayerId> // take priority and remove structure from list found by <theOldLayerId>
// if the structure is not found there, scan through all other layers // 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--; myNbStructures--;
AddStructure (theStructure, theNewLayerId, aPriority); AddStructure (theStructure, theNewLayerId, aPriority, Standard_True);
} }
else else
{ {
@ -255,10 +270,47 @@ void OpenGl_LayerList::ChangeLayer (const OpenGl_Structure *theStructure,
continue; continue;
// try to remove structure and get priority value from this layer // 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--; 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; break;
} }
} }

View File

@ -60,7 +60,8 @@ class OpenGl_LayerList
//! to default bottom-level layer. //! to default bottom-level layer.
void AddStructure (const OpenGl_Structure *theStructure, void AddStructure (const OpenGl_Structure *theStructure,
const Standard_Integer theLayerId, 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 //! Remove structure from structure list and return its previous priority
void RemoveStructure (const OpenGl_Structure *theStructure, void RemoveStructure (const OpenGl_Structure *theStructure,
@ -73,6 +74,11 @@ class OpenGl_LayerList
const Standard_Integer theOldLayerId, const Standard_Integer theOldLayerId,
const Standard_Integer theNewLayerId); 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. //! Returns reference to the layer with given ID.
OpenGl_Layer& Layer (const Standard_Integer theLayerId); OpenGl_Layer& Layer (const Standard_Integer theLayerId);
@ -85,6 +91,10 @@ class OpenGl_LayerList
//! Returns the set of OpenGL Z-layers. //! Returns the set of OpenGL Z-layers.
const OpenGl_SequenceOfLayers& Layers() const { return myLayers; } 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). //! Returns structure modification state (for ray-tracing).
Standard_Size ModificationState() const { return myModificationState; } Standard_Size ModificationState() const { return myModificationState; }

View File

@ -15,36 +15,78 @@
#include <OpenGl_PriorityList.hxx> #include <OpenGl_PriorityList.hxx>
#include <OpenGl_BVHTreeSelector.hxx>
#include <OpenGl_Structure.hxx> #include <OpenGl_Structure.hxx>
#include <OpenGl_View.hxx>
/*----------------------------------------------------------------------*/ // =======================================================================
// function : OpenGl_PriorityList
void OpenGl_PriorityList::Add (const OpenGl_Structure *AStructure,const Standard_Integer APriority) // 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++;
} }
/*----------------------------------------------------------------------*/ // =======================================================================
// function : ~OpenGl_PriorityList
Standard_Integer OpenGl_PriorityList::Remove (const OpenGl_Structure *AStructure) // 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); theStructure->MarkAsNotCulled();
for (its.Init(aSeq); its.More(); its.Next()) }
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); aSeq.Remove (aStructIter);
myNbStructures--; if (!theStructure->IsAlwaysRendered()
return i; && !isForChangePriority)
{
myBVHPrimitives.Remove (theStructure);
}
--myNbStructures;
return aPriorityIter;
} }
} }
} }
@ -52,50 +94,177 @@ Standard_Integer OpenGl_PriorityList::Remove (const OpenGl_Structure *AStructure
return -1; return -1;
} }
/*----------------------------------------------------------------------*/ // =======================================================================
// function : InvalidateBVHData
void OpenGl_PriorityList::Render (const Handle(OpenGl_Workspace) &AWorkspace) const // purpose :
// =======================================================================
void OpenGl_PriorityList::InvalidateBVHData()
{ {
const Standard_Integer aNbPr = myArray.Length(); myIsBVHPrimitivesNeedsReset = Standard_True;
Standard_Integer i = 0; }
OpenGl_SequenceOfStructure::Iterator its;
for (; i < aNbPr; i++) // =======================================================================
// 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()) for (aStructIter.Init (myArray (aPriorityIter)); aStructIter.More(); aStructIter.Next())
its.Value()->Render(AWorkspace); {
aStructIter.Value()->Render (theWorkspace);
}
} }
} }
//======================================================================= // =======================================================================
//function : Append // function : renderTraverse
//purpose : // 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) Standard_Boolean OpenGl_PriorityList::Append (const OpenGl_PriorityList& theOther)
{ {
// the source priority list shouldn't have more priorities // the source priority list shouldn't have more priorities
const Standard_Integer aNbPriorities = theOther.NbPriorities (); const Standard_Integer aNbPriorities = theOther.NbPriorities ();
if (aNbPriorities > NbPriorities ()) if (aNbPriorities > NbPriorities())
{
return Standard_False; return Standard_False;
}
// add all structures to destination priority list // add all structures to destination priority list
Standard_Integer aIdx = 0; OpenGl_SequenceOfStructure::Iterator aStructIter;
OpenGl_SequenceOfStructure::Iterator anIts; for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
for (; aIdx < aNbPriorities; aIdx++)
{ {
const OpenGl_SequenceOfStructure& aSeq = theOther.myArray (aIdx); const OpenGl_SequenceOfStructure& aSeq = theOther.myArray (aPriorityIter);
for (anIts.Init (aSeq); anIts.More (); anIts.Next ()) for (aStructIter.Init (aSeq); aStructIter.More(); aStructIter.Next())
Add (anIts.Value (), aIdx); {
Add (aStructIter.Value(), aPriorityIter);
}
} }
return Standard_True; return Standard_True;
} }
//======================================================================= // =======================================================================
//function : NbPriorities // function : NbPriorities
//purpose : // purpose :
//======================================================================= // =======================================================================
Standard_Integer OpenGl_PriorityList::NbPriorities() const Standard_Integer OpenGl_PriorityList::NbPriorities() const
{ {
return myArray.Length(); return myArray.Length();

View File

@ -22,6 +22,8 @@
#include <InterfaceGraphic_telem.hxx> #include <InterfaceGraphic_telem.hxx>
#include <Handle_OpenGl_Workspace.hxx> #include <Handle_OpenGl_Workspace.hxx>
#include <OpenGl_BVHClipPrimitiveSet.hxx>
#include <OpenGl_BVHTreeSelector.hxx>
class OpenGl_Structure; class OpenGl_Structure;
@ -30,21 +32,27 @@ typedef NCollection_Array1<OpenGl_SequenceOfStructure> OpenGl_ArrayOfStructure;
class OpenGl_PriorityList 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, //! Remove structure and returns its priority, if the structure is not found, method returns negative value
//! method returns negative value Standard_Integer Remove (const OpenGl_Structure* theStructure,
Standard_Integer Remove (const OpenGl_Structure *AStructure); 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 //! Returns the number of available priority levels
Standard_Integer NbPriorities() const; Standard_Integer NbPriorities() const;
@ -56,13 +64,33 @@ class OpenGl_PriorityList
//! Returns array of OpenGL structures. //! Returns array of OpenGL structures.
const OpenGl_ArrayOfStructure& ArrayOfStructures() const { return myArray; } 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; protected:
Standard_Integer myNbStructures;
//! 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 DEFINE_STANDARD_ALLOC
}; };
#endif //_OpenGl_PriorityList_Header #endif // _OpenGl_PriorityList_Header

View File

@ -18,9 +18,9 @@
#ifdef HAVE_TBB #ifdef HAVE_TBB
// On Windows, function TryEnterCriticalSection has appeared in Windows NT // On Windows, function TryEnterCriticalSection has appeared in Windows NT
// and is surrounded by #ifdef in MS VC++ 7.1 headers. // 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 // 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 #define _WIN32_WINNT 0x0501
#endif #endif
@ -29,6 +29,9 @@
#include <OpenGl_SceneGeometry.hxx> #include <OpenGl_SceneGeometry.hxx>
#include <OpenGl_PrimitiveArray.hxx>
#include <OpenGl_Structure.hxx>
//! Use this macro to output BVH profiling info //! Use this macro to output BVH profiling info
//#define BVH_PRINT_INFO //#define BVH_PRINT_INFO

View File

@ -19,8 +19,11 @@
#include <BVH_Geometry.hxx> #include <BVH_Geometry.hxx>
#include <BVH_Triangulation.hxx> #include <BVH_Triangulation.hxx>
#include <NCollection_StdAllocator.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 namespace OpenGl_Raytrace
{ {

View File

@ -37,14 +37,15 @@ class OpenGl_BndBoxPrs : public OpenGl_Element
public: public:
//! Main constructor //! Main constructor
OpenGl_BndBoxPrs (const CALL_DEF_BOUNDBOX& theBndBox) OpenGl_BndBoxPrs (const Graphic3d_BndBox4f& theBndBox)
{ {
const float Xm = theBndBox.Pmin.x; const float Xm = theBndBox.CornerMin().x();
const float Ym = theBndBox.Pmin.y; const float Ym = theBndBox.CornerMin().y();
const float Zm = theBndBox.Pmin.z; const float Zm = theBndBox.CornerMin().z();
const float XM = theBndBox.Pmax.x; const float XM = theBndBox.CornerMax().x();
const float YM = theBndBox.Pmax.y; const float YM = theBndBox.CornerMax().y();
const float ZM = theBndBox.Pmax.z; const float ZM = theBndBox.CornerMax().z();
myVerts[0] = OpenGl_Vec3 (Xm, Ym, Zm); myVerts[0] = OpenGl_Vec3 (Xm, Ym, Zm);
myVerts[1] = OpenGl_Vec3 (Xm, Ym, ZM); myVerts[1] = OpenGl_Vec3 (Xm, Ym, ZM);
myVerts[2] = 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), myNamedStatus(0),
myZLayer(0), myZLayer(0),
myIsRaytracable (Standard_False), myIsRaytracable (Standard_False),
myModificationState (0) myModificationState (0),
myIsCulled (Standard_True)
{ {
UpdateNamedStatus(); UpdateNamedStatus();
} }
@ -212,6 +214,7 @@ void OpenGl_Structure::SetTransformPersistence(const CALL_DEF_TRANSFORM_PERSISTE
myTransPers->pointX = ATransPers.Point.x; myTransPers->pointX = ATransPers.Point.x;
myTransPers->pointY = ATransPers.Point.y; myTransPers->pointY = ATransPers.Point.y;
myTransPers->pointZ = ATransPers.Point.z; 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(); CALL_DEF_CONTEXTLINE& aContextLine = myHighlightBox->ChangeContextLine();
aContextLine.IsDef = 1; aContextLine.IsDef = 1;
aContextLine.Color = BoundBox.Color; aContextLine.Color = HighlightColor;
aContextLine.LineType = Aspect_TOL_SOLID; aContextLine.LineType = Aspect_TOL_SOLID;
aContextLine.Width = 1.0f; aContextLine.Width = 1.0f;
myHighlightBox->UpdateAspectLine (Standard_True); myHighlightBox->UpdateAspectLine (Standard_True);
OpenGl_BndBoxPrs* aBndBoxPrs = new OpenGl_BndBoxPrs (BoundBox); OpenGl_BndBoxPrs* aBndBoxPrs = new OpenGl_BndBoxPrs (myBndBox);
myHighlightBox->AddElement (aBndBoxPrs); myHighlightBox->AddElement (aBndBoxPrs);
} }
@ -598,6 +601,9 @@ void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
UpdateStateWithAncestorStructures(); UpdateStateWithAncestorStructures();
UpdateRaytracableWithAncestorStructures(); 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 ) if ( myNamedStatus & OPENGL_NS_HIDE )
return; return;
const Handle(OpenGl_Context)& aCtx = AWorkspace->GetGlContext();
// Render named status // Render named status
const Standard_Integer named_status = AWorkspace->NamedStatus; const Standard_Integer named_status = AWorkspace->NamedStatus;
AWorkspace->NamedStatus |= myNamedStatus; AWorkspace->NamedStatus |= myNamedStatus;
@ -617,8 +625,6 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
// Is rendering in ADD or IMMEDIATE mode? // Is rendering in ADD or IMMEDIATE mode?
const Standard_Boolean isImmediate = (AWorkspace->NamedStatus & OPENGL_NS_IMMEDIATE) != 0; const Standard_Boolean isImmediate = (AWorkspace->NamedStatus & OPENGL_NS_IMMEDIATE) != 0;
const Handle(OpenGl_Context)& aCtx = AWorkspace->GetGlContext();
// Apply local transformation // Apply local transformation
GLint matrix_mode = 0; GLint matrix_mode = 0;
const OpenGl_Matrix *local_trsf = NULL; const OpenGl_Matrix *local_trsf = NULL;
@ -678,12 +684,6 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
if (myAspectText) if (myAspectText)
AWorkspace->SetAspectText(myAspectText); AWorkspace->SetAspectText(myAspectText);
// Apply highlight box
if (!myHighlightBox.IsNull())
{
myHighlightBox->Render (AWorkspace);
}
// Apply highlight color // Apply highlight color
const TEL_COLOUR *highlight_color = AWorkspace->HighlightColor; const TEL_COLOUR *highlight_color = AWorkspace->HighlightColor;
if (myHighlightColor) 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 // Restore named status
AWorkspace->NamedStatus = named_status; AWorkspace->NamedStatus = named_status;
} }
@ -872,6 +878,7 @@ Standard_Integer OpenGl_Structure::GetZLayer () const
return myZLayer; return myZLayer;
} }
//! Dummy structure which just redirects to groups of another structure.
class OpenGl_StructureShadow : public OpenGl_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_HANDLE (OpenGl_StructureShadow, OpenGl_Structure)
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_StructureShadow, OpenGl_Structure) IMPLEMENT_STANDARD_RTTIEXT(OpenGl_StructureShadow, OpenGl_Structure)
//=======================================================================
//function : OpenGl_StructureShadow
//purpose :
//=======================================================================
OpenGl_StructureShadow::OpenGl_StructureShadow (const Handle(Graphic3d_StructureManager)& theManager, OpenGl_StructureShadow::OpenGl_StructureShadow (const Handle(Graphic3d_StructureManager)& theManager,
const Handle(OpenGl_Structure)& theStructure) const Handle(OpenGl_Structure)& theStructure)
: OpenGl_Structure (theManager) : OpenGl_Structure (theManager)

View File

@ -27,6 +27,8 @@
#include <OpenGl_Group.hxx> #include <OpenGl_Group.hxx>
#include <OpenGl_Matrix.hxx> #include <OpenGl_Matrix.hxx>
#include <OpenGl_NamedStatus.hxx> #include <OpenGl_NamedStatus.hxx>
#include <OpenGl_Vec.hxx>
#include <OpenGl_Workspace.hxx>
#include <NCollection_List.hxx> #include <NCollection_List.hxx>
#include <InterfaceGraphic_Graphic3d.hxx> #include <InterfaceGraphic_Graphic3d.hxx>
@ -140,6 +142,34 @@ public:
virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const; virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const;
virtual void Release (const Handle(OpenGl_Context)& theGlCtx); 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. //! This method releases GL resources without actual elements destruction.
//! As result structure could be correctly destroyed layer without GL context //! As result structure could be correctly destroyed layer without GL context
//! (after last window was closed for example). //! (after last window was closed for example).
@ -212,6 +242,8 @@ protected:
mutable Standard_Boolean myIsRaytracable; mutable Standard_Boolean myIsRaytracable;
mutable Standard_Size myModificationState; mutable Standard_Size myModificationState;
mutable Standard_Boolean myIsCulled; //!< A status specifying is structure needs to be rendered after BVH tree traverse.
public: public:
DEFINE_STANDARD_RTTI(OpenGl_Structure) // Type definition DEFINE_STANDARD_RTTI(OpenGl_Structure) // Type definition

View File

@ -37,6 +37,7 @@
#include <Graphic3d_ZLayerSettings.hxx> #include <Graphic3d_ZLayerSettings.hxx>
#include <Visual3d_TypeOfSurfaceDetail.hxx> #include <Visual3d_TypeOfSurfaceDetail.hxx>
#include <OpenGl_BVHTreeSelector.hxx>
#include <OpenGl_LayerList.hxx> #include <OpenGl_LayerList.hxx>
#include <OpenGl_Light.hxx> #include <OpenGl_Light.hxx>
#include <OpenGl_LineAttributes.hxx> #include <OpenGl_LineAttributes.hxx>
@ -164,6 +165,10 @@ class OpenGl_View : public MMgt_TShared
void SetZLayerSettings (const Standard_Integer theLayerId, void SetZLayerSettings (const Standard_Integer theLayerId,
const Graphic3d_ZLayerSettings theSettings); 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 CreateBackgroundTexture (const Standard_CString AFileName, const Aspect_FillMethod AFillStyle);
void SetBackgroundTextureStyle (const Aspect_FillMethod FillStyle); void SetBackgroundTextureStyle (const Aspect_FillMethod FillStyle);
void SetBackgroundGradient (const Quantity_Color& AColor1, const Quantity_Color& AColor2, const Aspect_GradientFillMethod AType); 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. //! Returns visualization mode for objects in the view.
Visual3d_TypeOfSurfaceDetail SurfaceDetail() const { return mySurfaceDetail; } 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, void GetMatrices (TColStd_Array2OfReal& theMatOrient,
TColStd_Array2OfReal& theMatMapping) const; TColStd_Array2OfReal& theMatMapping) const;
@ -273,6 +286,9 @@ protected:
StateInfo myLastViewMappingState; StateInfo myLastViewMappingState;
StateInfo myLastLightSourceState; StateInfo myLastLightSourceState;
//! Is needed for selection of overlapping objects and storage of the current view volume
OpenGl_BVHTreeSelector myBVHSelector;
Standard_Size myModificationState; Standard_Size myModificationState;
public: 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 // Set OCCT state uniform variables
const Handle(OpenGl_ShaderManager) aManager = aContext->ShaderManager(); const Handle(OpenGl_ShaderManager) aManager = aContext->ShaderManager();
if (!aManager->IsEmpty()) 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 // 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 //ExecuteViewDisplay
@ -1033,6 +1061,16 @@ void OpenGl_View::SetZLayerSettings (const Standard_Integer theLayerId,
myZLayers.Layer (theLayerId).SetLayerSettings (theSettings); 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 //function : RedrawScene

View File

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

View File

@ -64,6 +64,7 @@ class OpenGl_AspectMarker;
class OpenGl_AspectText; class OpenGl_AspectText;
class OpenGl_FrameBuffer; class OpenGl_FrameBuffer;
class OpenGl_Structure; class OpenGl_Structure;
class OpenGl_TriangleSet;
class OpenGl_Element; class OpenGl_Element;
class Image_PixMap; class Image_PixMap;
@ -224,6 +225,9 @@ public:
//! Returns currently applied polygon offset params. //! Returns currently applied polygon offset params.
const TEL_POFFSET_PARAM& AppliedPolygonOffset() { return PolygonOffset_applied; } const TEL_POFFSET_PARAM& AppliedPolygonOffset() { return PolygonOffset_applied; }
//! @return true if clipping algorithm enabled
inline Standard_Boolean IsCullingEnabled() const { return myIsCullingEnabled; }
protected: protected:
//! Copy content of Back buffer to the Front buffer //! Copy content of Back buffer to the Front buffer
@ -599,6 +603,7 @@ protected: //! @name protected fields
Standard_Boolean myUseZBuffer; Standard_Boolean myUseZBuffer;
Standard_Boolean myUseDepthTest; Standard_Boolean myUseDepthTest;
Standard_Boolean myUseGLLight; Standard_Boolean myUseGLLight;
Standard_Boolean myIsCullingEnabled; //!< frustum culling flag
protected: //! @name fields related to status protected: //! @name fields related to status

View File

@ -13,13 +13,15 @@
// Alternatively, this file may be used under the terms of Open CASCADE // Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement. // commercial license or contractual agreement.
#include <OpenGl_Workspace.hxx>
#include <NCollection_Mat4.hxx> #include <NCollection_Mat4.hxx>
#include <OpenGl_ArbFBO.hxx> #include <OpenGl_ArbFBO.hxx>
#include <OpenGl_FrameBuffer.hxx> #include <OpenGl_FrameBuffer.hxx>
#include <OpenGl_PrimitiveArray.hxx>
#include <OpenGl_Texture.hxx> #include <OpenGl_Texture.hxx>
#include <OpenGl_VertexBuffer.hxx> #include <OpenGl_VertexBuffer.hxx>
#include <OpenGl_View.hxx> #include <OpenGl_View.hxx>
#include <OpenGl_Workspace.hxx>
#include <OSD_File.hxx> #include <OSD_File.hxx>
#include <OSD_Protection.hxx> #include <OSD_Protection.hxx>
#include <Standard_Assert.hxx> #include <Standard_Assert.hxx>

View File

@ -91,6 +91,12 @@ is
---Purpose: displays the whole content of the presentation in the specified color. ---Purpose: displays the whole content of the presentation in the specified color.
BoundBox(me: mutable) is static; 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. ---Category: Global modification methods.
SetShadingAspect(me: mutable; aShadingAspect: ShadingAspect from Prs3d); 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 //function : Compute
//purpose : //purpose :
//======================================================================= //=======================================================================

View File

@ -277,6 +277,16 @@ is
---Purpose: Get clip planes. ---Purpose: Get clip planes.
-- @return set of previously added clip planes for all display mode presentations. -- @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; UpdateClipping (me : mutable) is virtual protected;
---Purpose: General virtual method for internal update of presentation state ---Purpose: General virtual method for internal update of presentation state
-- when some modifications on list of clip planes occurs. Base -- when some modifications on list of clip planes occurs. Base
@ -287,8 +297,8 @@ fields
myTypeOfPresentation3d: TypeOfPresentation3d from PrsMgr is protected; myTypeOfPresentation3d: TypeOfPresentation3d from PrsMgr is protected;
myLocation : Location from TopLoc is protected; myLocation : Location from TopLoc is protected;
myClipPlanes : SequenceOfHClipPlane from Graphic3d is protected; myClipPlanes : SequenceOfHClipPlane from Graphic3d is protected;
--myTransformPersistence : TransModeFlags from Graphic3d;
myTransformPersistence : CTransPersStruct from Graphic3d; myTransformPersistence : CTransPersStruct from Graphic3d;
myIsMutable : Boolean from Standard is protected;
friends friends
class Presentation from PrsMgr, class Presentation from PrsMgr,

View File

@ -27,8 +27,9 @@
//function : PrsMgr_PresentableObject //function : PrsMgr_PresentableObject
//purpose : //purpose :
//======================================================================= //=======================================================================
PrsMgr_PresentableObject::PrsMgr_PresentableObject(const PrsMgr_TypeOfPresentation3d aTypeOfPresentation3d) PrsMgr_PresentableObject::PrsMgr_PresentableObject (const PrsMgr_TypeOfPresentation3d theType)
:myPresentations(),myTypeOfPresentation3d(aTypeOfPresentation3d) : myTypeOfPresentation3d (theType),
myIsMutable (Standard_False)
{ {
myTransformPersistence.Flag = 0; myTransformPersistence.Flag = 0;
myTransformPersistence.Point.x = 0.0; myTransformPersistence.Point.x = 0.0;
@ -294,6 +295,7 @@ void PrsMgr_PresentableObject::SetTransformPersistence (const Graphic3d_TransMod
&& !aPrs3d->Presentation().IsNull()) && !aPrs3d->Presentation().IsNull())
{ {
aPrs3d->Presentation()->SetTransformPersistence (theFlag, thePoint); aPrs3d->Presentation()->SetTransformPersistence (theFlag, thePoint);
aPrs3d->Presentation()->ReCompute();
} }
} }
} }
@ -414,3 +416,37 @@ void PrsMgr_PresentableObject::UpdateClipping()
aModedPrs.Presentation()->Presentation()->SetClipPlanes (myClipPlanes); 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(), myStructure = new PrsMgr_Prs (thePrsMgr->StructureManager(),
this, thePrsObject->TypeOfPresentation3d()); this, thePrsObject->TypeOfPresentation3d());
myStructure->SetOwner (myPresentableObject); myStructure->SetOwner (myPresentableObject);
myStructure->SetMutable (myPresentableObject->IsMutable());
} }
//======================================================================= //=======================================================================
@ -68,15 +69,17 @@ void PrsMgr_Presentation::Display()
//function : Display //function : Display
//purpose : //purpose :
//======================================================================= //=======================================================================
void PrsMgr_Presentation::Display (const Standard_Boolean /*theIsHighlight*/) void PrsMgr_Presentation::Display (const Standard_Boolean theIsHighlight)
{ {
if (!myStructure->IsDisplayed()) if (!myStructure->IsDisplayed())
{ {
myStructure->SetIsForHighlight (theIsHighlight);
myStructure->Display(); myStructure->Display();
} }
else if (!myStructure->IsVisible()) else if (!myStructure->IsVisible())
{ {
SetVisible (Standard_True); SetVisible (Standard_True);
myStructure->SetIsForHighlight (theIsHighlight);
} }
} }

View File

@ -270,6 +270,20 @@ inline Standard_Integer RealToInt (const Standard_Real Value)
: (Standard_Integer)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 // Round : Returns the nearest integer of a real
//------------------------------------------------------------------- //-------------------------------------------------------------------

View File

@ -1629,6 +1629,14 @@ is
---Level: Public ---Level: Public
---Purpose: Returns reference to current rendering parameters and effect settings. ---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 fields
myOldMouseX : Real is protected; myOldMouseX : Real is protected;

View File

@ -3392,3 +3392,23 @@ void V3d_View::Translate (const Handle(Graphic3d_Camera)& theCamera,
theCamera->Transform (aPanTrsf); 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; ViewerTest_RedrawMode aToUpdate = ViewerTest_RM_Auto;
Standard_Boolean isContextOnly = Standard_False; Standard_Boolean isContextOnly = Standard_False;
Standard_Boolean toRemoveAll = Standard_False; Standard_Boolean toRemoveAll = Standard_False;
Standard_Boolean toPrintInfo = Standard_True;
Standard_Integer anArgIter = 1; Standard_Integer anArgIter = 1;
for (; anArgIter < theArgNb; ++anArgIter) for (; anArgIter < theArgNb; ++anArgIter)
@ -2042,6 +2043,10 @@ int VRemove (Draw_Interpretor& theDI,
{ {
toRemoveAll = Standard_True; toRemoveAll = Standard_True;
} }
else if (anArg == "-noinfo")
{
toPrintInfo = Standard_False;
}
else if (!parseRedrawMode (anArg, aToUpdate)) else if (!parseRedrawMode (anArg, aToUpdate))
{ {
break; break;
@ -2133,11 +2138,13 @@ int VRemove (Draw_Interpretor& theDI,
anIter.More(); anIter.Next()) anIter.More(); anIter.Next())
{ {
const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (anIter.Value())); const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (anIter.Value()));
if (!anIO.IsNull()) if (!anIO.IsNull())
{ {
TheAISContext()->Remove (anIO, Standard_False); TheAISContext()->Remove (anIO, Standard_False);
theDI << anIter.Value().ToCString() << " was removed\n"; if (toPrintInfo)
{
theDI << anIter.Value().ToCString() << " was removed\n";
}
} }
else else
{ {
@ -2145,10 +2152,12 @@ int VRemove (Draw_Interpretor& theDI,
if (!aNisIO.IsNull()) if (!aNisIO.IsNull())
{ {
TheNISContext()->Remove (aNisIO); TheNISContext()->Remove (aNisIO);
theDI << anIter.Value().ToCString() << " was removed\n"; if (toPrintInfo)
{
theDI << anIter.Value().ToCString() << " was removed\n";
}
} }
} }
if (!isContextOnly) if (!isContextOnly)
{ {
GetMapOfAIS().UnBind2 (anIter.Value()); GetMapOfAIS().UnBind2 (anIter.Value());
@ -2854,19 +2863,31 @@ static int VDisplay2 (Draw_Interpretor& theDI,
} }
ViewerTest_RedrawMode aToUpdate = ViewerTest_RM_Auto; ViewerTest_RedrawMode aToUpdate = ViewerTest_RM_Auto;
Standard_Integer isMutable = -1;
for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter) 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)) if (parseRedrawMode (aName, aToUpdate))
{ {
continue; continue;
} }
else if (aNameCase == "-mutable")
{
isMutable = 1;
continue;
}
else if (!GetMapOfAIS().IsBound2 (aName)) else if (!GetMapOfAIS().IsBound2 (aName))
{ {
// create the AIS_Shape from a name // create the AIS_Shape from a name
const Handle(AIS_InteractiveObject) aShape = GetAISShapeFromName (aName.ToCString()); const Handle(AIS_InteractiveObject) aShape = GetAISShapeFromName (aName.ToCString());
if (!aShape.IsNull()) if (!aShape.IsNull())
{ {
if (isMutable != -1)
{
aShape->SetMutable (isMutable == 1);
}
GetMapOfAIS().Bind (aShape, aName); GetMapOfAIS().Bind (aShape, aName);
aCtx->Display (aShape, Standard_False); aCtx->Display (aShape, Standard_False);
} }
@ -2877,6 +2898,11 @@ static int VDisplay2 (Draw_Interpretor& theDI,
if (anObj->IsKind (STANDARD_TYPE (AIS_InteractiveObject))) if (anObj->IsKind (STANDARD_TYPE (AIS_InteractiveObject)))
{ {
Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (anObj); Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (anObj);
if (isMutable != -1)
{
aShape->SetMutable (isMutable == 1);
}
if (aShape->Type() == AIS_KOI_Datum) if (aShape->Type() == AIS_KOI_Datum)
{ {
aCtx->Display (aShape, Standard_False); aCtx->Display (aShape, Standard_False);
@ -2896,7 +2922,6 @@ static int VDisplay2 (Draw_Interpretor& theDI,
aCtx->Redisplay (aShape, Standard_False); aCtx->Redisplay (aShape, Standard_False);
aCtx->Display (aShape, Standard_False); aCtx->Display (aShape, Standard_False);
} }
aShape.Nullify();
} }
else if (anObj->IsKind (STANDARD_TYPE (NIS_InteractiveObject))) 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(myAisCrankArm,"c");
GetMapOfAIS().Bind(myAisPropeller,"d"); GetMapOfAIS().Bind(myAisPropeller,"d");
TheAISContext()->SetColor(myAisCylinderHead, Quantity_NOC_INDIANRED); myAisCylinderHead->SetMutable (Standard_True);
TheAISContext()->SetColor(myAisEngineBlock , Quantity_NOC_RED); myAisEngineBlock ->SetMutable (Standard_True);
TheAISContext()->SetColor(myAisPropeller , Quantity_NOC_GREEN); myAisCrankArm ->SetMutable (Standard_True);
myAisPropeller ->SetMutable (Standard_True);
TheAISContext()->Display(myAisCylinderHead,Standard_False); TheAISContext()->SetColor (myAisCylinderHead, Quantity_NOC_INDIANRED);
TheAISContext()->Display(myAisEngineBlock,Standard_False ); TheAISContext()->SetColor (myAisEngineBlock, Quantity_NOC_RED);
TheAISContext()->Display(myAisCrankArm,Standard_False ); TheAISContext()->SetColor (myAisPropeller, Quantity_NOC_GREEN);
TheAISContext()->Display(myAisPropeller,Standard_False);
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(myAisCylinderHead);
TheAISContext()->Deactivate(myAisEngineBlock ); TheAISContext()->Deactivate(myAisEngineBlock );
@ -4215,9 +4245,10 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands)
__FILE__, visos, group); __FILE__, visos, group);
theCommands.Add("vdisplay", 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: Displays named objects."
"\n\t\t: Option -noupdate suppresses viewer redraw call." "\n\t\t: Option -noupdate suppresses viewer redraw call."
"\n\t\t: Option -mutable enables optimizations for mutable objects."
__FILE__,VDisplay2,group); __FILE__,VDisplay2,group);
theCommands.Add ("vupdate", theCommands.Add ("vupdate",
@ -4232,12 +4263,13 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands)
__FILE__, VErase, group); __FILE__, VErase, group);
theCommands.Add("vremove", 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" "or vremove [-context] -all to remove all objects"
"\n\t\t: Removes selected or named 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 If -context is in arguments, the objects are not deleted"
"\n\t\t from the map of objects and names." "\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); __FILE__, VRemove, group);
theCommands.Add("vdonly", 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 aCenterY = (argc > 5) ? Draw::Atof (argv[4]) : 0.0;
Standard_Real aCenterZ = (argc > 5) ? Draw::Atof (argv[5]) : 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_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 // remove AIS object with given name from map
VDisplayAISObject (aShapeName, Handle(AIS_InteractiveObject)()); VDisplayAISObject (aShapeName, Handle(AIS_InteractiveObject)());
std::cout << "Compute Triangulation...\n"; if (toPrintInfo)
std::cout << "Compute Triangulation...\n";
Handle(AIS_Triangulation) aShape Handle(AIS_Triangulation) aShape
= new AIS_Triangulation (CalculationOfSphere (aCenterX, aCenterY, aCenterZ, = new AIS_Triangulation (CalculationOfSphere (aCenterX, aCenterY, aCenterZ,
aResolution, aResolution,
@ -2967,12 +2969,15 @@ static int VDrawSphere (Draw_Interpretor& /*di*/, Standard_Integer argc, const c
aColorsSize >>= 20; aColorsSize >>= 20;
aTrianglesSize >>= 20; aTrianglesSize >>= 20;
aPolyConnectSize >>= 20; aPolyConnectSize >>= 20;
std::cout << "NumberOfPoints: " << aNumberPoints << "\n" if (toPrintInfo)
<< "NumberOfTriangles: " << aNumberTriangles << "\n" {
<< "Amount of memory required for PolyTriangulation without Normals: " << (aTotalSize - aNormalsSize) << " Mb\n" std::cout << "NumberOfPoints: " << aNumberPoints << "\n"
<< "Amount of memory for colors: " << aColorsSize << " Mb\n" << "NumberOfTriangles: " << aNumberTriangles << "\n"
<< "Amount of memory for PolyConnect: " << aPolyConnectSize << " Mb\n" << "Amount of memory required for PolyTriangulation without Normals: " << (aTotalSize - aNormalsSize) << " Mb\n"
<< "Amount of graphic card memory required: " << aTotalSize << " 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! // Setting material properties, very important for desirable visual result!
Graphic3d_MaterialAspect aMat (Graphic3d_NOM_PLASTIC); Graphic3d_MaterialAspect aMat (Graphic3d_NOM_PLASTIC);
@ -5283,7 +5288,7 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
__FILE__,VDrawText,group); __FILE__,VDrawText,group);
theCommands.Add("vdrawsphere", 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); __FILE__,VDrawSphere,group);
theCommands.Add ("vsetlocation", theCommands.Add ("vsetlocation",

View File

@ -86,7 +86,7 @@ public:
public: public:
Element (const Handle(VUserDrawObj)& theIObj, Element (const Handle(VUserDrawObj)& theIObj,
CALL_DEF_BOUNDS* theBounds) Graphic3d_BndBox4f* theBounds)
: myIObj( theIObj ) : myIObj( theIObj )
{ {
if (!myIObj.IsNull()) if (!myIObj.IsNull())
@ -123,7 +123,7 @@ private:
// Called by VUserDrawElement // Called by VUserDrawElement
void Render(const Handle(OpenGl_Workspace)& theWorkspace) const; void Render(const Handle(OpenGl_Workspace)& theWorkspace) const;
void GetBounds(CALL_DEF_BOUNDS* theBounds); void GetBounds(Graphic3d_BndBox4f* theBounds);
GLfloat myCoords[6]; GLfloat myCoords[6];
@ -156,16 +156,21 @@ void VUserDrawObj::ComputeSelection (const Handle(SelectMgr_Selection)& theSelec
theSelection->Add(aSensitive); theSelection->Add(aSensitive);
} }
void VUserDrawObj::GetBounds(CALL_DEF_BOUNDS* theBounds) void VUserDrawObj::GetBounds(Graphic3d_BndBox4f* theBounds)
{ {
if (theBounds) if (theBounds)
{ {
theBounds->XMin = myCoords[0]; Graphic3d_Vec4 aMinPt (myCoords[0], myCoords[1], myCoords[2], 1.0f);
theBounds->YMin = myCoords[1]; Graphic3d_Vec4 aMaxPt (myCoords[3], myCoords[4], myCoords[5], 1.0f);
theBounds->ZMin = myCoords[2]; if (!theBounds->IsValid())
theBounds->XMax = myCoords[3]; {
theBounds->YMax = myCoords[4]; theBounds->Combine (Graphic3d_BndBox4f (aMinPt, aMaxPt));
theBounds->ZMax = myCoords[5]; }
else
{
theBounds->CornerMin() = aMinPt;
theBounds->CornerMax() = aMaxPt;
}
} }
} }

View File

@ -6603,6 +6603,53 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
return 0; 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 //function : ViewerCommands
//purpose : //purpose :
@ -6968,4 +7015,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
"\n '-fsaa on|off' Enables/disables adaptive anti-aliasing" "\n '-fsaa on|off' Enables/disables adaptive anti-aliasing"
"\n '-gleam on|off' Enables/disables transparency shadow effects", "\n '-gleam on|off' Enables/disables transparency shadow effects",
__FILE__, VRenderParams, group); __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>. ---Purpose: Sets the context <CTX> in the view <me>.
---Category: Methods to modify the class definition ---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 ) SetViewMappingDefault ( me : mutable )
is static; is static;
---Level: Public ---Level: Public

View File

@ -1189,8 +1189,7 @@ Standard_Integer Index = IsComputed (AStructure);
<< ", " << OldPriority << ", " << NewPriority << ")\n"; << ", " << OldPriority << ", " << NewPriority << ")\n";
cout << flush; cout << flush;
#endif #endif
MyGraphicDriver->EraseStructure (MyCView, *(MyCOMPUTEDSequence.Value (Index)->CStructure())); MyGraphicDriver->ChangePriority (*(MyCOMPUTEDSequence.Value (Index)->CStructure()), MyCView, NewPriority);
MyGraphicDriver->DisplayStructure (MyCView, *(MyCOMPUTEDSequence.Value (Index)->CStructure()), NewPriority);
} }
else else
{ {
@ -1201,8 +1200,7 @@ Standard_Integer Index = IsComputed (AStructure);
<< ", " << OldPriority << ", " << NewPriority << ")\n"; << ", " << OldPriority << ", " << NewPriority << ")\n";
cout << flush; cout << flush;
#endif #endif
MyGraphicDriver->EraseStructure (MyCView, *(AStructure->CStructure())); MyGraphicDriver->ChangePriority (*(AStructure->CStructure()), MyCView, NewPriority);
MyGraphicDriver->DisplayStructure (MyCView, *(AStructure->CStructure()), NewPriority);
} }
} }
@ -1381,6 +1379,7 @@ Standard_Integer Index = IsComputed (AStructure);
if (Answer == Visual3d_TOA_YES ) { if (Answer == Visual3d_TOA_YES ) {
if (IsDisplayed (AStructure)) return; if (IsDisplayed (AStructure)) return;
AStructure->CalculateBoundBox();
MyGraphicDriver->DisplayStructure (MyCView, *(AStructure->CStructure()), AStructure->DisplayPriority()); MyGraphicDriver->DisplayStructure (MyCView, *(AStructure->CStructure()), AStructure->DisplayPriority());
MyDisplayedStructure.Add (AStructure); MyDisplayedStructure.Add (AStructure);
if (AnUpdateMode == Aspect_TOU_ASAP) Update (); if (AnUpdateMode == Aspect_TOU_ASAP) Update ();
@ -1628,6 +1627,14 @@ Standard_Integer Index = IsComputed (AStructure);
MyCOMPUTEDSequence.Value (Index)->GraphicTransform (ATrsf); MyCOMPUTEDSequence.Value (Index)->GraphicTransform (ATrsf);
} }
Standard_Integer aLayerId = AStructure->GetZLayer();
if (!AStructure->IsMutable()
&& !AStructure->CStructure()->IsForHighlight
&& !AStructure->CStructure()->IsInfinite)
{
AStructure->CalculateBoundBox();
MyGraphicDriver->InvalidateBVHData (MyCView, aLayerId);
}
} }
void Visual3d_View::UnHighlight (const Handle(Graphic3d_Structure)& AStructure) { void Visual3d_View::UnHighlight (const Handle(Graphic3d_Structure)& AStructure) {
@ -2089,6 +2096,13 @@ Graphic3d_SequenceOfStructure FooSequence;
} }
void Visual3d_View::ReCompute (const Handle(Graphic3d_Structure)& AStructure) { void Visual3d_View::ReCompute (const Handle(Graphic3d_Structure)& AStructure) {
if (MyCView.IsCullingEnabled)
{
AStructure->CalculateBoundBox();
Standard_Integer aLayerId = AStructure->DisplayPriority();
MyGraphicDriver->InvalidateBVHData(MyCView, aLayerId);
}
if (!ComputedMode()) return; if (!ComputedMode()) return;
if (IsDeleted ()) 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