1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +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

@@ -2028,6 +2028,7 @@ int VRemove (Draw_Interpretor& theDI,
ViewerTest_RedrawMode aToUpdate = ViewerTest_RM_Auto;
Standard_Boolean isContextOnly = Standard_False;
Standard_Boolean toRemoveAll = Standard_False;
Standard_Boolean toPrintInfo = Standard_True;
Standard_Integer anArgIter = 1;
for (; anArgIter < theArgNb; ++anArgIter)
@@ -2042,6 +2043,10 @@ int VRemove (Draw_Interpretor& theDI,
{
toRemoveAll = Standard_True;
}
else if (anArg == "-noinfo")
{
toPrintInfo = Standard_False;
}
else if (!parseRedrawMode (anArg, aToUpdate))
{
break;
@@ -2133,11 +2138,13 @@ int VRemove (Draw_Interpretor& theDI,
anIter.More(); anIter.Next())
{
const Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (anIter.Value()));
if (!anIO.IsNull())
{
TheAISContext()->Remove (anIO, Standard_False);
theDI << anIter.Value().ToCString() << " was removed\n";
if (toPrintInfo)
{
theDI << anIter.Value().ToCString() << " was removed\n";
}
}
else
{
@@ -2145,10 +2152,12 @@ int VRemove (Draw_Interpretor& theDI,
if (!aNisIO.IsNull())
{
TheNISContext()->Remove (aNisIO);
theDI << anIter.Value().ToCString() << " was removed\n";
if (toPrintInfo)
{
theDI << anIter.Value().ToCString() << " was removed\n";
}
}
}
if (!isContextOnly)
{
GetMapOfAIS().UnBind2 (anIter.Value());
@@ -2854,19 +2863,31 @@ static int VDisplay2 (Draw_Interpretor& theDI,
}
ViewerTest_RedrawMode aToUpdate = ViewerTest_RM_Auto;
Standard_Integer isMutable = -1;
for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
{
const TCollection_AsciiString aName = theArgVec[anArgIter];
const TCollection_AsciiString aName = theArgVec[anArgIter];
TCollection_AsciiString aNameCase = aName;
aNameCase.LowerCase();
if (parseRedrawMode (aName, aToUpdate))
{
continue;
}
else if (aNameCase == "-mutable")
{
isMutable = 1;
continue;
}
else if (!GetMapOfAIS().IsBound2 (aName))
{
// create the AIS_Shape from a name
const Handle(AIS_InteractiveObject) aShape = GetAISShapeFromName (aName.ToCString());
if (!aShape.IsNull())
{
if (isMutable != -1)
{
aShape->SetMutable (isMutable == 1);
}
GetMapOfAIS().Bind (aShape, aName);
aCtx->Display (aShape, Standard_False);
}
@@ -2877,6 +2898,11 @@ static int VDisplay2 (Draw_Interpretor& theDI,
if (anObj->IsKind (STANDARD_TYPE (AIS_InteractiveObject)))
{
Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast (anObj);
if (isMutable != -1)
{
aShape->SetMutable (isMutable == 1);
}
if (aShape->Type() == AIS_KOI_Datum)
{
aCtx->Display (aShape, Standard_False);
@@ -2896,7 +2922,6 @@ static int VDisplay2 (Draw_Interpretor& theDI,
aCtx->Redisplay (aShape, Standard_False);
aCtx->Display (aShape, Standard_False);
}
aShape.Nullify();
}
else if (anObj->IsKind (STANDARD_TYPE (NIS_InteractiveObject)))
{
@@ -3088,14 +3113,19 @@ static int VAnimation (Draw_Interpretor& di, Standard_Integer argc, const char**
GetMapOfAIS().Bind(myAisCrankArm,"c");
GetMapOfAIS().Bind(myAisPropeller,"d");
TheAISContext()->SetColor(myAisCylinderHead, Quantity_NOC_INDIANRED);
TheAISContext()->SetColor(myAisEngineBlock , Quantity_NOC_RED);
TheAISContext()->SetColor(myAisPropeller , Quantity_NOC_GREEN);
myAisCylinderHead->SetMutable (Standard_True);
myAisEngineBlock ->SetMutable (Standard_True);
myAisCrankArm ->SetMutable (Standard_True);
myAisPropeller ->SetMutable (Standard_True);
TheAISContext()->Display(myAisCylinderHead,Standard_False);
TheAISContext()->Display(myAisEngineBlock,Standard_False );
TheAISContext()->Display(myAisCrankArm,Standard_False );
TheAISContext()->Display(myAisPropeller,Standard_False);
TheAISContext()->SetColor (myAisCylinderHead, Quantity_NOC_INDIANRED);
TheAISContext()->SetColor (myAisEngineBlock, Quantity_NOC_RED);
TheAISContext()->SetColor (myAisPropeller, Quantity_NOC_GREEN);
TheAISContext()->Display (myAisCylinderHead, Standard_False);
TheAISContext()->Display (myAisEngineBlock, Standard_False);
TheAISContext()->Display (myAisCrankArm, Standard_False);
TheAISContext()->Display (myAisPropeller, Standard_False);
TheAISContext()->Deactivate(myAisCylinderHead);
TheAISContext()->Deactivate(myAisEngineBlock );
@@ -4215,9 +4245,10 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands)
__FILE__, visos, group);
theCommands.Add("vdisplay",
"vdisplay [-noupdate|-update] name1 [name2] ... [name n]"
"vdisplay [-noupdate|-update] [-mutable] name1 [name2] ... [name n]"
"\n\t\t: Displays named objects."
"\n\t\t: Option -noupdate suppresses viewer redraw call."
"\n\t\t: Option -mutable enables optimizations for mutable objects."
__FILE__,VDisplay2,group);
theCommands.Add ("vupdate",
@@ -4232,12 +4263,13 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands)
__FILE__, VErase, group);
theCommands.Add("vremove",
"vremove [-noupdate|-update] [-context] [-all] [name1] ... [name n]"
"vremove [-noupdate|-update] [-context] [-all] [-noinfo] [name1] ... [name n]"
"or vremove [-context] -all to remove all objects"
"\n\t\t: Removes selected or named objects."
"\n\t\t If -context is in arguments, the objects are not deleted"
"\n\t\t from the map of objects and names."
"\n\t\t: Option -noupdate suppresses viewer redraw call.",
"\n\t\t: Option -noupdate suppresses viewer redraw call."
"\n\t\t: Option -noinfo suppresses displaying the list of removed objects.",
__FILE__, VRemove, group);
theCommands.Add("vdonly",

View File

@@ -2923,12 +2923,14 @@ static int VDrawSphere (Draw_Interpretor& /*di*/, Standard_Integer argc, const c
Standard_Real aCenterY = (argc > 5) ? Draw::Atof (argv[4]) : 0.0;
Standard_Real aCenterZ = (argc > 5) ? Draw::Atof (argv[5]) : 0.0;
Standard_Real aRadius = (argc > 6) ? Draw::Atof (argv[6]) : 100.0;
Standard_Boolean toShowEdges = (argc > 7) ? Draw::Atoi (argv[7]) : Standard_False;
Standard_Boolean toShowEdges = (argc > 7) ? Draw::Atoi (argv[7]) == 1 : Standard_False;
Standard_Boolean toPrintInfo = (argc > 8) ? Draw::Atoi (argv[8]) == 1 : Standard_True;
// remove AIS object with given name from map
VDisplayAISObject (aShapeName, Handle(AIS_InteractiveObject)());
std::cout << "Compute Triangulation...\n";
if (toPrintInfo)
std::cout << "Compute Triangulation...\n";
Handle(AIS_Triangulation) aShape
= new AIS_Triangulation (CalculationOfSphere (aCenterX, aCenterY, aCenterZ,
aResolution,
@@ -2967,12 +2969,15 @@ static int VDrawSphere (Draw_Interpretor& /*di*/, Standard_Integer argc, const c
aColorsSize >>= 20;
aTrianglesSize >>= 20;
aPolyConnectSize >>= 20;
std::cout << "NumberOfPoints: " << aNumberPoints << "\n"
<< "NumberOfTriangles: " << aNumberTriangles << "\n"
<< "Amount of memory required for PolyTriangulation without Normals: " << (aTotalSize - aNormalsSize) << " Mb\n"
<< "Amount of memory for colors: " << aColorsSize << " Mb\n"
<< "Amount of memory for PolyConnect: " << aPolyConnectSize << " Mb\n"
<< "Amount of graphic card memory required: " << aTotalSize << " Mb\n";
if (toPrintInfo)
{
std::cout << "NumberOfPoints: " << aNumberPoints << "\n"
<< "NumberOfTriangles: " << aNumberTriangles << "\n"
<< "Amount of memory required for PolyTriangulation without Normals: " << (aTotalSize - aNormalsSize) << " Mb\n"
<< "Amount of memory for colors: " << aColorsSize << " Mb\n"
<< "Amount of memory for PolyConnect: " << aPolyConnectSize << " Mb\n"
<< "Amount of graphic card memory required: " << aTotalSize << " Mb\n";
}
// Setting material properties, very important for desirable visual result!
Graphic3d_MaterialAspect aMat (Graphic3d_NOM_PLASTIC);
@@ -5283,7 +5288,7 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
__FILE__,VDrawText,group);
theCommands.Add("vdrawsphere",
"vdrawsphere: vdrawsphere shapeName Fineness [X=0.0 Y=0.0 Z=0.0] [Radius=100.0] [ToShowEdges=0]\n",
"vdrawsphere: vdrawsphere shapeName Fineness [X=0.0 Y=0.0 Z=0.0] [Radius=100.0] [ToShowEdges=0] [ToPrintInfo=1]\n",
__FILE__,VDrawSphere,group);
theCommands.Add ("vsetlocation",

View File

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

View File

@@ -6603,6 +6603,53 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
return 0;
}
//=======================================================================
//function : VFrustumCulling
//purpose : enables/disables view volume's culling.
//=======================================================================
static int VFrustumCulling (Draw_Interpretor& theDI,
Standard_Integer theArgNb,
const char** theArgVec)
{
Handle(V3d_View) aView = ViewerTest::CurrentView();
if (aView.IsNull())
{
std::cout << theArgVec[0] << " Error: Use 'vinit' command before\n";
return 1;
}
if (theArgNb < 2)
{
theDI << (aView->IsCullingEnabled() ? "on" : "off");
return 0;
}
else if (theArgNb != 2)
{
std::cout << theArgVec[0] << " Syntax error: Specify the mode\n";
return 1;
}
TCollection_AsciiString aModeStr (theArgVec[1]);
aModeStr.LowerCase();
Standard_Boolean toEnable = 0;
if (aModeStr == "on")
{
toEnable = 1;
}
else if (aModeStr == "off")
{
toEnable = 0;
}
else
{
toEnable = Draw::Atoi (theArgVec[1]) != 0;
}
aView->SetFrustumCulling (toEnable);
aView->Redraw();
return 0;
}
//=======================================================================
//function : ViewerCommands
//purpose :
@@ -6968,4 +7015,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
"\n '-fsaa on|off' Enables/disables adaptive anti-aliasing"
"\n '-gleam on|off' Enables/disables transparency shadow effects",
__FILE__, VRenderParams, group);
theCommands.Add("vfrustumculling",
"vfrustumculling [toEnable]: enables/disables objects clipping",
__FILE__,VFrustumCulling,group);
}