mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-29 14:00:49 +03:00
OCC22144 NIS performance and memory usage update
This commit is contained in:
@@ -8,6 +8,8 @@
|
||||
#include <NIS_InteractiveObject.hxx>
|
||||
#include <gp_Ax1.hxx>
|
||||
#include <Visual3d_View.hxx>
|
||||
#include <Bnd_B2f.hxx>
|
||||
#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
|
||||
#ifdef WNT
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
@@ -23,12 +25,12 @@ IMPLEMENT_STANDARD_RTTIEXT (NIS_View, V3d_OrthographicView)
|
||||
|
||||
NIS_View::NIS_View (const Handle(V3d_Viewer)& theViewer,
|
||||
const Handle(Aspect_Window)& theWindow)
|
||||
: V3d_OrthographicView (theViewer)
|
||||
: V3d_OrthographicView (theViewer),
|
||||
myIsTopHilight(Standard_False),
|
||||
myDoHilightSelected(Standard_True)
|
||||
{
|
||||
if (!theWindow.IsNull()) {
|
||||
const Aspect_GraphicCallbackProc aCallback = &MyCallback;
|
||||
V3d_View::SetWindow (theWindow, NULL, aCallback, this);
|
||||
}
|
||||
if (!theWindow.IsNull())
|
||||
V3d_View::SetWindow (theWindow, NULL, &MyCallback, this);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -38,8 +40,7 @@ NIS_View::NIS_View (const Handle(V3d_Viewer)& theViewer,
|
||||
|
||||
void NIS_View::SetWindow(const Handle(Aspect_Window) &theWindow)
|
||||
{
|
||||
const Aspect_GraphicCallbackProc aCallback = &MyCallback;
|
||||
V3d_View::SetWindow (theWindow, NULL, aCallback, this);
|
||||
V3d_View::SetWindow (theWindow, NULL, &MyCallback, this);
|
||||
}
|
||||
|
||||
// //=======================================================================
|
||||
@@ -80,6 +81,14 @@ void NIS_View::RemoveContext (NIS_InteractiveContext * theCtx)
|
||||
myContexts.Remove (anIter);
|
||||
break;
|
||||
}
|
||||
|
||||
NCollection_Map<Handle_NIS_Drawer>::Iterator anIterD (theCtx->GetDrawers ());
|
||||
for (; anIterD.More(); anIterD.Next()) {
|
||||
const Handle(NIS_Drawer)& aDrawer = anIterD.Value();
|
||||
if (aDrawer.IsNull() == Standard_False) {
|
||||
aDrawer->UpdateExListId(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -87,7 +96,93 @@ void NIS_View::RemoveContext (NIS_InteractiveContext * theCtx)
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void NIS_View::FitAll3d ()
|
||||
Standard_Boolean NIS_View::FitAll3d (const Quantity_Coefficient theCoef)
|
||||
{
|
||||
Standard_Boolean aResult(Standard_False);
|
||||
/*
|
||||
Standard_Integer aLimp[4] = { 1000000, -1000000, 1000000, -1000000 };
|
||||
GetBndBox( aLimp[0], aLimp[1], aLimp[2], aLimp[3] );
|
||||
if (aLimp[1] > -1000000 && aLimp[3] > -1000000 &&
|
||||
aLimp[0] < aLimp[1] && aLimp[2] < aLimp[3])
|
||||
{
|
||||
// Scale the view
|
||||
WindowFit (aLimp[0], aLimp[2], aLimp[1], aLimp[3]);
|
||||
aResult = Standard_True;
|
||||
}
|
||||
*/
|
||||
|
||||
Bnd_B3f aBox = GetBndBox();
|
||||
|
||||
// Check that the box is not empty
|
||||
if (aBox.IsVoid() == Standard_False && MyView->IsDefined() == Standard_True) {
|
||||
// Convert the 3D box to 2D representation in view coordinates
|
||||
Standard_Real Umin,Umax,Vmin,Vmax,U,V,W;
|
||||
gp_XYZ aCoord;
|
||||
|
||||
const gp_XYZ aCorner[2] = { aBox.CornerMin(), aBox.CornerMax() };
|
||||
|
||||
Standard_Boolean doFit = Standard_True;
|
||||
while (doFit) {
|
||||
|
||||
for (Standard_Integer i = 0; i < 8; i++) {
|
||||
if (i & 0x1) aCoord.SetX (aCorner[0].X());
|
||||
else aCoord.SetX (aCorner[1].X());
|
||||
if (i & 0x2) aCoord.SetY (aCorner[0].Y());
|
||||
else aCoord.SetY (aCorner[1].Y());
|
||||
if (i & 0x4) aCoord.SetZ (aCorner[0].Z());
|
||||
else aCoord.SetZ (aCorner[1].Z());
|
||||
|
||||
MyView->Projects(aCoord.X(), aCoord.Y(), aCoord.Z(), U, V, W);
|
||||
if (i) {
|
||||
Umin = Min(Umin, U); Umax = Max(Umax, U);
|
||||
Vmin = Min(Vmin, V); Vmax = Max(Vmax, V);
|
||||
}
|
||||
else {
|
||||
Umin = Umax = U;
|
||||
Vmin = Vmax = V;
|
||||
}
|
||||
}
|
||||
|
||||
if ( (Umax > Umin) && (Vmax > Vmin) ) {
|
||||
Standard_Real OldUmin,OldUmax,OldVmin,OldVmax;
|
||||
MyViewMapping.WindowLimit(OldUmin, OldVmin, OldUmax, OldVmax);
|
||||
Standard_Real DxvOld = Abs(OldUmax - OldUmin);
|
||||
|
||||
// make a margin
|
||||
Standard_Real Xrp, Yrp, DxvNew, DyvNew;
|
||||
|
||||
DxvNew = Abs(Umax - Umin); DyvNew = Abs(Vmax - Vmin);
|
||||
DxvNew *= (1. + theCoef);
|
||||
DyvNew *= (1. + theCoef);
|
||||
|
||||
Standard_Real aRatio = DxvNew / DxvOld;
|
||||
|
||||
Xrp = (Umin + Umax)/2. ; Yrp = (Vmin + Vmax)/2. ;
|
||||
Umin = Xrp - DxvNew/2. ; Umax = Xrp + DxvNew/2. ;
|
||||
Vmin = Yrp - DyvNew/2. ; Vmax = Yrp + DyvNew/2. ;
|
||||
|
||||
// fit view
|
||||
FitAll(Umin, Vmin, Umax, Vmax);
|
||||
|
||||
// ratio 1e+6 often gives calculation error(s), reduce it
|
||||
// if (aRatio < 1e+6) doFit = Standard_False;
|
||||
if (aRatio < 100) doFit = Standard_False;
|
||||
aResult = Standard_True;
|
||||
}
|
||||
else doFit = Standard_False;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return aResult;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : GetBndBox
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Bnd_B3f NIS_View::GetBndBox() const
|
||||
{
|
||||
// Calculate the 3D bounding box of visible objects
|
||||
// in all interactive contexts
|
||||
@@ -103,12 +198,6 @@ void NIS_View::FitAll3d ()
|
||||
}
|
||||
}
|
||||
|
||||
if (aBox.IsVoid()) {
|
||||
// No NIS objects displays, run the compatible method of V3d_View
|
||||
FitAll();
|
||||
return;
|
||||
}
|
||||
|
||||
// Take the bounding box of AIS objects displayed in the view
|
||||
Standard_Real aVal[6];
|
||||
View()->MinMaxValues(aVal[0], aVal[1], aVal[2], aVal[3], aVal[4], aVal[5]);
|
||||
@@ -117,6 +206,22 @@ void NIS_View::FitAll3d ()
|
||||
aBox.Add (gp_XYZ (aVal[3], aVal[4], aVal[5]));
|
||||
}
|
||||
|
||||
return aBox;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : GetBndBox
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void NIS_View::GetBndBox( Standard_Integer& theXMin, Standard_Integer& theXMax,
|
||||
Standard_Integer& theYMin, Standard_Integer& theYMax ) const
|
||||
{
|
||||
theXMin = theYMin = 0;
|
||||
theXMax = theYMax = -1;
|
||||
|
||||
Bnd_B3f aBox = GetBndBox();
|
||||
|
||||
// Check that the box is not empty
|
||||
if (aBox.IsVoid() == Standard_False) {
|
||||
// Convert the 3D box to 2D representation in pixel coordinates
|
||||
@@ -140,8 +245,11 @@ void NIS_View::FitAll3d ()
|
||||
if (aLimp[0] < aLimp[1] && aLimp[2] < aLimp[3])
|
||||
{
|
||||
// Scale the view
|
||||
WindowFit (aLimp[0], aLimp[2], aLimp[1], aLimp[3]);
|
||||
return;
|
||||
// WindowFit (aLimp[0], aLimp[2], aLimp[1], aLimp[3]);
|
||||
theXMin = aLimp[0];
|
||||
theXMax = aLimp[1];
|
||||
theYMin = aLimp[2];
|
||||
theYMax = aLimp[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -200,7 +308,6 @@ int NIS_View::MyCallback (Aspect_Drawable /* Window ID */,
|
||||
}
|
||||
#endif //IS_DISABLED
|
||||
|
||||
// glEnable(GL_COLOR_MATERIAL);
|
||||
GLboolean isDepthWriteMask, isDepthTest;
|
||||
glGetBooleanv(GL_DEPTH_WRITEMASK,&isDepthWriteMask);
|
||||
glGetBooleanv(GL_DEPTH_TEST,&isDepthTest);
|
||||
@@ -217,14 +324,40 @@ int NIS_View::MyCallback (Aspect_Drawable /* Window ID */,
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
TColStd_MapIteratorOfPackedMapOfInteger anIterM(thisView->myExListId);
|
||||
for (; anIterM.More(); anIterM.Next())
|
||||
if (anIterM.Key() != 0) {
|
||||
#ifdef ARRAY_LISTS
|
||||
glDeleteLists (anIterM.Key(), 5);
|
||||
#else
|
||||
glDeleteLists (anIterM.Key(), 1);
|
||||
}
|
||||
#endif
|
||||
thisView->myExListId.Clear();
|
||||
|
||||
for (anIter = thisView->myContexts; anIter.More(); anIter.Next())
|
||||
anIter.Value()->redraw (thisView, NIS_Drawer::Draw_Normal);
|
||||
for (anIter = thisView->myContexts; anIter.More(); anIter.Next())
|
||||
anIter.Value()->redraw (thisView, NIS_Drawer::Draw_Transparent);
|
||||
|
||||
// #818151 - selected object is hidden by covered unselected one
|
||||
// display hilighted objects always above the rest ones
|
||||
if (thisView->myIsTopHilight == Standard_True) {
|
||||
glDepthFunc(GL_ALWAYS);
|
||||
}
|
||||
|
||||
for (anIter = thisView->myContexts; anIter.More(); anIter.Next())
|
||||
anIter.Value()->redraw (thisView, NIS_Drawer::Draw_Hilighted);
|
||||
for (anIter = thisView->myContexts; anIter.More(); anIter.Next())
|
||||
anIter.Value()->redraw (thisView, NIS_Drawer::Draw_DynHilighted);
|
||||
for (anIter = thisView->myContexts; anIter.More(); anIter.Next())
|
||||
anIter.Value()->redraw (thisView, NIS_Drawer::Draw_Transparent);
|
||||
|
||||
// draw top objects always above
|
||||
if (thisView->myIsTopHilight == Standard_False) {
|
||||
glDepthFunc(GL_ALWAYS);
|
||||
}
|
||||
|
||||
for (anIter = thisView->myContexts; anIter.More(); anIter.Next())
|
||||
anIter.Value()->redraw (thisView, NIS_Drawer::Draw_Top);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -237,6 +370,7 @@ int NIS_View::MyCallback (Aspect_Drawable /* Window ID */,
|
||||
void NIS_View::DynamicHilight (const Standard_Integer theX,
|
||||
const Standard_Integer theY)
|
||||
{
|
||||
myDetected.Clear();
|
||||
const Handle(NIS_InteractiveObject) aSelected = Pick (theX, theY);
|
||||
|
||||
// ASV: if at least one Context returns IsSelectable()==False,
|
||||
@@ -248,10 +382,17 @@ void NIS_View::DynamicHilight (const Standard_Integer theX,
|
||||
if (aSelected != myDynHilighted) {
|
||||
const Handle(NIS_View) aView (this);
|
||||
if (myDynHilighted.IsNull() == Standard_False)
|
||||
myDynHilighted->GetDrawer()->SetDynamicHilighted (Standard_False,
|
||||
myDynHilighted, aView);
|
||||
if (aSelected.IsNull())
|
||||
if (myDynHilighted->GetDrawer().IsNull() == Standard_False)
|
||||
myDynHilighted->GetDrawer()->SetDynamicHilighted(Standard_False,
|
||||
myDynHilighted, aView);
|
||||
|
||||
// 30.07.10 - NKV - synchronize behaviour with AIS interactive context (if need)
|
||||
if (aSelected.IsNull() ||
|
||||
(myDoHilightSelected == Standard_False &&
|
||||
aSelected->GetDrawer()->GetContext()->IsSelected(aSelected)))
|
||||
{
|
||||
myDynHilighted.Nullify();
|
||||
}
|
||||
else {
|
||||
aSelected->GetDrawer()->SetDynamicHilighted (Standard_True,
|
||||
aSelected, aView);
|
||||
@@ -270,8 +411,9 @@ void NIS_View::DynamicUnhilight(const Handle_NIS_InteractiveObject& theObj)
|
||||
{
|
||||
if (theObj == myDynHilighted && theObj.IsNull() == Standard_False) {
|
||||
const Handle(NIS_View) aView (this);
|
||||
myDynHilighted->GetDrawer()->SetDynamicHilighted (Standard_False,
|
||||
myDynHilighted, aView);
|
||||
if (myDynHilighted->GetDrawer().IsNull() == Standard_False)
|
||||
myDynHilighted->GetDrawer()->SetDynamicHilighted (Standard_False,
|
||||
myDynHilighted, aView);
|
||||
myDynHilighted.Nullify();
|
||||
Redraw();
|
||||
}
|
||||
@@ -284,8 +426,10 @@ void NIS_View::DynamicUnhilight(const Handle_NIS_InteractiveObject& theObj)
|
||||
|
||||
void NIS_View::Select (const Standard_Integer theX,
|
||||
const Standard_Integer theY,
|
||||
const Standard_Boolean isForceMultiple)
|
||||
const Standard_Boolean isForceMultiple,
|
||||
const Standard_Boolean theRedraw)
|
||||
{
|
||||
myDetected.Clear();
|
||||
const Handle(NIS_InteractiveObject) aSelected = Pick (theX, theY);
|
||||
NCollection_List<NIS_InteractiveContext *>::Iterator anIter (myContexts);
|
||||
for (; anIter.More(); anIter.Next())
|
||||
@@ -296,7 +440,7 @@ void NIS_View::Select (const Standard_Integer theX,
|
||||
const Handle(NIS_Drawer)& aDrawer = aSelected->GetDrawer();
|
||||
aDrawer->SetDynamicHilighted (Standard_False, aSelected, this);
|
||||
}
|
||||
Redraw();
|
||||
if (theRedraw) Redraw();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -309,8 +453,10 @@ void NIS_View::Select (const Standard_Integer theXmin,
|
||||
const Standard_Integer theXmax,
|
||||
const Standard_Integer theYmax,
|
||||
const Standard_Boolean isForceMult,
|
||||
const Standard_Boolean isFullyIncluded)
|
||||
const Standard_Boolean isFullyIncluded,
|
||||
const Standard_Boolean theRedraw)
|
||||
{
|
||||
myDetected.Clear();
|
||||
Standard_Real anX, anY, aZ;
|
||||
if (theXmin == theXmax || theYmin == theYmax)
|
||||
return;
|
||||
@@ -346,18 +492,85 @@ void NIS_View::Select (const Standard_Integer theXmin,
|
||||
pCtx->selectObjects (mapSelected, aBoxSel, aTrfInv, aTrf, isFullyIncluded);
|
||||
pCtx->ProcessSelection (mapSelected, isForceMult);
|
||||
}
|
||||
Redraw();
|
||||
if (theRedraw) Redraw();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Select
|
||||
//purpose : Selection by polygon
|
||||
//=======================================================================
|
||||
|
||||
void NIS_View::Select (const NCollection_List<gp_XY> &thePolygon,
|
||||
const Standard_Boolean isForceMult,
|
||||
const Standard_Boolean isFullyIncluded,
|
||||
const Standard_Boolean theRedraw)
|
||||
{
|
||||
myDetected.Clear();
|
||||
if (thePolygon.IsEmpty())
|
||||
return;
|
||||
|
||||
Standard_Real anX, anY, aZ;
|
||||
|
||||
//Transformed box corresponding to the selected rectangle
|
||||
Proj (anX, anY, aZ); // vector orthogonal to the view plane
|
||||
const gp_Dir aProj (anX, anY, aZ);
|
||||
|
||||
const gp_XY &aPf = thePolygon.First();
|
||||
// 3D point for the 3D coordinates
|
||||
Convert((Standard_Integer) aPf.X(), (Standard_Integer) aPf.Y(), anX, anY, aZ);
|
||||
const gp_Pnt anEye (anX, anY, aZ);
|
||||
|
||||
// 3D point for the 3D coordinates
|
||||
const gp_XY &aPl = thePolygon.Last();
|
||||
|
||||
Convert((Standard_Integer) aPl.X(), (Standard_Integer) aPl.Y(), anX, anY, aZ);
|
||||
|
||||
// Compute transformation.
|
||||
const gp_XYZ anXdir (gp_XYZ(anX, anY, aZ) - anEye.XYZ());
|
||||
const gp_Ax3 anAx3 (anEye, aProj, anXdir);
|
||||
gp_Trsf aTrf;
|
||||
aTrf.SetTransformation (anAx3);
|
||||
const gp_Trsf aTrfInv = aTrf.Inverted();
|
||||
|
||||
// Prepare list of 2d points of selection polygon.
|
||||
NCollection_List<gp_XY> aPoints;
|
||||
NCollection_List<gp_XY>::Iterator anIter(thePolygon);
|
||||
Bnd_B2f aPolyBox;
|
||||
|
||||
for (; anIter.More(); anIter.Next()) {
|
||||
const gp_XY &aP = anIter.Value();
|
||||
|
||||
Convert((Standard_Integer) aP.X(), (Standard_Integer) aP.Y(), anX, anY, aZ);
|
||||
gp_XYZ aP3d(anX, anY, aZ);
|
||||
|
||||
aTrf.Transforms(aP3d);
|
||||
|
||||
gp_XY aP2d(aP3d.X(), aP3d.Y());
|
||||
|
||||
aPoints.Append(aP2d);
|
||||
aPolyBox.Add(aP2d);
|
||||
}
|
||||
|
||||
TColStd_PackedMapOfInteger mapSelected;
|
||||
NCollection_List<NIS_InteractiveContext *>::Iterator anIterC(myContexts);
|
||||
|
||||
for (; anIterC.More(); anIterC.Next()) {
|
||||
NIS_InteractiveContext * pCtx = anIterC.Value();
|
||||
mapSelected.Clear();
|
||||
pCtx->selectObjects (mapSelected, aPoints, aPolyBox, aTrf, isFullyIncluded);
|
||||
pCtx->ProcessSelection (mapSelected, isForceMult);
|
||||
}
|
||||
|
||||
if (theRedraw) Redraw();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Pick
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Handle_NIS_InteractiveObject NIS_View::Pick
|
||||
(const Standard_Integer theX,
|
||||
const Standard_Integer theY) const
|
||||
Handle_NIS_InteractiveObject NIS_View::Pick (const Standard_Integer theX,
|
||||
const Standard_Integer theY)
|
||||
{
|
||||
// Find the ray passing through the clicked point in the view window.
|
||||
Standard_Real anX, anY, aZ, anOver;
|
||||
@@ -381,20 +594,30 @@ Handle_NIS_InteractiveObject NIS_View::Pick
|
||||
Handle_NIS_InteractiveObject NIS_View::Pick
|
||||
(const gp_Ax1& theAxis,
|
||||
const Standard_Real theOver,
|
||||
const Standard_Boolean isOnlySelectable) const
|
||||
const Standard_Boolean isOnlySelectable)
|
||||
{
|
||||
typedef NCollection_List<NIS_InteractiveContext::DetectedEnt> LstDetected;
|
||||
Standard_Real aDistance (0.1 * RealLast());
|
||||
Handle(NIS_InteractiveObject) aSelected, aTmpSel;
|
||||
LstDetected aDetected;
|
||||
|
||||
NCollection_List<NIS_InteractiveContext *>::Iterator anIterC (myContexts);
|
||||
for (; anIterC.More(); anIterC.Next()) {
|
||||
const Standard_Real aDist =
|
||||
anIterC.Value()->selectObject (aTmpSel, theAxis, theOver,
|
||||
anIterC.Value()->selectObject (aTmpSel, aDetected, theAxis, theOver,
|
||||
isOnlySelectable);
|
||||
if (aDist < aDistance) {
|
||||
aDistance = aDist;
|
||||
aSelected = aTmpSel;
|
||||
}
|
||||
}
|
||||
|
||||
// simple iterating is enough to create list of detected objects
|
||||
// in the order of increasing distance
|
||||
myDetected.Clear();
|
||||
for (LstDetected::Iterator anIt(aDetected); anIt.More(); anIt.Next())
|
||||
myDetected.Append(anIt.Value().PObj);
|
||||
|
||||
return aSelected;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user