This patch improves performance of OpenGl_BVHClipPrimitiveSet. In particular, on the attached test case for 90 000 spheres the results are the following:
1) Master: vdisplay - 55 sec, 5 FPS, 1.4 GB memory, vclear - 180 sec.
2) Branch: vdisplay - 1.3 sec, 5 FPS, 1.4 GB memory, vclear - 90 sec.
So, the patch improves vdisplay in ~40 times, and vclear in ~2 times without extra memory and with no impact on rendering performance. However, the vclear time is still significant. According to profile results, it is due to Graphic3d_Structure::DisconnectAll method.
Test case for issue CR26199
Fix invalid warnings in 'vdefaults' command.
// =======================================================================
Graphic3d_BndBox4f OpenGl_BVHClipPrimitiveSet::Box (const Standard_Integer theIdx) const
{
- return myStructs (theIdx + 1)->BoundingBox();
+ return myStructs.FindKey (theIdx + 1)->BoundingBox();
}
// =======================================================================
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;
+ Graphic3d_BndBox4f aBndBox = myStructs.FindKey (theIdx + 1)->BoundingBox();
+
+ return (aBndBox.CornerMin()[theAxis] +
+ aBndBox.CornerMax()[theAxis]) * 0.5f;
}
// =======================================================================
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;
+ myStructs.Swap (theIdx1 + 1, theIdx2 + 1);
}
// =======================================================================
{
myStructs.Clear();
- const Standard_Integer aNbPriorities = theStructs.Length();
- for (Standard_Integer aPriorityIdx = 0; aPriorityIdx < aNbPriorities; ++aPriorityIdx)
+ for (Standard_Integer aPriorityIdx = 0, aNbPriorities = theStructs.Length(); aPriorityIdx < aNbPriorities; ++aPriorityIdx)
{
for (OpenGl_SequenceOfStructure::Iterator aStructIter (theStructs (aPriorityIdx)); aStructIter.More(); aStructIter.Next())
{
const OpenGl_Structure* aStruct = aStructIter.Value();
+
if (!aStruct->IsAlwaysRendered())
- myStructs.Append (aStruct);
+ {
+ myStructs.Add (aStruct);
+ }
}
}
// =======================================================================
void OpenGl_BVHClipPrimitiveSet::Add (const OpenGl_Structure* theStruct)
{
- myStructs.Append (theStruct);
- MarkDirty();
+ const Standard_Integer aSize = myStructs.Size();
+
+ if (myStructs.Add (theStruct) > aSize) // new structure?
+ {
+ MarkDirty();
+ }
}
// =======================================================================
// =======================================================================
void OpenGl_BVHClipPrimitiveSet::Remove (const OpenGl_Structure* theStruct)
{
- for (Standard_Integer anIdx = 1; anIdx <= myStructs.Size(); ++anIdx)
+ const Standard_Integer anIndex = myStructs.FindIndex (theStruct);
+
+ if (anIndex != 0)
{
- if (myStructs (anIdx) == theStruct)
- {
- myStructs.Remove (anIdx);
- MarkDirty();
- break;
- }
+ myStructs.Swap (Size(), anIndex);
+ myStructs.RemoveLast();
+ MarkDirty();
}
}
// =======================================================================
const OpenGl_Structure* OpenGl_BVHClipPrimitiveSet::GetStructureById (Standard_Integer theId)
{
- return myStructs (theId + 1);
+ return myStructs.FindKey (theId + 1);
}
#include <BVH_PrimitiveSet.hxx>
#include <NCollection_Array1.hxx>
+#include <NCollection_IndexedMap.hxx>
-#include <OpenGl_Vec.hxx>
#include <OpenGl_Structure.hxx>
#include <OpenGl_SequenceOfStructure.hxx>
//! Returns total number of structures.
virtual Standard_Integer Size() const;
- //! Returns AABB of a structure.
+ //! Returns AABB of the structure.
virtual Graphic3d_BndBox4f Box (const Standard_Integer theIdx) const;
- //! Calculates center of the AABB projection onto given axis.
+ //! Calculates center of the AABB along given axis.
virtual Standard_ShortReal Center (const Standard_Integer theIdx,
const Standard_Integer theAxis) const;
- //! Swaps given AABBs.
+ //! Swaps structures with the given indices.
virtual void Swap (const Standard_Integer theIdx1,
const Standard_Integer theIdx2);
//! if each structure is cullable or not.
void Assign (const OpenGl_ArrayOfStructure& theStructs);
- //! Adds structure theStruct to the set.
+ //! Adds structure to the set.
void Add (const OpenGl_Structure* theStruct);
- //! Removes the given OpenGl_Structure from the set.
+ //! Removes the given 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.
+ //! 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
+ NCollection_IndexedMap<const OpenGl_Structure*> myStructs; //!< Indexed map of structures.
};
// currently HLRDeviationAngle is used instead of DeviationAngle in most places
aDefParams->SetHLRAngle (M_PI * Draw::Atof (theArgVec[anArgIter]) / 180.0);
}
- if (anArg == "-AUTOTR"
- || anArg == "-AUTOTRIANG"
- || anArg == "-AUTOTRIANGULATION")
+ else if (anArg == "-AUTOTR"
+ || anArg == "-AUTOTRIANG"
+ || anArg == "-AUTOTRIANGULATION")
{
if (++anArgIter >= theArgsNb)
{
--- /dev/null
+puts "=========="
+puts "OCC26199"
+puts "=========="
+puts ""
+############################################################
+# Visualization - use NCollection_IndexedMap instead of NCollection_Sequence in OpenGl_BVHClipPrimitiveSet to improve performance
+############################################################
+
+psphere s 0.5
+tclean s
+incmesh s 0.1
+trinfo s
+
+vinit View1
+vclear
+vaxo
+vsetdispmode 1
+
+vdefaults -defl 1.0 -autoTriang off
+# Warning, unknown argument '-DEFL'
+
+vdisplay s
+
+set aNb1 100
+
+# display 100x100 connected instances of single presentation
+puts "Creating [expr $aNb1*$aNb1] instances..."
+set t1 [time {for {set i 0} {$i < $aNb1} {incr i} {for {set j 0} {$j < $aNb1} {incr j} {vconnectto s_${i}_${j} ${i} ${j} 0 s -noupdate}}}]
+
+# the following command is slow
+set t2 [time {vclear}]
+
+set d1 [lindex $t1 0]
+puts "vconnectto done in $d1 microseconds!\n"
+
+set d2 [lindex $t2 0]
+puts "vclear done in $d2 microseconds!\n"
+
+set t1_sec [expr $d1 * 1.e-6]
+set t2_sec [expr $d2 * 1.e-6]
+
+if { [regexp {Debug mode} [dversion]] } {
+ if { [regexp {Windows} [dversion]] } {
+ set max_time_vconnectto 5
+ set max_time_vclear 5
+ } else {
+ set max_time_vconnectto 5
+ set max_time_vclear 5
+ }
+} else {
+ if { [regexp {Windows} [dversion]] } {
+ set max_time_vconnectto 1
+ set max_time_vclear 1
+ } else {
+ set max_time_vconnectto 1
+ set max_time_vclear 1
+ }
+}
+
+if { ${t1_sec} > ${max_time_vconnectto} } {
+ puts "Elapsed time of vconnectto is more than ${max_time_vconnectto} seconds - Error"
+} else {
+ puts "Elapsed time of vconnectto is less than ${max_time_vconnectto} seconds - OK"
+}
+
+if { ${t2_sec} > ${max_time_vclear} } {
+ puts "Elapsed time of vclear is more than ${max_time_vclear} seconds - Error"
+} else {
+ puts "Elapsed time of vclear is less than ${max_time_vclear} seconds - OK"
+}