mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-05-16 10:54:53 +03:00
OCC22144 NIS performance and memory usage update
This commit is contained in:
parent
d51c7072ea
commit
ffe2bea78c
@ -1,5 +1,7 @@
|
||||
EXTERNLIB
|
||||
FILES
|
||||
NIS_Allocator.cxx
|
||||
NIS_Allocator.hxx
|
||||
NIS_Drawer.cxx
|
||||
NIS_Drawer.hxx
|
||||
NIS_DrawList.cxx
|
||||
|
59
src/NIS/NIS_Allocator.cxx
Normal file
59
src/NIS/NIS_Allocator.cxx
Normal file
@ -0,0 +1,59 @@
|
||||
// File: NIS_Allocator.cpp
|
||||
// Created: 22.10.10 17:35
|
||||
// Author: Alexander GRIGORIEV
|
||||
// Copyright: Open Cascade 2010
|
||||
|
||||
#include <NIS_Allocator.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_HANDLE (NIS_Allocator, NCollection_IncAllocator)
|
||||
IMPLEMENT_STANDARD_RTTIEXT (NIS_Allocator, NCollection_IncAllocator)
|
||||
|
||||
//=======================================================================
|
||||
//function : NIS_Allocator
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
NIS_Allocator::NIS_Allocator (const size_t theBlockSize)
|
||||
: NCollection_IncAllocator (theBlockSize),
|
||||
myNAllocated (0),
|
||||
myNFreed (0)
|
||||
{}
|
||||
|
||||
//=======================================================================
|
||||
//function : ResetCounters
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void NIS_Allocator::ResetCounters ()
|
||||
{
|
||||
myNAllocated = 0;
|
||||
myNFreed = 0;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Allocate
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void* NIS_Allocator::Allocate (const size_t size)
|
||||
{
|
||||
size_t* pResult = reinterpret_cast<size_t*>
|
||||
(NCollection_IncAllocator::Allocate(size + sizeof(size_t)));
|
||||
pResult[0] = size;
|
||||
myNAllocated += size;
|
||||
return &pResult[1];
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Free
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void NIS_Allocator::Free (void *anAddress)
|
||||
{
|
||||
if (anAddress) {
|
||||
size_t* pAddress = reinterpret_cast<size_t*>(anAddress) - 1;
|
||||
myNFreed += pAddress[0];
|
||||
NCollection_IncAllocator::Free(pAddress);
|
||||
}
|
||||
}
|
76
src/NIS/NIS_Allocator.hxx
Normal file
76
src/NIS/NIS_Allocator.hxx
Normal file
@ -0,0 +1,76 @@
|
||||
// File: NIS_Allocator.h
|
||||
// Created: 22.10.10 17:22
|
||||
// Author: Alexander GRIGORIEV
|
||||
// Copyright: Open Cascade 2010
|
||||
|
||||
|
||||
#ifndef NIS_Allocator_HeaderFile
|
||||
#define NIS_Allocator_HeaderFile
|
||||
|
||||
#include <NCollection_IncAllocator.hxx>
|
||||
|
||||
/**
|
||||
* Subclass of Incremental Allocator. It is aware of the total
|
||||
* allocated and released memory. Used in NIS_Interactive context as
|
||||
* private allocator that manages all memory used by interactive objects.
|
||||
*/
|
||||
|
||||
class NIS_Allocator : public NCollection_IncAllocator
|
||||
{
|
||||
public:
|
||||
// ---------- PUBLIC METHODS ----------
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
Standard_EXPORT NIS_Allocator (const size_t theBlockSize = 24600);
|
||||
|
||||
/**
|
||||
* Query the total number of allocated bytes
|
||||
*/
|
||||
inline Standard_Size NAllocated () const
|
||||
{
|
||||
return myNAllocated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the total number of released bytes
|
||||
*/
|
||||
inline Standard_Size NFreed () const
|
||||
{
|
||||
return myNFreed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set both counters to zero. Should be called with method Reset of the base
|
||||
* class NCollection_IncAlocator.
|
||||
*/
|
||||
Standard_EXPORT void ResetCounters ();
|
||||
|
||||
/**
|
||||
* Allocate memory with given size. Returns NULL on failure
|
||||
*/
|
||||
Standard_EXPORT virtual void* Allocate (const size_t size);
|
||||
|
||||
/*
|
||||
* Free a previously allocated memory. Does nothing but count released bytes.
|
||||
*/
|
||||
Standard_EXPORT virtual void Free (void *anAddress);
|
||||
|
||||
private:
|
||||
// ---------- PRIVATE FIELDS ----------
|
||||
|
||||
Standard_Size myNAllocated;
|
||||
Standard_Size myNFreed;
|
||||
|
||||
public:
|
||||
// Declaration of CASCADE RTTI
|
||||
DEFINE_STANDARD_RTTI (NIS_Allocator)
|
||||
};
|
||||
|
||||
// Definition of HANDLE object using Standard_DefineHandle.hxx
|
||||
DEFINE_STANDARD_HANDLE (NIS_Allocator, NCollection_IncAllocator)
|
||||
|
||||
|
||||
#endif
|
@ -4,6 +4,7 @@
|
||||
// Copyright: Open Cascade 2007
|
||||
|
||||
#include <NIS_Drawer.hxx>
|
||||
#include <NIS_View.hxx>
|
||||
|
||||
#ifdef WNT
|
||||
#include <windows.h>
|
||||
@ -16,12 +17,21 @@
|
||||
//=======================================================================
|
||||
|
||||
NIS_DrawList::NIS_DrawList ()
|
||||
: myListID (0)
|
||||
{
|
||||
#ifdef ARRAY_LISTS
|
||||
myListID = 0;
|
||||
#else
|
||||
myListID[0] = 0;
|
||||
myListID[1] = 0;
|
||||
myListID[2] = 0;
|
||||
myListID[3] = 0;
|
||||
myListID[4] = 0;
|
||||
#endif
|
||||
myIsUpdated[0] = Standard_True;
|
||||
myIsUpdated[1] = Standard_True;
|
||||
myIsUpdated[2] = Standard_True;
|
||||
myIsUpdated[3] = Standard_True;
|
||||
myIsUpdated[4] = Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@ -30,13 +40,22 @@ NIS_DrawList::NIS_DrawList ()
|
||||
//=======================================================================
|
||||
|
||||
NIS_DrawList::NIS_DrawList (const Handle_NIS_View& theView)
|
||||
: myView (theView),
|
||||
myListID (0)
|
||||
: myView (theView)
|
||||
{
|
||||
#ifdef ARRAY_LISTS
|
||||
myListID = 0;
|
||||
#else
|
||||
myListID[0] = 0;
|
||||
myListID[1] = 0;
|
||||
myListID[2] = 0;
|
||||
myListID[3] = 0;
|
||||
myListID[4] = 0;
|
||||
#endif
|
||||
myIsUpdated[0] = Standard_True;
|
||||
myIsUpdated[1] = Standard_True;
|
||||
myIsUpdated[2] = Standard_True;
|
||||
myIsUpdated[3] = Standard_True;
|
||||
myIsUpdated[4] = Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@ -46,8 +65,67 @@ NIS_DrawList::NIS_DrawList (const Handle_NIS_View& theView)
|
||||
|
||||
NIS_DrawList::~NIS_DrawList ()
|
||||
{
|
||||
if (myListID != 0)
|
||||
glDeleteLists (myListID, 4);
|
||||
//if (myListID != 0)
|
||||
//glDeleteLists (myListID, 5);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ClearListID
|
||||
//purpose : Set myListID to 0.
|
||||
//=======================================================================
|
||||
|
||||
void NIS_DrawList::ClearListID (const Standard_Integer theType)
|
||||
{
|
||||
#ifndef ARRAY_LISTS
|
||||
if (theType >= 0) {
|
||||
// To be called only in Callback context (i.e. when GL context is active)
|
||||
if (myListID[theType] > 0) {
|
||||
glDeleteLists(myListID[theType], 1);
|
||||
myListID[theType] = 0;
|
||||
}
|
||||
myIsUpdated[theType] = Standard_False;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ClearListID
|
||||
//purpose : Set myListID to 0.
|
||||
//=======================================================================
|
||||
|
||||
void NIS_DrawList::ClearListID (const Handle_NIS_View& theView)
|
||||
{
|
||||
#ifdef ARRAY_LISTS
|
||||
if (myListID > 0)
|
||||
myView->GetExListId().Add(myListID);
|
||||
myListID = 0;
|
||||
#else
|
||||
NIS_View * pView = (myView.IsNull()) ?
|
||||
theView.operator->() : myView.operator->();
|
||||
if (pView) {
|
||||
if (myListID[0] > 0)
|
||||
pView->GetExListId().Add(myListID[0]);
|
||||
myListID[0] = 0;
|
||||
if (myListID[1] > 0)
|
||||
pView->GetExListId().Add(myListID[1]);
|
||||
myListID[1] = 0;
|
||||
if (myListID[2] > 0)
|
||||
pView->GetExListId().Add(myListID[2]);
|
||||
myListID[2] = 0;
|
||||
if (myListID[3] > 0)
|
||||
pView->GetExListId().Add(myListID[3]);
|
||||
myListID[3] = 0;
|
||||
if (myListID[4] > 0)
|
||||
pView->GetExListId().Add(myListID[4]);
|
||||
myListID[4] = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
myIsUpdated[0] = Standard_False;
|
||||
myIsUpdated[1] = Standard_False;
|
||||
myIsUpdated[2] = Standard_False;
|
||||
myIsUpdated[3] = Standard_False;
|
||||
myIsUpdated[4] = Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@ -57,9 +135,14 @@ NIS_DrawList::~NIS_DrawList ()
|
||||
|
||||
void NIS_DrawList::BeginPrepare (const Standard_Integer theType)
|
||||
{
|
||||
#ifdef ARRAY_LISTS
|
||||
if (myListID == 0)
|
||||
myListID = glGenLists(4);
|
||||
glNewList (GetListID (theType), GL_COMPILE);
|
||||
myListID = glGenLists(5);
|
||||
#else
|
||||
if (GetListID(theType) == 0)
|
||||
myListID[theType] = glGenLists(1);
|
||||
#endif
|
||||
glNewList (GetListID(theType), GL_COMPILE);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@ -70,7 +153,7 @@ void NIS_DrawList::BeginPrepare (const Standard_Integer theType)
|
||||
void NIS_DrawList::EndPrepare (const Standard_Integer theType)
|
||||
{
|
||||
glEndList ();
|
||||
myIsUpdated[theType&0x3] = Standard_False;
|
||||
myIsUpdated[theType] = Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@ -120,9 +203,20 @@ Standard_Boolean NIS_DrawList::SetDynHilighted
|
||||
void NIS_DrawList::SetUpdated (const Standard_Integer theType,
|
||||
const Standard_Boolean theFlag)
|
||||
{
|
||||
if ( theFlag )
|
||||
SetUpdated( theType );
|
||||
if (theFlag)
|
||||
SetUpdated(theType);
|
||||
else
|
||||
myIsUpdated [theType&0x3] = Standard_False;
|
||||
myIsUpdated [theType] = Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetUpdated
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void NIS_DrawList::SetUpdated (const Standard_Integer theType)
|
||||
{
|
||||
myIsUpdated [theType] = Standard_True;
|
||||
if (theType == NIS_Drawer::Draw_Hilighted)
|
||||
myDynHilighted.Clear();
|
||||
}
|
||||
|
@ -12,9 +12,18 @@
|
||||
#include <NCollection_List.hxx>
|
||||
|
||||
class NIS_InteractiveContext;
|
||||
/**
|
||||
* This macro defines that OpenGL draw lists will be allocated as array of 5
|
||||
* integers and any of them would not be deleted unless all interactive objects
|
||||
* in the given drawer are removed.
|
||||
* When the macro is undefined every draw list is created when needed and it is
|
||||
* destroyed when there is no objects to show in this draw list.
|
||||
*/
|
||||
//#define ARRAY_LISTS
|
||||
|
||||
/**
|
||||
* Block of comments describing class NIS_DrawList
|
||||
* Implementation of a set of OpenGL draw lists for a given NIS_Drawer and
|
||||
* given NIS_View. Stored in NIS_Drawer instances.
|
||||
*/
|
||||
|
||||
class NIS_DrawList
|
||||
@ -43,8 +52,26 @@ class NIS_DrawList
|
||||
* @param theType
|
||||
* Integer value coinciding with the enumerated NIS_Drawer:DrawType.
|
||||
*/
|
||||
inline Standard_Integer GetListID (const Standard_Integer theType)
|
||||
{ return myListID + (theType&0x3); }
|
||||
inline Standard_Integer GetListID (const Standard_Integer theType) const
|
||||
#ifdef ARRAY_LISTS
|
||||
{ return myListID + theType; }
|
||||
#else
|
||||
{ return myListID[theType]; }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Set myListID to 0.
|
||||
* @return
|
||||
* Previous value of myListID
|
||||
*/
|
||||
Standard_EXPORT void ClearListID (const Standard_Integer theType);
|
||||
|
||||
/**
|
||||
* Set myListID to 0.
|
||||
* @return
|
||||
* Previous value of myListID
|
||||
*/
|
||||
Standard_EXPORT void ClearListID (const Handle_NIS_View& theView=NULL);
|
||||
|
||||
/**
|
||||
* This method is called to start recording a new list. It must be eventually
|
||||
@ -74,14 +101,13 @@ class NIS_DrawList
|
||||
* @param theType
|
||||
* Integer value coinciding with the enumerated NIS_Drawer::DrawType.
|
||||
*/
|
||||
inline Standard_Boolean IsUpdated (const Standard_Integer theType)
|
||||
{ return myIsUpdated [theType&0x3]; }
|
||||
inline Standard_Boolean IsUpdated (const Standard_Integer theType) const
|
||||
{ return myIsUpdated [theType]; }
|
||||
|
||||
/**
|
||||
* Set the flag indicating that the List should be updated (rebuilt).
|
||||
*/
|
||||
inline void SetUpdated (const Standard_Integer theType)
|
||||
{ myIsUpdated [theType&0x3] = Standard_True; }
|
||||
Standard_EXPORT void SetUpdated (const Standard_Integer theType);
|
||||
|
||||
/**
|
||||
* Query if the given list should be processed by Dynamic Hilighting.
|
||||
@ -108,10 +134,10 @@ class NIS_DrawList
|
||||
Standard_EXPORT void SetUpdated (const Standard_Integer,
|
||||
const Standard_Boolean);
|
||||
|
||||
#ifdef ARRAY_LISTS
|
||||
inline void SetListID (const Standard_Integer theID)
|
||||
{ myListID = theID; }
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
private:
|
||||
// ---------- PRIVATE METHODS (PROHIBITED) ----------
|
||||
@ -122,8 +148,12 @@ class NIS_DrawList
|
||||
// ---------- PRIVATE FIELDS ----------
|
||||
|
||||
Handle_NIS_View myView;
|
||||
#ifdef ARRAY_LISTS
|
||||
Standard_Integer myListID;
|
||||
Standard_Boolean myIsUpdated[4];
|
||||
#else
|
||||
Standard_Integer myListID[5];
|
||||
#endif
|
||||
Standard_Boolean myIsUpdated[5];
|
||||
NCollection_List<Handle_NIS_InteractiveObject> myDynHilighted;
|
||||
};
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
// Copyright: Open Cascade 2007
|
||||
|
||||
#include <NIS_Drawer.hxx>
|
||||
#include <NIS_View.hxx>
|
||||
#include <NIS_InteractiveContext.hxx>
|
||||
#include <NIS_InteractiveObject.hxx>
|
||||
#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
|
||||
@ -34,6 +35,9 @@ void NIS_Drawer::Assign (const Handle_NIS_Drawer& theOther)
|
||||
{
|
||||
if (theOther->IsKind(DynamicType()) == Standard_False)
|
||||
Standard_TypeMismatch::Raise ("NIS_Drawer::Assign");
|
||||
myIniId = theOther->myIniId;
|
||||
myObjPerDrawer = theOther->myObjPerDrawer;
|
||||
myTransparency = theOther->myTransparency;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@ -43,7 +47,9 @@ void NIS_Drawer::Assign (const Handle_NIS_Drawer& theOther)
|
||||
|
||||
Standard_Integer NIS_Drawer::HashCode(const Standard_Integer theN) const
|
||||
{
|
||||
return ::HashCode (DynamicType(), theN);
|
||||
Standard_Integer aKey = ::HashCode (DynamicType(), theN);
|
||||
aKey += (myIniId / myObjPerDrawer);
|
||||
return ((aKey & 0x7fffffff) % theN) + 1;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@ -56,7 +62,13 @@ Standard_Boolean NIS_Drawer::IsEqual (const Handle_NIS_Drawer& theOther) const
|
||||
Standard_Boolean aResult (Standard_False);
|
||||
if (theOther.IsNull() == Standard_False)
|
||||
if (DynamicType() == theOther->DynamicType())
|
||||
aResult = (myMapID.Extent() < 2048);
|
||||
if (theOther->myIniId/theOther->myObjPerDrawer == myIniId/myObjPerDrawer)
|
||||
aResult = Standard_True;
|
||||
|
||||
if (aResult)
|
||||
if (fabs(myTransparency - theOther->myTransparency) > 0.01)
|
||||
aResult = Standard_False;
|
||||
|
||||
return aResult;
|
||||
}
|
||||
|
||||
@ -78,6 +90,36 @@ void NIS_Drawer::AfterDraw (const DrawType, const NIS_DrawList&)
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : UpdateExListId
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void NIS_Drawer::UpdateExListId (const Handle_NIS_View& theView) const
|
||||
{
|
||||
if (theView.IsNull()) {
|
||||
if (myCtx) {
|
||||
if (myCtx->myViews.IsEmpty() == Standard_False) {
|
||||
const Handle(NIS_View)& aView = myCtx->myViews.First();
|
||||
NCollection_List<NIS_DrawList *>::Iterator anIterL(myLists);
|
||||
for (; anIterL.More(); anIterL.Next()) {
|
||||
NIS_DrawList * const pList = anIterL.Value();
|
||||
pList->ClearListID(aView);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NCollection_List<NIS_DrawList *>::Iterator anIterL(myLists);
|
||||
for (; anIterL.More(); anIterL.Next()) {
|
||||
NIS_DrawList * const pList = anIterL.Value();
|
||||
if (pList->GetView() == theView) {
|
||||
pList->ClearListID(theView);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : redraw
|
||||
//purpose :
|
||||
@ -93,13 +135,25 @@ void NIS_Drawer::redraw (const DrawType theType,
|
||||
NCollection_List<NIS_DrawList*>::Iterator anIter (myLists);
|
||||
for (; anIter.More(); anIter.Next()) {
|
||||
NIS_DrawList& aDrawList = * anIter.ChangeValue();
|
||||
if (aDrawList.GetView() == theView) {
|
||||
const Handle_NIS_View& aView = aDrawList.GetView();
|
||||
if (aView == theView || aView.IsNull()) {
|
||||
if (aDrawList.IsUpdated(theType)) {
|
||||
// Get the IDs of objects concerned
|
||||
TColStd_PackedMapOfInteger mapObj;
|
||||
mapObj.Intersection (myCtx->myMapObjects[theType], myMapID);
|
||||
#ifndef ARRAY_LISTS
|
||||
// Release the list that is no more in use
|
||||
if (mapObj.IsEmpty() && theType != Draw_DynHilighted) {
|
||||
aDrawList.ClearListID(theType);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
aDrawList.BeginPrepare(theType);
|
||||
prepareList (theType, aDrawList);
|
||||
prepareList (theType, aDrawList, mapObj);
|
||||
aDrawList.EndPrepare(theType);
|
||||
}
|
||||
aDrawList.Call(theType);
|
||||
if (aDrawList.GetListID(theType) > 0)
|
||||
aDrawList.Call(theType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -158,6 +212,28 @@ void NIS_Drawer::SetUpdated (const DrawType theType1,
|
||||
const_cast<Bnd_B3f&>(myBox).Clear();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetUpdated
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
|
||||
void NIS_Drawer::SetUpdated (const DrawType theType1,
|
||||
const DrawType theType2,
|
||||
const DrawType theType3,
|
||||
const DrawType theType4) const
|
||||
{
|
||||
NCollection_List<NIS_DrawList*>::Iterator anIter (myLists);
|
||||
for (; anIter.More(); anIter.Next()) {
|
||||
NIS_DrawList& aDrawList = * anIter.ChangeValue();
|
||||
aDrawList.SetUpdated (theType1);
|
||||
aDrawList.SetUpdated (theType2);
|
||||
aDrawList.SetUpdated (theType3);
|
||||
aDrawList.SetUpdated (theType4);
|
||||
}
|
||||
const_cast<Bnd_B3f&>(myBox).Clear();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetDynamicHilighted
|
||||
//purpose :
|
||||
@ -180,7 +256,8 @@ void NIS_Drawer::SetDynamicHilighted
|
||||
} else
|
||||
for (; anIter.More(); anIter.Next()) {
|
||||
NIS_DrawList& aDrawList = * anIter.ChangeValue();
|
||||
if (aDrawList.GetView() == theView) {
|
||||
const Handle(NIS_View)& aView = aDrawList.GetView();
|
||||
if (aView == theView || aView.IsNull()) {
|
||||
aDrawList.SetDynHilighted (isHilighted, theObj);
|
||||
theObj->myIsDynHilighted = isHilighted;
|
||||
aDrawList.SetUpdated (Draw_DynHilighted);
|
||||
@ -195,15 +272,18 @@ void NIS_Drawer::SetDynamicHilighted
|
||||
//=======================================================================
|
||||
|
||||
void NIS_Drawer::removeObject (const NIS_InteractiveObject * theObj,
|
||||
const Standard_Boolean isUpdateViews)
|
||||
const Standard_Boolean isUpdateViews)
|
||||
{
|
||||
const Standard_Integer anID = theObj->ID();
|
||||
myMapID.Remove (anID);
|
||||
// Stop dynamic hilighting if it has been activated
|
||||
if (theObj->IsDynHilighted())
|
||||
SetDynamicHilighted (Standard_False, theObj);
|
||||
if (myMapID.IsEmpty()) {
|
||||
UpdateExListId(NULL);
|
||||
}
|
||||
// Set Updated for the draw type.
|
||||
if (theObj->IsHidden() == Standard_False && isUpdateViews)
|
||||
else if (theObj->IsHidden() == Standard_False && isUpdateViews)
|
||||
SetUpdated (theObj->DrawType());
|
||||
}
|
||||
|
||||
@ -213,6 +293,7 @@ void NIS_Drawer::removeObject (const NIS_InteractiveObject * theObj,
|
||||
//=======================================================================
|
||||
|
||||
void NIS_Drawer::addObject (const NIS_InteractiveObject * theObj,
|
||||
const Standard_Boolean isShareList,
|
||||
const Standard_Boolean isUpdateViews)
|
||||
{
|
||||
myMapID.Add (theObj->ID());
|
||||
@ -220,9 +301,13 @@ void NIS_Drawer::addObject (const NIS_InteractiveObject * theObj,
|
||||
// Fill the drawer (if new) with DrawList instances for available Views.
|
||||
if ( myLists.IsEmpty())
|
||||
{
|
||||
NCollection_List<Handle_NIS_View>::Iterator anIter (GetContext()->myViews);
|
||||
for (; anIter.More(); anIter.Next())
|
||||
myLists.Append (createDefaultList(anIter.Value()));
|
||||
if (isShareList)
|
||||
myLists.Append (createDefaultList(NULL));
|
||||
else {
|
||||
NCollection_List<Handle_NIS_View>::Iterator anIter(GetContext()->myViews);
|
||||
for (; anIter.More(); anIter.Next())
|
||||
myLists.Append (createDefaultList(anIter.Value()));
|
||||
}
|
||||
}
|
||||
|
||||
if (theObj->IsHidden() == Standard_False && isUpdateViews)
|
||||
@ -245,7 +330,8 @@ const Bnd_B3f& NIS_Drawer::GetBox (const NIS_View * pView) const
|
||||
NCollection_List<NIS_DrawList*>::Iterator anIterL (myLists);
|
||||
for (; anIterL.More(); anIterL.Next()) {
|
||||
NIS_DrawList& aDrawList = * anIterL.ChangeValue();
|
||||
if (aDrawList.GetView().operator->() == pView)
|
||||
const Handle(NIS_View)& aView = aDrawList.GetView();
|
||||
if (aView.IsNull() || aView.operator->() == pView)
|
||||
break;
|
||||
}
|
||||
if (anIterL.More())
|
||||
@ -269,8 +355,9 @@ const Bnd_B3f& NIS_Drawer::GetBox (const NIS_View * pView) const
|
||||
//function : prepareList
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void NIS_Drawer::prepareList( const NIS_Drawer::DrawType theType,
|
||||
const NIS_DrawList& theDrawList )
|
||||
void NIS_Drawer::prepareList(const NIS_Drawer::DrawType theType,
|
||||
const NIS_DrawList& theDrawList,
|
||||
const TColStd_PackedMapOfInteger& mapObj)
|
||||
{
|
||||
if (!myCtx)
|
||||
return;
|
||||
@ -280,17 +367,15 @@ void NIS_Drawer::prepareList( const NIS_Drawer::DrawType theType,
|
||||
if (theType == NIS_Drawer::Draw_DynHilighted) {
|
||||
NCollection_List<Handle_NIS_InteractiveObject>::Iterator
|
||||
anIter (theDrawList.DynHilightedList());
|
||||
for (; anIter.More(); anIter.Next())
|
||||
{
|
||||
if (anIter.More()) {
|
||||
BeforeDraw (theType, theDrawList);
|
||||
Draw (anIter.Value(), NIS_Drawer::Draw_DynHilighted, theDrawList);
|
||||
for (; anIter.More(); anIter.Next())
|
||||
Draw (anIter.Value(), NIS_Drawer::Draw_DynHilighted, theDrawList);
|
||||
AfterDraw (theType, theDrawList);
|
||||
}
|
||||
} else {
|
||||
// The common part of two maps (objects for this draw type & objects in
|
||||
// the current Drawer) is used for updating the presentation.
|
||||
TColStd_PackedMapOfInteger mapObj;
|
||||
mapObj.Intersection (myCtx->myMapObjects[theType&0x3], myMapID);
|
||||
TColStd_MapIteratorOfPackedMapOfInteger anIter (mapObj);
|
||||
if (anIter.More()) {
|
||||
BeforeDraw (theType, theDrawList);
|
||||
@ -313,5 +398,5 @@ void NIS_Drawer::prepareList( const NIS_Drawer::DrawType theType,
|
||||
NIS_DrawList* NIS_Drawer::createDefaultList
|
||||
(const Handle_NIS_View& theView) const
|
||||
{
|
||||
return new NIS_DrawList( theView );
|
||||
return new NIS_DrawList(theView);
|
||||
}
|
||||
|
@ -28,21 +28,91 @@ class NIS_View;
|
||||
template <class A> class NCollection_Vector;
|
||||
|
||||
/**
|
||||
* Abstract Drawer type
|
||||
* Abstract Drawer type.
|
||||
* Drawer provides the immediate OpenGL drawing for every NIS_InteractiveObject
|
||||
* maneged by the given Drawer instance. Each Drawer instance has reciprocal
|
||||
* link with a number of NIS_InteractiveObject instances of the same
|
||||
* (corresponding to Drawer) type. The idea is to group the drawing for all
|
||||
* referred interactive objects using the same pre- and post-treatment like
|
||||
* color setting, matrix, polygon offset, line thickness and what not.
|
||||
*
|
||||
* @section nis_drawer_visualprop Visual properties of Drawer
|
||||
* Normally visual properties of any NIS_InteractiveObject are stored in its
|
||||
* Drawer instance, but not in an object. For example, if an interactive object
|
||||
* has method SetColor() then the color is stored in the corresponding Drawer
|
||||
* rather than in the interactive object itself. This scheme avoid useless
|
||||
* duplication when a lot of objects have similar properties like color. Please
|
||||
* see @see nis_interactiveobject_drawer to learn how this mechanism
|
||||
* works from the side of NIS_InteractiveObject.
|
||||
*
|
||||
* @section nis_drawer_drawing Drawing
|
||||
* There are 3 virtual methods to implement OpenGL drawing in this API. They
|
||||
* define the drawing cycle that consists of filling the internal OpenGL draw
|
||||
* list with commands. This drawing cycle is triggered when the corresponding
|
||||
* internal instance of NIS_DrawList has 'IsUpdated' flag (you can set this
|
||||
* flag by means of public methods NIS_Drawer::SetUpdated()).
|
||||
* <ul>
|
||||
* <li><b>BeforeDraw()</b> : contains all OpenGL commands that define the
|
||||
* common set of visual properties for all managed interactive objects.
|
||||
* This method is called once in the beginning of drawing cycle for the
|
||||
* Drawer instance</li>
|
||||
* <li><b>Draw()</b> : all OpenGL commands that are specific to a given
|
||||
* interactive object, usually definition of vertices, triangles, lines,
|
||||
* or their arrays.</li>
|
||||
* <li><b>AfterDraw()</b> : commands that revert the status of OpenGL context
|
||||
* to the state before execution of BeforeDraw(). This method is called
|
||||
* once in the end of drawing cycle.</li>
|
||||
* </ul>
|
||||
* Each of these methods receives NIS_DrawList and DrawType, both identify the
|
||||
* OpenGL draw list that should be filled with commands. Based on DrawType
|
||||
* you will be able to define different presentation - the most important case
|
||||
* is how hilighted (selected) interactive object is presented.
|
||||
* <p>
|
||||
* For advanced purposes you also can redefine the virtual method redraw(), it
|
||||
* is dedicated to higher-level management of draw lists and ordering of
|
||||
* their update when necessary.
|
||||
*
|
||||
* @section nis_drawer_distinction Distinction of Drawer instances
|
||||
* Every Drawer should define which interactive objects it may manage and
|
||||
* which - may not. The same idea could be shaped alternatively: every
|
||||
* interactive object should understand to what Drawer it can attach itself.
|
||||
* This question is answerd by special virtual method IsEqual() that compares
|
||||
* two Drawers of the same type. <b>Two instances of Drawer are equal if they
|
||||
* have the same set of visual properties that are implemented in BeforeDraw().
|
||||
* </b> The method IsEqual() is the core of Drawer architecture and it must
|
||||
* be implemented very carefully for any new type. Particularly, for any
|
||||
* derived class the method IsEqual() should first call the same method of
|
||||
* its superclass.
|
||||
* <p>
|
||||
* For the optimal efficiency of OpenGL drawing it is better to keep the size
|
||||
* of draw list (i.e., the number of interactive objects in a Drawer instance)
|
||||
* not too small and not too big. The latter limitation is entered by the
|
||||
* protected field myObjPerDrawer. It is used in method IsEqual() of the base
|
||||
* Drawer class: two Drawers are not equal if they are initialized on objects
|
||||
* that have too different IDs -- even if all visual properties of these two
|
||||
* Drawer instances coincide.
|
||||
* <p>
|
||||
* @section nis_drawer_cloning Cloning Drawer instances
|
||||
* It is possible to clone a Drawer instance with the viryual method Assign().
|
||||
* This method copies all visual properties and other important data from the
|
||||
* Drawer provided as parameter. Method Clone() also should be very carefully
|
||||
* implemented for any new Drawer type, to make sure that all necessary data
|
||||
* fields and structures are properly copied.
|
||||
*/
|
||||
|
||||
class NIS_Drawer : public Standard_Transient
|
||||
{
|
||||
public:
|
||||
#if (_MSC_VER < 1400)
|
||||
enum DrawType {
|
||||
#if defined(WNT) && (_MSC_VER >= 1400)
|
||||
enum DrawType : unsigned int {
|
||||
#else
|
||||
enum DrawType : unsigned int {
|
||||
enum DrawType {
|
||||
#endif
|
||||
Draw_Normal = 0,
|
||||
Draw_Transparent = 1,
|
||||
Draw_Hilighted = 2,
|
||||
Draw_DynHilighted = 3
|
||||
Draw_Top = 1,
|
||||
Draw_Transparent = 2,
|
||||
Draw_Hilighted = 3,
|
||||
Draw_DynHilighted = 4
|
||||
};
|
||||
|
||||
public:
|
||||
@ -52,7 +122,12 @@ class NIS_Drawer : public Standard_Transient
|
||||
/**
|
||||
* Empty constructor.
|
||||
*/
|
||||
inline NIS_Drawer () : myCtx (0L) {}
|
||||
inline NIS_Drawer ()
|
||||
: myTransparency (0.f),
|
||||
myIniId (0),
|
||||
myObjPerDrawer (1024),
|
||||
myCtx (0L)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
@ -91,6 +166,11 @@ class NIS_Drawer : public Standard_Transient
|
||||
const DrawType theType2,
|
||||
const DrawType theType3) const;
|
||||
|
||||
Standard_EXPORT void SetUpdated (const DrawType theType1,
|
||||
const DrawType theType2,
|
||||
const DrawType theType3,
|
||||
const DrawType theType4) const;
|
||||
|
||||
/**
|
||||
* Switch on/off the dynamic hilight of the given object in the
|
||||
* given view.
|
||||
@ -126,7 +206,20 @@ class NIS_Drawer : public Standard_Transient
|
||||
ObjectIterator () const
|
||||
{ return TColStd_MapIteratorOfPackedMapOfInteger (myMapID); }
|
||||
|
||||
/**
|
||||
* Query associated draw lists.
|
||||
*/
|
||||
inline NCollection_List<NIS_DrawList *>
|
||||
GetLists() const
|
||||
{ return myLists; }
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Called to add draw list IDs to ex-list Ids of view. These draw lists are
|
||||
* eventually released in the callback function, before anything is displayed
|
||||
*/
|
||||
Standard_EXPORT void UpdateExListId (const Handle_NIS_View& theView) const;
|
||||
|
||||
// ---------- PROTECTED METHODS ----------
|
||||
|
||||
/**
|
||||
@ -154,7 +247,8 @@ protected:
|
||||
const Handle_NIS_View& theView);
|
||||
|
||||
Standard_EXPORT void addObject (const NIS_InteractiveObject * theObj,
|
||||
const Standard_Boolean isUpVws);
|
||||
const Standard_Boolean isShareList,
|
||||
const Standard_Boolean isUpVws);
|
||||
|
||||
Standard_EXPORT void removeObject (const NIS_InteractiveObject * theObj,
|
||||
const Standard_Boolean isUpVws);
|
||||
@ -162,6 +256,11 @@ protected:
|
||||
Standard_EXPORT virtual NIS_DrawList*
|
||||
createDefaultList (const Handle_NIS_View&) const;
|
||||
|
||||
protected:
|
||||
//! Get the number of interactive objects in this drawer
|
||||
inline Standard_Integer NObjects() const
|
||||
{ return myMapID.Extent(); }
|
||||
|
||||
private:
|
||||
// ---------- PRIVATE (PROHIBITED) METHODS ----------
|
||||
|
||||
@ -169,12 +268,21 @@ protected:
|
||||
NIS_Drawer& operator = (const NIS_Drawer& theOther);
|
||||
|
||||
// ---------- PRIVATE METHODS ----------
|
||||
void prepareList (const NIS_Drawer::DrawType theType,
|
||||
const NIS_DrawList& theDrawLst);
|
||||
void prepareList (const NIS_Drawer::DrawType theType,
|
||||
const NIS_DrawList& theDrawLst,
|
||||
const TColStd_PackedMapOfInteger& mapObj);
|
||||
|
||||
protected:
|
||||
// ---------- PROTECTED FIELDS ----------
|
||||
NCollection_List<NIS_DrawList*> myLists;
|
||||
Standard_ShortReal myTransparency;
|
||||
//! ID of the initializing InteractiveObject. It is never changed, can be
|
||||
//! used to compute hash code of the Drawer instance.
|
||||
Standard_Integer myIniId;
|
||||
//! Maximal range of IDs of objects in one drawer. Limits the size of
|
||||
//! draw lists. Can be initialized only in constructor (default 1024). It is
|
||||
//! strictly prohibited to change this value outside the constructor.
|
||||
Standard_Integer myObjPerDrawer;
|
||||
|
||||
private:
|
||||
// ---------- PRIVATE FIELDS ----------
|
||||
@ -185,6 +293,7 @@ protected:
|
||||
|
||||
friend class NIS_InteractiveContext;
|
||||
friend class NIS_InteractiveObject;
|
||||
friend class NIS_View;
|
||||
|
||||
public:
|
||||
// Declaration of CASCADE RTTI
|
||||
|
@ -8,16 +8,12 @@
|
||||
#include <NIS_View.hxx>
|
||||
#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
|
||||
#include <Standard_NoSuchObject.hxx>
|
||||
#include <Bnd_B2f.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_HANDLE (NIS_InteractiveContext, Standard_Transient)
|
||||
IMPLEMENT_STANDARD_RTTIEXT (NIS_InteractiveContext, Standard_Transient)
|
||||
|
||||
static void deselectObj (const Handle(NIS_InteractiveObject)&,
|
||||
const Standard_Integer,
|
||||
TColStd_PackedMapOfInteger *);
|
||||
static void selectObj (const Handle(NIS_InteractiveObject)&,
|
||||
const Standard_Integer,
|
||||
TColStd_PackedMapOfInteger *);
|
||||
static void markAllDrawersUpdated (const NCollection_Map<Handle_NIS_Drawer>&);
|
||||
|
||||
//=======================================================================
|
||||
//function : NIS_InteractiveContext()
|
||||
@ -25,8 +21,10 @@ static void selectObj (const Handle(NIS_InteractiveObject)&,
|
||||
//=======================================================================
|
||||
|
||||
NIS_InteractiveContext::NIS_InteractiveContext ()
|
||||
: mySelectionMode (Mode_NoSelection),
|
||||
myAllocator (new NCollection_IncAllocator)
|
||||
: myAllocator (new NIS_Allocator(1024*100)),
|
||||
// myDrawers (101, myAllocator),
|
||||
mySelectionMode (Mode_NoSelection),
|
||||
myIsShareDrawList (Standard_True)
|
||||
{
|
||||
// ID == 0 is invalid so we reserve this item from subsequent allocation.
|
||||
myObjects.Append (NULL);
|
||||
@ -143,42 +141,42 @@ void NIS_InteractiveContext::GetBox (Bnd_B3f& theBox,
|
||||
//=======================================================================
|
||||
|
||||
void NIS_InteractiveContext::Display
|
||||
(const Handle_NIS_InteractiveObject& theObj,
|
||||
const Handle_NIS_Drawer& theDrawer,
|
||||
const Standard_Boolean isUpdateViews)
|
||||
(Handle_NIS_InteractiveObject& theObj,
|
||||
const Handle_NIS_Drawer& theDrawer,
|
||||
const Standard_Boolean isUpdateViews)
|
||||
{
|
||||
if (theObj.IsNull())
|
||||
return;
|
||||
Standard_Integer anID = theObj->ID();
|
||||
Handle(NIS_Drawer) aDrawer = theDrawer;
|
||||
if (aDrawer.IsNull() == Standard_False) {
|
||||
if (aDrawer->myCtx != this)
|
||||
Standard_NoSuchObject::Raise ("NIS_InteractiveContext::Display (0)");
|
||||
} else {
|
||||
aDrawer = theObj->GetDrawer();
|
||||
if (aDrawer.IsNull()) {
|
||||
aDrawer = theObj->DefaultDrawer();
|
||||
aDrawer->myCtx = this;
|
||||
}
|
||||
}
|
||||
if (anID == 0) {
|
||||
// Create a new ID for this object
|
||||
theObj->myID = myObjects.Length();
|
||||
myObjects.Append (theObj);
|
||||
myMapObjects[NIS_Drawer::Draw_Normal].Add(theObj->myID);
|
||||
}
|
||||
aDrawer = theObj->SetDrawer (aDrawer);
|
||||
|
||||
// Display Object as Normal or Transparent if it has been hidden
|
||||
objectForDisplay(theObj, theObj->DrawType());
|
||||
const Handle(NIS_Drawer)& aDrawer = drawerForDisplay(theObj, theDrawer);
|
||||
// Display Object as Normal or Transparent if it has been hidden
|
||||
if (theObj->IsHidden())
|
||||
theObj->myIsHidden = Standard_False;
|
||||
|
||||
// Set Update flag in the Drawer
|
||||
if (isUpdateViews)
|
||||
aDrawer->SetUpdated (theObj->DrawType());
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : DisplayOnTop
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void NIS_InteractiveContext::DisplayOnTop
|
||||
(Handle_NIS_InteractiveObject& theObj,
|
||||
const Handle_NIS_Drawer& theDrawer,
|
||||
const Standard_Boolean isUpdateViews)
|
||||
{
|
||||
if (theObj.IsNull())
|
||||
return;
|
||||
|
||||
objectForDisplay(theObj, NIS_Drawer::Draw_Top);
|
||||
const Handle(NIS_Drawer)& aDrawer = drawerForDisplay(theObj, theDrawer);
|
||||
|
||||
// Display Object as Normal or Transparent if it has been hidden
|
||||
if (theObj->IsHidden())
|
||||
theObj->myIsHidden = Standard_False;
|
||||
// if (theObj->IsTransparent()) {
|
||||
// myMapObjects[NIS_Drawer::Draw_Transparent].Add(anID);
|
||||
// theObj->myDrawType = NIS_Drawer::Draw_Transparent;
|
||||
// } else {
|
||||
// myMapObjects[NIS_Drawer::Draw_Normal].Add(anID);
|
||||
// theObj->myDrawType = NIS_Drawer::Draw_Normal;
|
||||
// }
|
||||
|
||||
// Set Update flag in the Drawer
|
||||
if (isUpdateViews)
|
||||
@ -221,6 +219,8 @@ void NIS_InteractiveContext::Remove (const Handle_NIS_InteractiveObject& theObj,
|
||||
{
|
||||
if (theObj.IsNull() == Standard_False) {
|
||||
const Handle(NIS_Drawer)& aDrawer = theObj->GetDrawer();
|
||||
if ( aDrawer.IsNull() )
|
||||
return;
|
||||
if (aDrawer->myCtx == this) {
|
||||
// Remove the hilighting if the object has been hilighted
|
||||
if (theObj->IsDynHilighted()) {
|
||||
@ -229,10 +229,10 @@ void NIS_InteractiveContext::Remove (const Handle_NIS_InteractiveObject& theObj,
|
||||
if (anIterV.Value().IsNull() == Standard_False)
|
||||
anIterV.Value()->DynamicUnhilight (theObj);
|
||||
}
|
||||
// Remove the obejct from the context
|
||||
// Remove the object from the context
|
||||
const Standard_Integer anID = theObj->ID();
|
||||
const NIS_Drawer::DrawType aDrawType (theObj->DrawType());
|
||||
if (myMapObjects[Standard_Integer(aDrawType)&0x3].Remove(anID))
|
||||
if (myMapObjects[Standard_Integer(aDrawType)].Remove(anID))
|
||||
aDrawer->removeObject(theObj.operator->(), isUpdateViews);
|
||||
theObj->myID = 0;
|
||||
theObj->myDrawer.Nullify();
|
||||
@ -246,7 +246,7 @@ void NIS_InteractiveContext::Remove (const Handle_NIS_InteractiveObject& theObj,
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void NIS_InteractiveContext::DisplayAll (const Standard_Boolean isUpdateViews)
|
||||
void NIS_InteractiveContext::DisplayAll ()
|
||||
{
|
||||
// UnHide all objects in the Context
|
||||
NCollection_Vector <Handle_NIS_InteractiveObject>::Iterator anIter(myObjects);
|
||||
@ -258,15 +258,14 @@ void NIS_InteractiveContext::DisplayAll (const Standard_Boolean isUpdateViews)
|
||||
}
|
||||
|
||||
// Update status of objects in Drawers (particularly cancel dyn. hilighting)
|
||||
if (isUpdateViews) {
|
||||
NCollection_Map<Handle_NIS_Drawer>::Iterator anIterD (myDrawers);
|
||||
for (; anIterD.More(); anIterD.Next()) {
|
||||
const Handle(NIS_Drawer)& aDrawer = anIterD.Value();
|
||||
if (aDrawer.IsNull() == Standard_False) {
|
||||
aDrawer->SetUpdated (NIS_Drawer::Draw_Normal,
|
||||
NIS_Drawer::Draw_Transparent,
|
||||
NIS_Drawer::Draw_Hilighted);
|
||||
}
|
||||
NCollection_Map<Handle_NIS_Drawer>::Iterator anIterD (myDrawers);
|
||||
for (; anIterD.More(); anIterD.Next()) {
|
||||
const Handle(NIS_Drawer)& aDrawer = anIterD.Value();
|
||||
if (aDrawer.IsNull() == Standard_False) {
|
||||
aDrawer->SetUpdated (NIS_Drawer::Draw_Normal,
|
||||
NIS_Drawer::Draw_Top,
|
||||
NIS_Drawer::Draw_Transparent,
|
||||
NIS_Drawer::Draw_Hilighted);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -276,7 +275,7 @@ void NIS_InteractiveContext::DisplayAll (const Standard_Boolean isUpdateViews)
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void NIS_InteractiveContext::EraseAll (const Standard_Boolean isUpdateViews)
|
||||
void NIS_InteractiveContext::EraseAll ()
|
||||
{
|
||||
// Hide all objects in the Context
|
||||
NCollection_Vector <Handle_NIS_InteractiveObject>::Iterator anIter(myObjects);
|
||||
@ -299,14 +298,15 @@ void NIS_InteractiveContext::EraseAll (const Standard_Boolean isUpdateViews)
|
||||
for (; anIterD.More(); anIterD.Next()) {
|
||||
const Handle(NIS_Drawer)& aDrawer = anIterD.Value();
|
||||
if (aDrawer.IsNull() == Standard_False) {
|
||||
if (isUpdateViews)
|
||||
aDrawer->SetUpdated (NIS_Drawer::Draw_Normal,
|
||||
NIS_Drawer::Draw_Transparent,
|
||||
NIS_Drawer::Draw_Hilighted);
|
||||
aDrawer->SetUpdated (NIS_Drawer::Draw_Normal,
|
||||
NIS_Drawer::Draw_Top,
|
||||
NIS_Drawer::Draw_Transparent,
|
||||
NIS_Drawer::Draw_Hilighted);
|
||||
// if (aList.myDynHilighted.IsEmpty() == Standard_False) {
|
||||
// aList.myIsUpdated[NIS_Drawer::Draw_DynHilighted]= Standard_True;
|
||||
// aList.myDynHilighted.Clear();
|
||||
// }
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -316,7 +316,7 @@ void NIS_InteractiveContext::EraseAll (const Standard_Boolean isUpdateViews)
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void NIS_InteractiveContext::RemoveAll (const Standard_Boolean isUpdateViews)
|
||||
void NIS_InteractiveContext::RemoveAll ()
|
||||
{
|
||||
// Remove objects from the Context
|
||||
NCollection_Vector <Handle_NIS_InteractiveObject>::Iterator anIter(myObjects);
|
||||
@ -335,43 +335,71 @@ void NIS_InteractiveContext::RemoveAll (const Standard_Boolean isUpdateViews)
|
||||
}
|
||||
}
|
||||
|
||||
// Remove objects from Drawers (particularly cancel dynamic hilighting)
|
||||
// Mark all draw lists to be removed in the view callback
|
||||
NCollection_Map<Handle_NIS_Drawer>::Iterator anIterD (myDrawers);
|
||||
for (; anIterD.More(); anIterD.Next()) {
|
||||
const Handle(NIS_Drawer)& aDrawer = anIterD.Value();
|
||||
if (aDrawer.IsNull() == Standard_False) {
|
||||
aDrawer->myMapID.Clear();
|
||||
if (isUpdateViews)
|
||||
aDrawer->SetUpdated (NIS_Drawer::Draw_Normal,
|
||||
NIS_Drawer::Draw_Transparent,
|
||||
NIS_Drawer::Draw_Hilighted);
|
||||
// if (aList.myDynHilighted.IsEmpty() == Standard_False) {
|
||||
// aList.myIsUpdated[NIS_Drawer::Draw_DynHilighted]= Standard_True;
|
||||
// aList.myDynHilighted.Clear();
|
||||
// }
|
||||
aDrawer->UpdateExListId(NULL);
|
||||
aDrawer->myLists.Clear();
|
||||
}
|
||||
}
|
||||
// Remove Drawers
|
||||
myDrawers.Clear();
|
||||
|
||||
// Release memory
|
||||
myAllocator->Reset();
|
||||
myAllocator->ResetCounters();
|
||||
|
||||
myDrawers.Clear();
|
||||
|
||||
// Remove objects from maps
|
||||
myMapObjects[0].Clear();
|
||||
myMapObjects[1].Clear();
|
||||
myMapObjects[2].Clear();
|
||||
myMapObjects[3].Clear();
|
||||
myMapNonSelectableObjects.Clear();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : RebuildViews
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void NIS_InteractiveContext::RebuildViews ()
|
||||
{
|
||||
const Handle_NIS_Allocator aNewAlloc = compactObjects();
|
||||
|
||||
// Recalculate all DrawLists in all drawers
|
||||
markAllDrawersUpdated(myDrawers);
|
||||
|
||||
// It is time to destroy the old allocator, not before this line. Because
|
||||
// the old allocator is needed to tidy up draw lists in SetUpdated() calls.
|
||||
if (aNewAlloc.IsNull() == Standard_False)
|
||||
myAllocator = aNewAlloc;
|
||||
|
||||
NCollection_List<Handle_NIS_View>::Iterator anIterV(myViews);
|
||||
for (; anIterV.More(); anIterV.Next()) {
|
||||
const Handle(NIS_View)& aView = anIterV.Value();
|
||||
if (aView.IsNull() == Standard_False)
|
||||
aView->Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : UpdateViews
|
||||
//purpose :
|
||||
//purpose : Only repaint the views refreshing their presentations only for
|
||||
// those drawers that have been marked as updated.
|
||||
//=======================================================================
|
||||
|
||||
void NIS_InteractiveContext::UpdateViews ()
|
||||
{
|
||||
NCollection_Map<Handle_NIS_Drawer>::Iterator anIterD (myDrawers);
|
||||
for (; anIterD.More(); anIterD.Next()) {
|
||||
const Handle(NIS_Drawer)& aDrawer = anIterD.Value();
|
||||
if (aDrawer.IsNull() == Standard_False) {
|
||||
aDrawer->SetUpdated (NIS_Drawer::Draw_Normal,
|
||||
NIS_Drawer::Draw_Transparent,
|
||||
NIS_Drawer::Draw_Hilighted);
|
||||
// aList.myIsUpdated[NIS_Drawer::Draw_DynHilighted] =
|
||||
// (aList.myDynHilighted.IsEmpty() == Standard_False);
|
||||
}
|
||||
}
|
||||
NCollection_List<Handle_NIS_View>::Iterator anIterV (myViews);
|
||||
const Handle_NIS_Allocator aNewAlloc = compactObjects();
|
||||
if (aNewAlloc.IsNull() == Standard_False)
|
||||
myAllocator = aNewAlloc;
|
||||
|
||||
NCollection_List<Handle_NIS_View>::Iterator anIterV(myViews);
|
||||
for (; anIterV.More(); anIterV.Next()) {
|
||||
const Handle(NIS_View)& aView = anIterV.Value();
|
||||
if (aView.IsNull() == Standard_False)
|
||||
@ -393,13 +421,13 @@ Standard_Boolean NIS_InteractiveContext::SetSelected
|
||||
const Standard_Integer anID = theObj->ID();
|
||||
if (isSelected == Standard_False) {
|
||||
if (myMapObjects[NIS_Drawer::Draw_Hilighted].Remove(anID)) {
|
||||
deselectObj (theObj, anID, &myMapObjects[0]);
|
||||
deselectObj (theObj, anID);
|
||||
aResult = Standard_True;
|
||||
}
|
||||
} else {
|
||||
if (IsSelectable(anID) == Standard_True) {
|
||||
if (myMapObjects[NIS_Drawer::Draw_Hilighted].Add(anID)) {
|
||||
selectObj (theObj, anID, &myMapObjects[0]);
|
||||
selectObj (theObj, anID);
|
||||
aResult = Standard_True;
|
||||
}
|
||||
}
|
||||
@ -421,8 +449,13 @@ Standard_Boolean NIS_InteractiveContext::ProcessSelection
|
||||
Standard_Integer anID (0);
|
||||
Standard_Boolean wasSelected (Standard_False);
|
||||
if (theObj.IsNull() == Standard_False) {
|
||||
anID = theObj->ID();
|
||||
wasSelected = myMapObjects[NIS_Drawer::Draw_Hilighted].Contains (anID);
|
||||
const Handle(NIS_Drawer)& aDrawer = theObj->GetDrawer();
|
||||
if (aDrawer.IsNull() == Standard_False) {
|
||||
if (aDrawer->GetContext() == this) {
|
||||
anID = theObj->ID();
|
||||
wasSelected = myMapObjects[NIS_Drawer::Draw_Hilighted].Contains (anID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (mySelectionMode) {
|
||||
@ -433,20 +466,20 @@ Standard_Boolean NIS_InteractiveContext::ProcessSelection
|
||||
aResult = Standard_True;
|
||||
} else if (wasSelected && mySelectionMode == Mode_Normal) {
|
||||
myMapObjects[NIS_Drawer::Draw_Hilighted].Remove( anID );
|
||||
deselectObj (theObj, anID, &myMapObjects[0]);
|
||||
deselectObj (theObj, anID);
|
||||
aResult = Standard_True;
|
||||
break;
|
||||
}
|
||||
if (wasSelected == Standard_False && IsSelectable(anID) == Standard_True) {
|
||||
myMapObjects[NIS_Drawer::Draw_Hilighted].Add( anID );
|
||||
selectObj (theObj, anID, &myMapObjects[0]);
|
||||
selectObj (theObj, anID);
|
||||
aResult = Standard_True;
|
||||
}
|
||||
break;
|
||||
case Mode_Exclusive:
|
||||
if (wasSelected) {
|
||||
myMapObjects[NIS_Drawer::Draw_Hilighted].Remove( anID );
|
||||
deselectObj (theObj, anID, &myMapObjects[0]);
|
||||
deselectObj (theObj, anID);
|
||||
aResult = Standard_True;
|
||||
}
|
||||
break;
|
||||
@ -476,7 +509,7 @@ void NIS_InteractiveContext::ProcessSelection
|
||||
myMapObjects[NIS_Drawer::Draw_Hilighted] = aMap;
|
||||
for (anIter.Initialize (aMap); anIter.More(); anIter.Next()) {
|
||||
const Standard_Integer anID = anIter.Key();
|
||||
selectObj (myObjects(anID), anID, &myMapObjects[0]);
|
||||
selectObj (myObjects(anID), anID);
|
||||
}
|
||||
} else {
|
||||
TColStd_PackedMapOfInteger aMapSub;
|
||||
@ -486,11 +519,11 @@ void NIS_InteractiveContext::ProcessSelection
|
||||
myMapObjects[NIS_Drawer::Draw_Hilighted].Subtract (aMapSub);
|
||||
for (anIter.Initialize (aMap); anIter.More(); anIter.Next()) {
|
||||
const Standard_Integer anID = anIter.Key();
|
||||
selectObj (myObjects(anID), anID, &myMapObjects[0]);
|
||||
selectObj (myObjects(anID), anID);
|
||||
}
|
||||
for (anIter.Initialize (aMapSub); anIter.More(); anIter.Next()) {
|
||||
const Standard_Integer anID = anIter.Key();
|
||||
deselectObj (myObjects(anID), anID, &myMapObjects[0]);
|
||||
deselectObj (myObjects(anID), anID);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -499,7 +532,7 @@ void NIS_InteractiveContext::ProcessSelection
|
||||
myMapObjects[NIS_Drawer::Draw_Hilighted].Unite (aMap);
|
||||
for (anIter.Initialize (aMap); anIter.More(); anIter.Next()) {
|
||||
const Standard_Integer anID = anIter.Key();
|
||||
selectObj (myObjects(anID), anID, &myMapObjects[0]);
|
||||
selectObj (myObjects(anID), anID);
|
||||
}
|
||||
break;
|
||||
case Mode_Exclusive:
|
||||
@ -507,7 +540,7 @@ void NIS_InteractiveContext::ProcessSelection
|
||||
myMapObjects[NIS_Drawer::Draw_Hilighted].Subtract (aMap);
|
||||
for (anIter.Initialize (aMap); anIter.More(); anIter.Next()) {
|
||||
const Standard_Integer anID = anIter.Key();
|
||||
deselectObj (myObjects(anID), anID, &myMapObjects[0]);
|
||||
deselectObj (myObjects(anID), anID);
|
||||
}
|
||||
break;
|
||||
default: ;
|
||||
@ -541,7 +574,7 @@ void NIS_InteractiveContext::ClearSelected ()
|
||||
(myMapObjects[NIS_Drawer::Draw_Hilighted]);
|
||||
for (; anIter.More(); anIter.Next()) {
|
||||
const Standard_Integer anID = anIter.Key();
|
||||
deselectObj (myObjects(anID), anID, &myMapObjects[0]);
|
||||
deselectObj (myObjects(anID), anID);
|
||||
}
|
||||
myMapObjects[NIS_Drawer::Draw_Hilighted].Clear();
|
||||
}
|
||||
@ -569,7 +602,7 @@ void NIS_InteractiveContext::SetSelected
|
||||
aMapSub.Subtraction (myMapObjects[NIS_Drawer::Draw_Hilighted], aMap);
|
||||
for (anIter.Initialize(aMapSub); anIter.More(); anIter.Next()) {
|
||||
const Standard_Integer anID = anIter.Key();
|
||||
deselectObj (myObjects(anID), anID, &myMapObjects[0]);
|
||||
deselectObj (myObjects(anID), anID);
|
||||
}
|
||||
myMapObjects[NIS_Drawer::Draw_Hilighted].Subtract(aMapSub);
|
||||
}
|
||||
@ -579,7 +612,7 @@ void NIS_InteractiveContext::SetSelected
|
||||
// Select objects
|
||||
for (anIter.Initialize (aMap); anIter.More(); anIter.Next()) {
|
||||
const Standard_Integer anID = anIter.Key();
|
||||
selectObj (myObjects(anID), anID, &myMapObjects[0]);
|
||||
selectObj (myObjects(anID), anID);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -590,14 +623,17 @@ void NIS_InteractiveContext::SetSelected
|
||||
//=======================================================================
|
||||
|
||||
Standard_Real NIS_InteractiveContext::selectObject
|
||||
(Handle_NIS_InteractiveObject& theSel,
|
||||
const gp_Ax1& theAxis,
|
||||
const Standard_Real theOver,
|
||||
const Standard_Boolean isOnlySel) const
|
||||
(Handle_NIS_InteractiveObject& theSel,
|
||||
NCollection_List<DetectedEnt>& theDetected,
|
||||
const gp_Ax1& theAxis,
|
||||
const Standard_Real theOver,
|
||||
const Standard_Boolean isOnlySel) const
|
||||
{
|
||||
Standard_Real aResult (0.5 * RealLast());
|
||||
static const Standard_Real anInfiniteDist = 0.5 * RealLast();
|
||||
Standard_Real aMinDist(anInfiniteDist);
|
||||
if (mySelectionMode != Mode_NoSelection || isOnlySel == Standard_False)
|
||||
{
|
||||
DetectedEnt anEnt;
|
||||
NCollection_Vector <Handle_NIS_InteractiveObject>::Iterator
|
||||
anIter(myObjects);
|
||||
for (; anIter.More(); anIter.Next()) {
|
||||
@ -615,16 +651,29 @@ Standard_Real NIS_InteractiveContext::selectObject
|
||||
const Bnd_B3f& aBox = anObj->GetBox();
|
||||
if (aBox.IsOut (theAxis, Standard_False, theOver) == Standard_False)
|
||||
{
|
||||
const Standard_Real aDist = anObj->Intersect (theAxis, theOver);
|
||||
if (aDist < aResult) {
|
||||
aResult = aDist;
|
||||
theSel = anObj;
|
||||
anEnt.Dist = anObj->Intersect (theAxis, theOver);
|
||||
if (anEnt.Dist < anInfiniteDist) {
|
||||
anEnt.PObj = anObj.operator->();
|
||||
// Insert the detected entity in the sorted list
|
||||
NCollection_List<DetectedEnt>::Iterator anIterD(theDetected);
|
||||
for (; anIterD.More(); anIterD.Next()) {
|
||||
if (anEnt.Dist < anIterD.Value().Dist) {
|
||||
theDetected.InsertBefore(anEnt, anIterD);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (anIterD.More() == Standard_False)
|
||||
theDetected.Append(anEnt);
|
||||
if (anEnt.Dist < aMinDist) {
|
||||
aMinDist = anEnt.Dist;
|
||||
theSel = anObj;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return aResult;
|
||||
return aMinDist;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@ -646,7 +695,7 @@ void NIS_InteractiveContext::SetSelectable
|
||||
anID = anIter.Key();
|
||||
if ( myMapObjects[NIS_Drawer::Draw_Hilighted].Contains(anID)) {
|
||||
myMapObjects[NIS_Drawer::Draw_Hilighted].Remove(anID);
|
||||
deselectObj (myObjects(anID), anID, &myMapObjects[0]);
|
||||
deselectObj (myObjects(anID), anID);
|
||||
}
|
||||
}
|
||||
myMapNonSelectableObjects.Unite(objIDs);
|
||||
@ -694,25 +743,90 @@ Standard_Boolean NIS_InteractiveContext::selectObjects
|
||||
return aResult;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : selectObjects
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean NIS_InteractiveContext::selectObjects
|
||||
(TColStd_PackedMapOfInteger &mapObj,
|
||||
const NCollection_List<gp_XY> &thePolygon,
|
||||
const Bnd_B2f &thePolygonBox,
|
||||
const gp_Trsf &theTrfInv,
|
||||
const Standard_Boolean isFullyIn) const
|
||||
{
|
||||
Standard_Boolean aResult (Standard_False);
|
||||
|
||||
if (mySelectionMode != Mode_NoSelection) {
|
||||
NCollection_Vector <Handle_NIS_InteractiveObject>::Iterator
|
||||
anIter(myObjects);
|
||||
|
||||
for (; anIter.More(); anIter.Next()) {
|
||||
const Handle(NIS_InteractiveObject)& anObj = anIter.Value();
|
||||
|
||||
if (anObj.IsNull() == Standard_False)
|
||||
if (anObj->IsDisplayed()) {
|
||||
// Pass the object through the SelectFilter if available
|
||||
if (mySelectFilter.IsNull() == Standard_False)
|
||||
if (mySelectFilter->IsOk (anObj.operator->()) == Standard_False)
|
||||
continue;
|
||||
|
||||
// Comvert 3d box to 2d one
|
||||
const Bnd_B3f &aBox = anObj->GetBox();
|
||||
Bnd_B2f aB2d;
|
||||
Standard_Real aX[2];
|
||||
Standard_Real aY[2];
|
||||
Standard_Real aZ[2];
|
||||
gp_XYZ aBoxVtx;
|
||||
Standard_Integer i;
|
||||
|
||||
aBox.CornerMin().Coord(aX[0], aY[0], aZ[0]);
|
||||
aBox.CornerMax().Coord(aX[1], aY[1], aZ[1]);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
aBoxVtx.SetX(aX[(i & 1) ? 1 : 0]);
|
||||
aBoxVtx.SetY(aY[(i & 2) ? 1 : 0]);
|
||||
aBoxVtx.SetZ(aZ[(i & 4) ? 1 : 0]);
|
||||
theTrfInv.Transforms(aBoxVtx);
|
||||
aB2d.Add(gp_XY(aBoxVtx.X(), aBoxVtx.Y()));
|
||||
}
|
||||
|
||||
// Check the intersection with the box
|
||||
if (thePolygonBox.IsOut(aB2d) == Standard_False) {
|
||||
if (anObj->Intersect(thePolygon, theTrfInv, isFullyIn)) {
|
||||
mapObj.Add (anObj->ID());
|
||||
aResult = Standard_True;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return aResult;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : deselectObj
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void deselectObj (const Handle(NIS_InteractiveObject)& theObj,
|
||||
const Standard_Integer theID,
|
||||
TColStd_PackedMapOfInteger * mapObjects)
|
||||
void NIS_InteractiveContext::deselectObj
|
||||
(const Handle(NIS_InteractiveObject)& theObj,
|
||||
const Standard_Integer theID)
|
||||
{
|
||||
if (theObj.IsNull() == Standard_False) {
|
||||
const Handle(NIS_Drawer)& aDrawer = theObj->GetDrawer();
|
||||
if (theObj->IsTransparent()) {
|
||||
mapObjects[NIS_Drawer::Draw_Transparent].Add(theID);
|
||||
myMapObjects[NIS_Drawer::Draw_Transparent].Add(theID);
|
||||
aDrawer->SetUpdated(NIS_Drawer::Draw_Transparent);
|
||||
} else if (theObj->myBaseType == NIS_Drawer::Draw_Top) {
|
||||
myMapObjects[NIS_Drawer::Draw_Top].Add(theID);
|
||||
aDrawer->SetUpdated(NIS_Drawer::Draw_Top);
|
||||
} else {
|
||||
mapObjects[NIS_Drawer::Draw_Normal].Add(theID);
|
||||
myMapObjects[NIS_Drawer::Draw_Normal].Add(theID);
|
||||
aDrawer->SetUpdated(NIS_Drawer::Draw_Normal);
|
||||
}
|
||||
aDrawer->SetUpdated(NIS_Drawer::Draw_Hilighted);
|
||||
theObj->myDrawType = theObj->myBaseType;
|
||||
}
|
||||
}
|
||||
|
||||
@ -721,20 +835,129 @@ void deselectObj (const Handle(NIS_InteractiveObject)& theObj,
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void selectObj (const Handle(NIS_InteractiveObject)& theObj,
|
||||
const Standard_Integer theID,
|
||||
TColStd_PackedMapOfInteger * mapObjects)
|
||||
void NIS_InteractiveContext::selectObj
|
||||
(const Handle(NIS_InteractiveObject)& theObj,
|
||||
const Standard_Integer theID)
|
||||
{
|
||||
if (theObj.IsNull() == Standard_False) {
|
||||
const Handle(NIS_Drawer)& aDrawer = theObj->GetDrawer();
|
||||
if (theObj->IsTransparent()) {
|
||||
mapObjects[NIS_Drawer::Draw_Transparent].Remove(theID);
|
||||
myMapObjects[NIS_Drawer::Draw_Transparent].Remove(theID);
|
||||
aDrawer->SetUpdated(NIS_Drawer::Draw_Transparent);
|
||||
} else if (theObj->myDrawType == NIS_Drawer::Draw_Top) {
|
||||
myMapObjects[NIS_Drawer::Draw_Top].Remove(theID);
|
||||
aDrawer->SetUpdated(NIS_Drawer::Draw_Top);
|
||||
} else {
|
||||
mapObjects[NIS_Drawer::Draw_Normal].Remove(theID);
|
||||
myMapObjects[NIS_Drawer::Draw_Normal].Remove(theID);
|
||||
aDrawer->SetUpdated(NIS_Drawer::Draw_Normal);
|
||||
}
|
||||
aDrawer->SetUpdated(NIS_Drawer::Draw_Hilighted);
|
||||
theObj->myDrawType = NIS_Drawer::Draw_Hilighted;
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : drawerForDisplay
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
const Handle_NIS_Drawer& NIS_InteractiveContext::drawerForDisplay
|
||||
(const Handle_NIS_InteractiveObject& theObj,
|
||||
const Handle_NIS_Drawer& theDrawer)
|
||||
{
|
||||
Handle(NIS_Drawer) aDrawer;
|
||||
if (theDrawer.IsNull() == Standard_False) {
|
||||
if (theDrawer->myCtx != this)
|
||||
Standard_NoSuchObject::Raise ("NIS_InteractiveContext::Display (0)");
|
||||
aDrawer = theDrawer;
|
||||
} else {
|
||||
const Handle(NIS_Drawer)& anObjDrawer = theObj->GetDrawer();
|
||||
if (anObjDrawer.IsNull() == Standard_False)
|
||||
return anObjDrawer;
|
||||
aDrawer = theObj->DefaultDrawer(0L);
|
||||
aDrawer->myCtx = this;
|
||||
}
|
||||
return theObj->SetDrawer (aDrawer, Standard_False);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : objectIdForDisplay
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void NIS_InteractiveContext::objectForDisplay
|
||||
(Handle_NIS_InteractiveObject& theObj,
|
||||
const NIS_Drawer::DrawType theDrawType)
|
||||
{
|
||||
if (theObj->ID() == 0) {
|
||||
// Create a new ID for this object
|
||||
Handle(NIS_InteractiveObject) anObj;
|
||||
theObj->Clone(myAllocator, anObj);
|
||||
theObj = anObj;
|
||||
anObj->myID = myObjects.Length();
|
||||
myObjects.Append (anObj);
|
||||
myMapObjects[theDrawType].Add(anObj->myID);
|
||||
anObj->myDrawType = theDrawType;
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : compactObjects
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Handle_NIS_Allocator NIS_InteractiveContext::compactObjects()
|
||||
{
|
||||
Handle(NIS_Allocator) aNewAlloc;
|
||||
|
||||
NCollection_List<Handle_NIS_View>::Iterator anIterV;
|
||||
// Check if the memory used by objects has to be compacted.
|
||||
const Standard_Size nAllocated = myAllocator->NAllocated();
|
||||
|
||||
if (nAllocated > 1024*1024) {
|
||||
const Standard_Size nFreed = myAllocator->NFreed();
|
||||
if ((nFreed * 5) / 3 > nAllocated || nFreed > 20*1024*1024)
|
||||
{
|
||||
for (anIterV.Init(myViews); anIterV.More(); anIterV.Next()) {
|
||||
const Handle(NIS_View)& aView = anIterV.Value();
|
||||
if (aView.IsNull() == Standard_False) {
|
||||
aView->myDynHilighted.Nullify();
|
||||
aView->GetDetected().Clear();
|
||||
}
|
||||
}
|
||||
// Compact the memory: clone all objects to a new allocator, release
|
||||
// the old allocator instance.
|
||||
aNewAlloc = new NIS_Allocator;
|
||||
NCollection_Vector<Handle_NIS_InteractiveObject>::Iterator
|
||||
anIter(myObjects);
|
||||
for (; anIter.More(); anIter.Next()) {
|
||||
if (anIter.Value().IsNull() == Standard_False) {
|
||||
Handle(NIS_InteractiveObject)& aNewObj = anIter.ChangeValue();
|
||||
const Handle(NIS_InteractiveObject) anObj = aNewObj;
|
||||
aNewObj.Nullify();
|
||||
anObj->CloneWithID(aNewAlloc, aNewObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return aNewAlloc;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : markAllDrawersUpdated
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void markAllDrawersUpdated (const NCollection_Map<Handle_NIS_Drawer>& lstDrv)
|
||||
{
|
||||
NCollection_Map<Handle_NIS_Drawer>::Iterator anIterD (lstDrv);
|
||||
for (; anIterD.More(); anIterD.Next()) {
|
||||
const Handle(NIS_Drawer)& aDrawer = anIterD.Value();
|
||||
if (aDrawer.IsNull() == Standard_False) {
|
||||
aDrawer->SetUpdated (NIS_Drawer::Draw_Normal,
|
||||
NIS_Drawer::Draw_Top,
|
||||
NIS_Drawer::Draw_Transparent,
|
||||
NIS_Drawer::Draw_Hilighted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,9 +9,9 @@
|
||||
|
||||
#include <Handle_NIS_InteractiveObject.hxx>
|
||||
#include <Handle_NIS_View.hxx>
|
||||
#include <NCollection_IncAllocator.hxx>
|
||||
#include <NCollection_Map.hxx>
|
||||
#include <NCollection_Vector.hxx>
|
||||
#include <NIS_Allocator.hxx>
|
||||
#include <NIS_Drawer.hxx>
|
||||
#include <NIS_SelectFilter.hxx>
|
||||
|
||||
@ -23,36 +23,42 @@
|
||||
|
||||
class NIS_View;
|
||||
class Bnd_B3f;
|
||||
class Bnd_B2f;
|
||||
|
||||
/**
|
||||
* InteractiveContext is the central NIS structure that stores and manages
|
||||
* all InteractiveObject instances as well as the Drawers for their
|
||||
* all NIS_InteractiveObject instances as well as the Drawers for their
|
||||
* visualisation.
|
||||
* There may be one or more Views referred by an InteractiveContext instance.
|
||||
* Also there may be one or more InteractiveContext instances referring the same
|
||||
* View. However the latter case is not typical (see NIS_View description).<br>
|
||||
* To add or remove a View in a Context, use methods AttachView() and
|
||||
* DetachView().
|
||||
* <p>The main purpose of class NIS_InteractiveContext is allocation and
|
||||
*
|
||||
* @section nis_interactivecontext_mgtobjects Management of objects
|
||||
* The main purpose of class NIS_InteractiveContext is allocation and
|
||||
* management of NIS_InteractiveObject instances.
|
||||
* <p>An InteractiveObject should be added to the Context by a call to method
|
||||
* Display(). After that (not before) it becomes possible to:
|
||||
* Display() or DisplayOnTop(). After that (not before) it becomes possible to:
|
||||
* <ul>
|
||||
* <li>change the presentation of the InteractiveObject (e.g., modify the color)
|
||||
* </li>
|
||||
* <li>make the InteractiveObject visible or invisible;</li>
|
||||
* <li>make the InteractiveObject visible or invisible, selectable or
|
||||
* unselectable;</li>
|
||||
* <li>set Transparency;</li>
|
||||
* <li>select InteractiveObject interactively, including the hilighting and
|
||||
* the dynamic hilighting.</li>
|
||||
* </ul>
|
||||
* All methods managing InteractiveObject instances have the optional parameter
|
||||
* 'isUpdateViews'. When it is set to True (default), the modification of the
|
||||
* object brings about the immediate update of the presentation (the
|
||||
* corresponding Drawer is flagged to recompute presentations). However, for
|
||||
* block operations when many InteractiveObject instances are affected it is
|
||||
* usually better to delay this recalculation till a definite moment in the end
|
||||
* of updates. Then you can set the optional parameter to False and in the end -
|
||||
* call the method UpdateViews of the NIS_InteractiveContext.
|
||||
* Methods that add/remove/display/hide NIS_InteractiveObject instances have
|
||||
* the optional parameter 'isUpdateViews'. When it is set to True (default),
|
||||
* the modification of the object brings about an immediate update of its
|
||||
* presentation (the corresponding Drawer flagged to recompute presentations).
|
||||
* Normally you do not have to worry about this parameter leaving it assigned to
|
||||
* the default value; use the alternative value 'Standard_False' only for
|
||||
* very special purposes, like animation -- when many updates should be
|
||||
* synchronized in time. For other methods like changing the transparency or
|
||||
* color definition there is no parameter 'isUpdateViews', all changes mark
|
||||
* the corresponding drawers immediately.
|
||||
* <p>Typical scheme of usage:
|
||||
* @code
|
||||
* const Handle(NIS_InteractiveContext) aContext = new NIS_InteractiveContext;
|
||||
@ -60,26 +66,53 @@ class Bnd_B3f;
|
||||
* aContext->AttachView (aView);
|
||||
* ....
|
||||
* for (; ;) {
|
||||
* const Handle(NIS_InteractiveObject) anObject = new ...
|
||||
* aContext->Display (anObject, NULL, Standard_False);
|
||||
* const Handle(MyIOClass) anObject = new MyIOClass();
|
||||
* aContext->Display (anObject);
|
||||
* anObject->SetColor(...); // method of class MyIOClass
|
||||
* ...
|
||||
* }
|
||||
* aContext->UpdateViews();
|
||||
* @endcode
|
||||
* Additional services provided by InteractiveContext:
|
||||
* @section nis_interactivecontext_display Method Display()
|
||||
* This method performs three important tasks, when called the first time for
|
||||
* an object:
|
||||
* <ul>
|
||||
* <li>Every instance of this class maintains a distinct
|
||||
* NCollection_IncAllocator that can be used by contained
|
||||
* NIS_InteractiveObject and NIS_Drawer instances. For example, each Object
|
||||
* may be assigned a name using the method SetAttribute, like:
|
||||
* @code
|
||||
* Standard_Size aLen = strlen(theName)+1;
|
||||
* char * aName = (char *) myContext->Allocator()->Allocate(aLen);
|
||||
* memcpy (aName, theName, aLen);
|
||||
* myObject->SetAttribute(aName);
|
||||
* @endcode
|
||||
* </li>
|
||||
* <li>Copy its argument to the memory pool that is managed by the internal
|
||||
* Allocator of NIS_InteractiveContext. Then <b>the new instance of
|
||||
* object</b> is returned back in the same argument (in-out parameter);</li>
|
||||
* <li>Store the copied instance in the internal vector of objects, so that
|
||||
* the displayed object receives its ID (sequential address in the vector);
|
||||
* </li>
|
||||
* <li>Create a Drawer instance if necessary; attach the displayed interactive
|
||||
* object to this instance (or to a relevant and already existing Drawer)
|
||||
* </li>
|
||||
* </ul>
|
||||
* Thus any methods dealing with Drawer-related properties like color, line
|
||||
* width, polygon offset, etc. can only be called following the necessary call
|
||||
* of method Display().
|
||||
* <p>
|
||||
* Subsequent calls to Display() just revert previous calls of Erase() without
|
||||
* any re-initialization of interactive object or its drawer.
|
||||
*
|
||||
* @section nis_interactivecontext_memory Using the memory
|
||||
* As described in the sections above, all interactive objects should completely
|
||||
* reside in the special memory pool managed by the InteractiveContext instance.
|
||||
* This is a fast memory (NCollection_IncAllocator is used) but it has the
|
||||
* drawback: when you destroy an object using method Remove() it is detached
|
||||
* from NIS_InteractiveContext and its presentation is removed from all Views.
|
||||
* But the memory allocated for that removed object is not released and it
|
||||
* cannot be reused by new interactive objects. In time there may appear too
|
||||
* many "dead" objects to hinder or even crash the application.
|
||||
* <p>
|
||||
* This problem is resolved by automatic keeping the record of the total size
|
||||
* of both used and unused memory, in the instance of NIS_Allocator. When the
|
||||
* amount of unused memory becomes too big then the method compactObjects()
|
||||
* creates a new NIS_Allocator instance and copies there all interactive
|
||||
* objects that are 'alive' then releasing the previous memory pool. All
|
||||
* object IDs and their drawers remain intact, so nothing is changed except
|
||||
* the greater amount of available memory in the system.
|
||||
* <p>
|
||||
* This mechanism works when either UpdateViews() or RebuildViews() is called
|
||||
* from time to time, only these two methods can call compactObjects().
|
||||
*/
|
||||
|
||||
class NIS_InteractiveContext : public Standard_Transient
|
||||
@ -135,7 +168,7 @@ class NIS_InteractiveContext : public Standard_Transient
|
||||
NbObjects ()
|
||||
// { return myObjects.Length()-1; }
|
||||
{ return (myMapObjects[0].Extent() + myMapObjects[1].Extent() +
|
||||
myMapObjects[2].Extent()); }
|
||||
myMapObjects[2].Extent()) + myMapObjects[3].Extent(); }
|
||||
|
||||
/**
|
||||
* Query the total number of Drawers instances.
|
||||
@ -145,11 +178,12 @@ class NIS_InteractiveContext : public Standard_Transient
|
||||
{ return myDrawers.Size(); }
|
||||
|
||||
/**
|
||||
* Query the memory allocator associated with InteractiveContext instance.
|
||||
*/
|
||||
inline const Handle_NCollection_IncAllocator&
|
||||
Allocator () const
|
||||
{ return myAllocator; }
|
||||
* Access to Drawers, can be used for specific operations where it is not
|
||||
* desirale to iterate InteractiveObjects.
|
||||
*/
|
||||
inline NCollection_Map<Handle_NIS_Drawer>::Iterator
|
||||
GetDrawers () const
|
||||
{ return NCollection_Map<Handle_NIS_Drawer>::Iterator(myDrawers); }
|
||||
|
||||
// ================ BEGIN Mangement of Objects ================
|
||||
///@name Management of Objects
|
||||
@ -161,6 +195,31 @@ class NIS_InteractiveContext : public Standard_Transient
|
||||
* this method should follow the creation of an InteractiveObject instance
|
||||
* before it can be displayed.
|
||||
* @param theObj
|
||||
* <tt>[in/out]</tt>Interactive object instance. If the object is displayed
|
||||
* for the first time then the output value will be a new (cloned) object.
|
||||
* @param theDrawer
|
||||
* If this parameter is NULL, the default drawer is used for theObj, defined
|
||||
* by the object type. Otherwise the given Drawer (must be present in this
|
||||
* context) is used for theObj. Use the parameter to change the presentation
|
||||
* of theObj.
|
||||
* @param isUpdateViews
|
||||
* If True, the drawer receives isUpdate flag, then it will recompute
|
||||
* the presentations when Redraw event happens. You can leave the parameter
|
||||
* to False if you have to make a number of similar calls, then you would
|
||||
* call UpdateViews() in the end.
|
||||
*/
|
||||
Standard_EXPORT void Display (Handle_NIS_InteractiveObject& theObj,
|
||||
const Handle_NIS_Drawer& theDrawer = NULL,
|
||||
const Standard_Boolean isUpdateViews
|
||||
= Standard_True);
|
||||
|
||||
/**
|
||||
* Make the given interactive object visible on top of other objects in
|
||||
* the current context.
|
||||
* If the object is not yet added to this context, it is added. Therefore
|
||||
* this method should follow the creation of an InteractiveObject instance
|
||||
* before it can be displayed.
|
||||
* @param theObj
|
||||
* Interactive object instance.
|
||||
* @param theDrawer
|
||||
* If this parameter is NULL, the default drawer is used for theObj, defined
|
||||
@ -173,10 +232,10 @@ class NIS_InteractiveContext : public Standard_Transient
|
||||
* to False if you have to make a number of similar calls, then you would
|
||||
* call UpdateViews() in the end.
|
||||
*/
|
||||
Standard_EXPORT void Display (const Handle_NIS_InteractiveObject& theObj,
|
||||
const Handle_NIS_Drawer& theDrawer = NULL,
|
||||
const Standard_Boolean isUpdateViews
|
||||
= Standard_True);
|
||||
Standard_EXPORT void DisplayOnTop (Handle_NIS_InteractiveObject& theObj,
|
||||
const Handle_NIS_Drawer& theDrawer = NULL,
|
||||
const Standard_Boolean isUpdateViews
|
||||
= Standard_True);
|
||||
|
||||
/**
|
||||
* Make the given object invisible in the current InteractiveContext.
|
||||
@ -209,45 +268,33 @@ class NIS_InteractiveContext : public Standard_Transient
|
||||
/**
|
||||
* Make all stored InteractiveObject instances visible, equivalent to
|
||||
* calling method Display() for all contained objects.
|
||||
* @param isUpdateViews
|
||||
* If True, the drawer receives isUpdate flag, then it will recompute
|
||||
* the presentations when Redraw event happens. You can leave the parameter
|
||||
* to False if you have to make a number of similar calls, then you would
|
||||
* call UpdateViews() in the end.
|
||||
*/
|
||||
Standard_EXPORT void DisplayAll (const Standard_Boolean isUpdateViews
|
||||
= Standard_True);
|
||||
Standard_EXPORT void DisplayAll ();
|
||||
|
||||
/**
|
||||
* Make all stored InteractiveObject instances invisible, equivalent to
|
||||
* calling method Erase() for all contained objects.
|
||||
* @param isUpdateViews
|
||||
* If True, the drawer receives isUpdate flag, then it will recompute
|
||||
* the presentations when Redraw event happens. You can leave the parameter
|
||||
* to False if you have to make a number of similar calls, then you would
|
||||
* call UpdateViews() in the end.
|
||||
*/
|
||||
Standard_EXPORT void EraseAll (const Standard_Boolean isUpdateViews
|
||||
= Standard_True);
|
||||
Standard_EXPORT void EraseAll ();
|
||||
|
||||
/**
|
||||
* Clean the context of its contained objects. Drawers are not destroyed
|
||||
* however all presentations should become empty.
|
||||
* @param isUpdateViews
|
||||
* If True, the drawer receives isUpdate flag, then it will recompute
|
||||
* the presentations when Redraw event happens. You can leave the parameter
|
||||
* to False if you have to make a number of similar calls, then you would
|
||||
* call UpdateViews() in the end.
|
||||
* Clean the context of its contained objects. Drawers are destroyed
|
||||
* and all presentations become empty.
|
||||
*/
|
||||
Standard_EXPORT void RemoveAll (const Standard_Boolean isUpdateViews
|
||||
= Standard_True);
|
||||
Standard_EXPORT void RemoveAll ();
|
||||
|
||||
/**
|
||||
* This method signal that the presenation should be refreshed in all
|
||||
* Drawers and in all Views.
|
||||
* This method signals that the presenation should be refreshed in all updated
|
||||
* Drawers and in all Views. Calls Redraw() of each view from inside.
|
||||
*/
|
||||
Standard_EXPORT void UpdateViews ();
|
||||
|
||||
/**
|
||||
* Similar to UpdateViews but forces all presentations to be rebuilt whether
|
||||
* the drawers are marked as updated or not.
|
||||
*/
|
||||
Standard_EXPORT void RebuildViews();
|
||||
|
||||
/**
|
||||
* Find the bounding box of all Objects displayed (visible) in the given View.
|
||||
* @param theBox
|
||||
@ -402,24 +449,35 @@ class NIS_InteractiveContext : public Standard_Transient
|
||||
inline Standard_Boolean IsSelectable (const Standard_Integer objID) const
|
||||
{ return (myMapNonSelectableObjects.Contains( objID ) == Standard_False); }
|
||||
|
||||
/**
|
||||
* Set or reset the flag that tells to NIS_Drawer to create shared DrawList.
|
||||
* The default mode (in Constructor) is True.
|
||||
*/
|
||||
inline void SetShareDrawList (Standard_Boolean isShare)
|
||||
{ myIsShareDrawList = isShare; }
|
||||
|
||||
//@}
|
||||
// ====== END Selection API ================
|
||||
|
||||
protected:
|
||||
//! Structure referencing one detected (picked) interactive entity.
|
||||
struct DetectedEnt
|
||||
{
|
||||
Standard_Real Dist; //!< Distance on the view direction
|
||||
NIS_InteractiveObject* PObj; //!< Pointer to interactive object
|
||||
};
|
||||
|
||||
// ---------- PROTECTED METHODS ----------
|
||||
|
||||
Standard_EXPORT void redraw (const Handle_NIS_View& theView,
|
||||
const NIS_Drawer::DrawType theType);
|
||||
|
||||
/*Standard_EXPORT void prepareList (const NIS_Drawer::DrawType theType,
|
||||
const NIS_DrawList& theView,
|
||||
NIS_Drawer * theDrawer);
|
||||
*/
|
||||
/**
|
||||
* Detect the object selected by the given ray.
|
||||
* @param theSel
|
||||
* <tt>[out]</tt> The selected object that has the lowest ray distance.
|
||||
* @param theDet
|
||||
* <tt>[out]</tt> Sorted list of all detected objects with ray distances
|
||||
* @param theAxis
|
||||
* Selection ray
|
||||
* @param theOver
|
||||
@ -432,6 +490,7 @@ class NIS_InteractiveContext : public Standard_Transient
|
||||
*/
|
||||
Standard_EXPORT Standard_Real
|
||||
selectObject (Handle_NIS_InteractiveObject& theSel,
|
||||
NCollection_List<DetectedEnt>& theDet,
|
||||
const gp_Ax1& theAxis,
|
||||
const Standard_Real theOver,
|
||||
const Standard_Boolean isOnlySelectable
|
||||
@ -461,9 +520,58 @@ class NIS_InteractiveContext : public Standard_Transient
|
||||
const gp_Trsf& theTrfInv,
|
||||
const Standard_Boolean isFullyIn)const;
|
||||
|
||||
/**
|
||||
* Build a list of objects that are inside or touched by a polygon.
|
||||
* @param mapObj
|
||||
* <tt>[out]</tt> Container of object IDs, updated by detected objects.
|
||||
* @param thePolygon
|
||||
* the list of vertices of a free-form closed polygon without
|
||||
* self-intersections. The last point should not coincide with the first
|
||||
* point of the list. Any two neighbor points should not be confused.
|
||||
* @param thePolygonBox
|
||||
* 2D box of selection polygon
|
||||
* @param theTrfInv
|
||||
* Inverted Position/Orientation of the plane where thePolygon is defined
|
||||
* (for polygon-object intersections)
|
||||
* @param isFullyIn
|
||||
* True if only those objects are processed that are fully inside the
|
||||
* selection polygon. False if objects fully or partially included in
|
||||
* the polygon are processed.
|
||||
* @return
|
||||
* True if at least one object was selected.
|
||||
*/
|
||||
Standard_EXPORT Standard_Boolean
|
||||
selectObjects (TColStd_PackedMapOfInteger &mapObj,
|
||||
const NCollection_List<gp_XY> &thePolygon,
|
||||
const Bnd_B2f &thePolygonBox,
|
||||
const gp_Trsf &theTrfInv,
|
||||
const Standard_Boolean isFullyIn) const;
|
||||
|
||||
private:
|
||||
void deselectObj (const Handle_NIS_InteractiveObject&,
|
||||
const Standard_Integer);
|
||||
|
||||
void selectObj (const Handle_NIS_InteractiveObject&,
|
||||
const Standard_Integer);
|
||||
|
||||
const Handle_NIS_Drawer&
|
||||
drawerForDisplay (const Handle_NIS_InteractiveObject&,
|
||||
const Handle_NIS_Drawer&);
|
||||
|
||||
void objectForDisplay (Handle_NIS_InteractiveObject&,
|
||||
const NIS_Drawer::DrawType);
|
||||
|
||||
Handle_NIS_Allocator
|
||||
compactObjects ();
|
||||
|
||||
private:
|
||||
// ---------- PRIVATE FIELDS ----------
|
||||
|
||||
/**
|
||||
* Allocator for all data associated with objects.
|
||||
*/
|
||||
Handle_NIS_Allocator myAllocator;
|
||||
|
||||
/**
|
||||
* Container of InteractiveObject instances.
|
||||
*/
|
||||
@ -483,11 +591,12 @@ class NIS_InteractiveContext : public Standard_Transient
|
||||
/**
|
||||
* Three maps indicating the state of contained objects:
|
||||
* - #0 - normally presented objects
|
||||
* - #1 - hilighted objects (i.e., selected)
|
||||
* - #2 - transparent objects
|
||||
* - #1 - top objects
|
||||
* - #2 - hilighted objects (i.e., selected)
|
||||
* - #3 - transparent objects
|
||||
* <br>Each object can have only one entry in these maps.
|
||||
*/
|
||||
TColStd_PackedMapOfInteger myMapObjects[3];
|
||||
TColStd_PackedMapOfInteger myMapObjects[4];
|
||||
|
||||
/**
|
||||
* Objects contained in this map are ignored by SetSelected methods,
|
||||
@ -500,20 +609,15 @@ class NIS_InteractiveContext : public Standard_Transient
|
||||
*/
|
||||
Handle_NIS_SelectFilter mySelectFilter;
|
||||
|
||||
/**
|
||||
* Current selection.
|
||||
*/
|
||||
// TColStd_PackedMapOfInteger mySelection;
|
||||
|
||||
/**
|
||||
* Current mode of selection.
|
||||
*/
|
||||
SelectionMode mySelectionMode;
|
||||
|
||||
/**
|
||||
* Allocator for arbitrary data associated with objects and drawers.
|
||||
* Flag that allows to use single draw list for all views.
|
||||
*/
|
||||
Handle_NCollection_IncAllocator myAllocator;
|
||||
Standard_Boolean myIsShareDrawList;
|
||||
|
||||
friend class NIS_View;
|
||||
friend class NIS_Drawer;
|
||||
|
@ -28,7 +28,8 @@ NIS_InteractiveObject::~NIS_InteractiveObject ( )
|
||||
//=======================================================================
|
||||
|
||||
const Handle_NIS_Drawer& NIS_InteractiveObject::SetDrawer
|
||||
(const Handle(NIS_Drawer)& theDrawer)
|
||||
(const Handle(NIS_Drawer)& theDrawer,
|
||||
const Standard_Boolean setUpdated)
|
||||
{
|
||||
NIS_InteractiveContext * aCtx = theDrawer->GetContext();
|
||||
if (myDrawer.IsNull() == Standard_False)
|
||||
@ -47,6 +48,8 @@ const Handle_NIS_Drawer& NIS_InteractiveObject::SetDrawer
|
||||
Standard_NullValue_Raise_if
|
||||
(aCtx == 0L, "NIS_InteractiveObject::SetDrawer: NULL drawer context");
|
||||
// Add (if necessary) the new drawer to the Context
|
||||
if (theDrawer->myIniId == 0)
|
||||
theDrawer->myIniId = myID;
|
||||
const Handle(NIS_Drawer)& aDrawer = aCtx->myDrawers.Added (theDrawer);
|
||||
if (myDrawer != aDrawer)
|
||||
{
|
||||
@ -55,8 +58,13 @@ const Handle_NIS_Drawer& NIS_InteractiveObject::SetDrawer
|
||||
myDrawer->removeObject(this, Standard_True);
|
||||
myDrawer = aDrawer;
|
||||
|
||||
myDrawer->addObject(this, Standard_True);
|
||||
myDrawer->addObject(this, aCtx->myIsShareDrawList, Standard_True);
|
||||
}
|
||||
if (setUpdated)
|
||||
myDrawer->SetUpdated (NIS_Drawer::Draw_Normal,
|
||||
NIS_Drawer::Draw_Top,
|
||||
NIS_Drawer::Draw_Transparent,
|
||||
NIS_Drawer::Draw_Hilighted);
|
||||
return aDrawer;
|
||||
}
|
||||
|
||||
@ -67,13 +75,23 @@ const Handle_NIS_Drawer& NIS_InteractiveObject::SetDrawer
|
||||
|
||||
void NIS_InteractiveObject::SetTransparency (const Standard_Real theValue)
|
||||
{
|
||||
if (fabs(theValue - myTransparency) > 0.001) {
|
||||
if (theValue > 0.001)
|
||||
myTransparency = static_cast<const Standard_ShortReal> (theValue);
|
||||
Standard_Integer aValue =
|
||||
static_cast<Standard_Integer> (theValue * MaxTransparency);
|
||||
if (aValue != static_cast<Standard_Integer>(myTransparency))
|
||||
{
|
||||
if (aValue <= 0)
|
||||
myTransparency = 0;
|
||||
else if (aValue >= 1000)
|
||||
myTransparency = 1000u;
|
||||
else
|
||||
myTransparency = 0.f;
|
||||
myTransparency = static_cast<unsigned int> (aValue);
|
||||
|
||||
if (myDrawer.IsNull() == Standard_False && myID != 0) {
|
||||
const Handle(NIS_Drawer) aDrawer = DefaultDrawer(0L);
|
||||
aDrawer->Assign (GetDrawer());
|
||||
aDrawer->myTransparency = Transparency();
|
||||
SetDrawer (aDrawer, Standard_False);
|
||||
|
||||
NIS_InteractiveContext * aCtx = myDrawer->GetContext();
|
||||
Standard_NullValue_Raise_if
|
||||
(aCtx == 0L, "NIS_InteractiveObject::SetTransparency: "
|
||||
@ -113,6 +131,44 @@ const Bnd_B3f& NIS_InteractiveObject::GetBox ()
|
||||
return myBox;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Clone
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void NIS_InteractiveObject::Clone (const Handle_NCollection_BaseAllocator&,
|
||||
Handle_NIS_InteractiveObject& theDest) const
|
||||
{
|
||||
if (theDest.IsNull() == Standard_False)
|
||||
{
|
||||
theDest->myID = 0;
|
||||
theDest->myDrawer = myDrawer;
|
||||
theDest->myDrawType = myDrawType;
|
||||
theDest->myBaseType = myBaseType;
|
||||
theDest->myIsHidden = myIsHidden;
|
||||
theDest->myIsDynHilighted = myIsDynHilighted;
|
||||
theDest->myIsUpdateBox = myIsUpdateBox;
|
||||
theDest->myTransparency = myTransparency;
|
||||
if (myIsUpdateBox == Standard_False)
|
||||
theDest->myBox = myBox;
|
||||
theDest->myAttributePtr = myAttributePtr;
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : CloneWithID
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void NIS_InteractiveObject::CloneWithID
|
||||
(const Handle_NCollection_BaseAllocator& theAlloc,
|
||||
Handle_NIS_InteractiveObject& theDest)
|
||||
{
|
||||
Clone(theAlloc, theDest);
|
||||
theDest->myID = myID;
|
||||
myDrawer.Nullify();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Intersect
|
||||
//purpose :
|
||||
@ -125,6 +181,19 @@ Standard_Boolean NIS_InteractiveObject::Intersect (const Bnd_B3f&,
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Intersect
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean NIS_InteractiveObject::Intersect
|
||||
(const NCollection_List<gp_XY> &thePolygon,
|
||||
const gp_Trsf &theTrf,
|
||||
const Standard_Boolean isFull) const
|
||||
{
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsSelectable
|
||||
//purpose : Query if the Object is selectable.
|
||||
@ -151,16 +220,10 @@ void NIS_InteractiveObject::SetSelectable (const Standard_Boolean isSel) const
|
||||
aCtx->myMapNonSelectableObjects.Remove (myID);
|
||||
else {
|
||||
aCtx->myMapNonSelectableObjects.Add (myID);
|
||||
if (aCtx->myMapObjects[NIS_Drawer::Draw_Hilighted].Remove(myID))
|
||||
if (myDrawType == NIS_Drawer::Draw_Hilighted)
|
||||
{
|
||||
if (IsTransparent()) {
|
||||
aCtx->myMapObjects[NIS_Drawer::Draw_Transparent].Add(myID);
|
||||
myDrawer->SetUpdated(NIS_Drawer::Draw_Transparent);
|
||||
} else {
|
||||
aCtx->myMapObjects[NIS_Drawer::Draw_Normal].Add(myID);
|
||||
myDrawer->SetUpdated(NIS_Drawer::Draw_Normal);
|
||||
}
|
||||
myDrawer->SetUpdated(NIS_Drawer::Draw_Hilighted);
|
||||
aCtx->myMapObjects[NIS_Drawer::Draw_Hilighted].Remove(myID);
|
||||
aCtx->deselectObj (this, myID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,22 +16,26 @@
|
||||
* An InteractiveObject has the attributes:
|
||||
* <ul>
|
||||
* <li>Integer ID that is unique within the Interactive Context that hosts
|
||||
* this Object. Thsi ID is 0 if the Object is not yet attached to an
|
||||
* this Object. This ID is 0 if the Object is not yet attached to an
|
||||
* InteractiveContext</li>
|
||||
* <li>3D Bounding box</li>
|
||||
* <li>Presenatble state of the Object: Normal, Hilighted or Transparent.</li>
|
||||
* <li>Presentable state of the Object: Normal, Hilighted or Transparent.</li>
|
||||
* <li>Visibility state (shown/hidden)</li>
|
||||
* <li>Transparency level (0 to 1) - for transparent state</li>
|
||||
* <li>Selectability (selectable/non-selectable)</li>
|
||||
* <li>Transparency level (0 to 1 in 1/1000 steps) - for transparent state</li>
|
||||
* </ul>
|
||||
* Because the class is abstract, it does not define any color, material and
|
||||
* other visual aspect - all relevant aspects should be defined in derived
|
||||
* classes.<br>
|
||||
* classes and their Drawers.
|
||||
*
|
||||
* @section nis_interactiveobject_drawer Drawers for NIS_InteractiveObject
|
||||
* Every InteractiveObject type should have an associated NIS_Drawer type; a
|
||||
* new instance of this associated drawer is returned by the virtual method
|
||||
* new instance of this associated drawer must be returned by the virtual method
|
||||
* DefaultDrawer(). The drawer is responsible for the correct calculation of
|
||||
* the presentation in every possible state (normal, hilighted, etc.); usually
|
||||
* the associated drawer instance contains all relevant visual aspects.<p>
|
||||
* Association with a Drawer instance is performed by method SetDrawer. This
|
||||
* the associated drawer instance contains all relevant visual aspects.
|
||||
* <p>
|
||||
* Association with a Drawer instance is performed by method SetDrawer(). This
|
||||
* method should not be called by any custom code, it is used internally by
|
||||
* NIS algorithms (in NIS_InteractiveContext::Display() for instance). If you
|
||||
* develop your own InteractiveObject type, you will need to call SetDrawer
|
||||
@ -39,17 +43,68 @@
|
||||
* @code
|
||||
* void MyIOClass::SetColor (const Quantity_Color& theColor);
|
||||
* {
|
||||
* Handle(MyIOClassDrawer) aDrawer = new MyIOClassDrawer;
|
||||
* const Handle(MyIOClassDrawer) aDrawer =
|
||||
* static_cast<MyIOClassDrawer*>(DefaultDrawer(0L));
|
||||
* // copy the current visual aspects and other attributes to the new Drawer
|
||||
* aDrawer->Assign (GetDrawer());
|
||||
* // replace the Drawer
|
||||
* aDrawer->myColor = theColor;
|
||||
* SetDrawer (aDrawer);
|
||||
* // optional: redraws the changed InteractiveObject in the views
|
||||
* GetDrawer()->GetContext()->UpdateViews();
|
||||
* }
|
||||
* @endcode
|
||||
* <p>
|
||||
* Please keep in mind that with this scheme you should not store the color in
|
||||
* MyIOClass type, because it is already stored in its Drawer.
|
||||
*
|
||||
* @section nis_interactiveobject_selection Interactive selection
|
||||
* Interactive selection is made in class NIS_InteractiveContext, methods
|
||||
* selectObjects(). These methods call the virtual API of interactive object,
|
||||
* that consists of 3 methods:
|
||||
* <ul>
|
||||
* <li>Intersect (theAxis, theOver) : find the intersection point with a 3D ray,
|
||||
* the method returns the coordinate of intersection point on the ray.
|
||||
* Parameter theOver provides the tolerance for intersection of thin
|
||||
* geometries (lines, vertices)</li>
|
||||
* <li>Intersect (theBox, theTrsf, isFullIn) : check if the interactive object
|
||||
* intersects with a 3D box. Transformation 'theTrf' is the <b>inverse</b>
|
||||
* box transformation, so it is applied to the interactive object rather
|
||||
* than to the 3D box (3D box stays axis-aligned during intersection
|
||||
* test). Parameter IsFullIn defines the condition for the result: if
|
||||
* True then the whole interactive object must be contained inside the box,
|
||||
* otherwise it is sufficient if only a portion (e.g., a point) is inside.
|
||||
* This method is used for interactive rectangle selection.</li>
|
||||
* <li>Intersect (thePolygon, theTrsf, isFullIn) : similar to the previous
|
||||
* method, but using a polygonal prism instead of box, for selection by
|
||||
* closed curve or polygon.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @section nis_interactiveobject_memory Memory management
|
||||
* All data used in the scope of NIS_InteractiveObject subtype should be either
|
||||
* its explicit fields or pointers to memory managed by a special NIS_Allocator
|
||||
* instance that belongs to NIS_InteractiveContext. This is strictly required
|
||||
* because NIS_InteractiveContext should completely manage all its objects,
|
||||
* meaning that it destroys/reallocates them automatically. To support that,
|
||||
* the virtual method Clone() should be correctly defined for every interactive
|
||||
* object subtype. Supposing that MyIOClass inherits MyBaseIOBase :
|
||||
* @code
|
||||
* void MyIOCalss::Clone (const Handle_NCollection_BaseAllocator& theAlloc,
|
||||
* Handle_NIS_InteractiveObject& theDest) const
|
||||
* {
|
||||
* Handle(MyIOClass) aNewObj;
|
||||
* if (theDest.IsNull()) {
|
||||
* aNewObj = new MyIOClass();
|
||||
* theDest = aNewObj;
|
||||
* } else {
|
||||
* aNewObj = reinterpret_cast<MyIOClass*> (theDest.operator->());
|
||||
* aNewObj->myAlloc = theAlloc;
|
||||
* }
|
||||
* MyIOBase::Clone(theAlloc, theDest);
|
||||
* aNewObj->myDataField = myDataField;
|
||||
* memcpy(myNewObj->myDataArray, myDataArray, nBytes);
|
||||
* ...
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @section nis_interactiveobject_attribute Attribute
|
||||
* An instance of this class can have an associated value (Attribute) that is
|
||||
* stored as a pointer. It can accommodate an integer/float/boolean value or
|
||||
* a pointer to some structure. This attribute is NOT automatically destroyed
|
||||
@ -68,10 +123,11 @@ class NIS_InteractiveObject : public Standard_Transient
|
||||
inline NIS_InteractiveObject ()
|
||||
: myID (0),
|
||||
myDrawType (NIS_Drawer::Draw_Normal),
|
||||
myBaseType (NIS_Drawer::Draw_Normal),
|
||||
myIsHidden (Standard_True),
|
||||
myIsDynHilighted (Standard_False),
|
||||
myIsUpdateBox (Standard_True),
|
||||
myTransparency (0.f),
|
||||
myTransparency (0),
|
||||
myAttributePtr (0L)
|
||||
{}
|
||||
|
||||
@ -106,7 +162,9 @@ class NIS_InteractiveObject : public Standard_Transient
|
||||
* the Context.
|
||||
*/
|
||||
Standard_EXPORT const Handle_NIS_Drawer&
|
||||
SetDrawer (const Handle_NIS_Drawer& theDrawer);
|
||||
SetDrawer (const Handle_NIS_Drawer& theDrawer,
|
||||
const Standard_Boolean setUpdated
|
||||
= Standard_True);
|
||||
|
||||
/**
|
||||
* Query the current drawer.
|
||||
@ -116,10 +174,14 @@ class NIS_InteractiveObject : public Standard_Transient
|
||||
{ return myDrawer; }
|
||||
|
||||
/**
|
||||
* Create a default drawer instance.
|
||||
* Create a default drawer instance. In the upper-level call (in subclass)
|
||||
* it is always called with NULL parameter. Then it should call the same
|
||||
* method of the superclass (except for NIS_InteractiveObject superclass type)
|
||||
* with the created Drawer instance as parameter.
|
||||
* @see NIS_Triangulated as example.
|
||||
*/
|
||||
Standard_EXPORT virtual Handle_NIS_Drawer
|
||||
DefaultDrawer () const = 0;
|
||||
Standard_EXPORT virtual NIS_Drawer *
|
||||
DefaultDrawer (NIS_Drawer * theDrv) const = 0;
|
||||
|
||||
/**
|
||||
* Query a 3D bounding box of the object.
|
||||
@ -131,7 +193,7 @@ class NIS_InteractiveObject : public Standard_Transient
|
||||
* Query the Transparent state.
|
||||
*/
|
||||
inline Standard_Boolean IsTransparent () const
|
||||
{ return myTransparency > 0.001; }
|
||||
{ return myTransparency > 0; }
|
||||
|
||||
/**
|
||||
* Query the Hidden state
|
||||
@ -154,7 +216,7 @@ class NIS_InteractiveObject : public Standard_Transient
|
||||
/**
|
||||
* Query if the Object is selectable.
|
||||
*/
|
||||
Standard_EXPORT Standard_Boolean
|
||||
Standard_EXPORT virtual Standard_Boolean
|
||||
IsSelectable () const;
|
||||
|
||||
/**
|
||||
@ -163,14 +225,15 @@ class NIS_InteractiveObject : public Standard_Transient
|
||||
* True (default) - the Object will be selectable, False - it will be
|
||||
* ignored by selection/hilighting algorithms.
|
||||
*/
|
||||
Standard_EXPORT void SetSelectable (const Standard_Boolean isSel
|
||||
Standard_EXPORT virtual void
|
||||
SetSelectable (const Standard_Boolean isSel
|
||||
= Standard_True) const;
|
||||
|
||||
/**
|
||||
* Query the Transparency factor.
|
||||
*/
|
||||
inline Standard_Real Transparency () const
|
||||
{ return myTransparency; }
|
||||
inline Standard_ShortReal Transparency () const
|
||||
{ return static_cast<Standard_ShortReal>(myTransparency) / MaxTransparency; }
|
||||
|
||||
/**
|
||||
* Set the Transparency factor.
|
||||
@ -183,6 +246,23 @@ class NIS_InteractiveObject : public Standard_Transient
|
||||
inline void UnsetTransparency ()
|
||||
{ SetTransparency (0.); }
|
||||
|
||||
/**
|
||||
* Create a copy of theObject except its ID.
|
||||
* @param theAll
|
||||
* Allocator where the Dest should store its private data.
|
||||
* @param theDest
|
||||
* <tt>[in-out]</tt> The target object where the data are copied.
|
||||
*/
|
||||
Standard_EXPORT virtual void
|
||||
Clone (const Handle_NCollection_BaseAllocator& theAll,
|
||||
Handle_NIS_InteractiveObject& theDest) const;
|
||||
|
||||
/**
|
||||
* The same as Clone() but also copies the ID.
|
||||
*/
|
||||
Standard_EXPORT void CloneWithID (const Handle_NCollection_BaseAllocator&,
|
||||
Handle_NIS_InteractiveObject&);
|
||||
|
||||
/**
|
||||
* Intersect the InteractiveObject geometry with a line/ray.
|
||||
* @param theAxis
|
||||
@ -227,6 +307,32 @@ class NIS_InteractiveObject : public Standard_Transient
|
||||
const gp_Trsf& theTrf,
|
||||
const Standard_Boolean isFull) const;
|
||||
|
||||
/**
|
||||
* Intersect the InteractiveObject geometry with a selection polygon.
|
||||
* The default implementation (in this abstract class) always returns True,
|
||||
* signalling that every object pre-selected by its bounding box is
|
||||
* automatically selected. The specializations should define a more correct
|
||||
* behaviour.<br>
|
||||
* The algorithm should transform the InteractiveObject geometry using the
|
||||
* parameter theTrf and then reject it with polygon.
|
||||
* @param thePolygon
|
||||
* the list of vertices of a free-form closed polygon without
|
||||
* self-intersections. The last point should not coincide with the first
|
||||
* point of the list. Any two neighbor points should not be confused.
|
||||
* @param theTrf
|
||||
* Position/Orientation of the polygon. It coincides with theTrfInv that is
|
||||
* passed to NIS_InteractiveContext::selectObjects().
|
||||
* @param isFull
|
||||
* True if full inclusion is required (full inside the tested box) for
|
||||
* the positive result, False - if only partial inclusion give a result.
|
||||
* @return
|
||||
* True if the InteractiveObject geometry intersects the polygon or is inside it
|
||||
*/
|
||||
Standard_EXPORT virtual Standard_Boolean
|
||||
Intersect (const NCollection_List<gp_XY> &thePolygon,
|
||||
const gp_Trsf &theTrf,
|
||||
const Standard_Boolean isFull) const;
|
||||
|
||||
/**
|
||||
* Set the pointer to custom (arbitrary) data associated with the Object.
|
||||
*/
|
||||
@ -267,18 +373,21 @@ class NIS_InteractiveObject : public Standard_Transient
|
||||
// ---------- PRIVATE FIELDS ----------
|
||||
|
||||
Handle_NIS_Drawer myDrawer;
|
||||
Standard_Size myID : 26;
|
||||
NIS_Drawer::DrawType myDrawType : 2;
|
||||
Standard_Size myID;
|
||||
NIS_Drawer::DrawType myDrawType : 3;
|
||||
NIS_Drawer::DrawType myBaseType : 3;
|
||||
Standard_Boolean myIsHidden : 1;
|
||||
Standard_Boolean myIsDynHilighted: 1;
|
||||
|
||||
Standard_Boolean myIsUpdateBox : 1;
|
||||
Standard_ShortReal myTransparency;
|
||||
unsigned int myTransparency : 10;
|
||||
static const unsigned int MaxTransparency = 1000;
|
||||
|
||||
protected:
|
||||
Bnd_B3f myBox;
|
||||
void * myAttributePtr;
|
||||
|
||||
|
||||
friend class NIS_InteractiveContext;
|
||||
friend class NIS_Drawer;
|
||||
|
||||
|
@ -34,3 +34,16 @@ void NIS_ObjectsIterator::Next ()
|
||||
if (myIter.Value().IsNull() == Standard_False)
|
||||
break;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Value
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
const Handle(NIS_InteractiveObject)& NIS_ObjectsIterator::Value() const
|
||||
{
|
||||
if (More())
|
||||
return myIter.Value();
|
||||
static const Handle(NIS_InteractiveObject) aNullObj;
|
||||
return aNullObj;
|
||||
}
|
||||
|
@ -69,9 +69,8 @@ class NIS_ObjectsIterator
|
||||
* Returns the current object at the iteration pointer. If the iteration is
|
||||
* over (More() == False) this method returns NULL Handle.
|
||||
*/
|
||||
inline Handle(NIS_InteractiveObject)
|
||||
Value () const
|
||||
{ if (More()) return myIter.Value(); return NULL; }
|
||||
Standard_EXPORT const Handle_NIS_InteractiveObject&
|
||||
Value () const;
|
||||
|
||||
/**
|
||||
* Step forward to the next valid InteractiveObject instance.
|
||||
|
@ -6,31 +6,39 @@
|
||||
#include <NIS_Surface.hxx>
|
||||
#include <NIS_SurfaceDrawer.hxx>
|
||||
#include <NIS_Triangulated.hxx>
|
||||
#include <BRepMesh_IncrementalMesh.hxx>
|
||||
#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
|
||||
#include <BRep_PolygonOnTriangulation.hxx>
|
||||
#include <BRep_TEdge.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <Geom_Surface.hxx>
|
||||
#include <NCollection_Map.hxx>
|
||||
#include <Poly_PolygonOnTriangulation.hxx>
|
||||
#include <Poly_Triangulation.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopLoc_Location.hxx>
|
||||
#include <TopTools_MapOfShape.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TShort_Array1OfShortReal.hxx>
|
||||
#include <gp_Ax1.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_HANDLE (NIS_Surface, NIS_InteractiveObject)
|
||||
IMPLEMENT_STANDARD_RTTIEXT(NIS_Surface, NIS_InteractiveObject)
|
||||
|
||||
//=======================================================================
|
||||
//function : defaultDrawer
|
||||
//purpose : internal method (static)
|
||||
//function : IsEqual
|
||||
//purpose : Compare two triangulations, for NCollection_Map interface.
|
||||
//=======================================================================
|
||||
|
||||
inline Handle(NIS_SurfaceDrawer) defaultDrawer()
|
||||
inline Standard_Boolean IsEqual(const Handle_Poly_Triangulation& theT0,
|
||||
const Handle_Poly_Triangulation& theT1)
|
||||
{
|
||||
const Handle(NIS_SurfaceDrawer) aDrawer =
|
||||
new NIS_SurfaceDrawer(Quantity_NOC_SLATEBLUE4);
|
||||
aDrawer->SetBackColor (Quantity_NOC_DARKGREEN);
|
||||
return aDrawer;
|
||||
return (theT0 == theT1);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@ -38,14 +46,36 @@ inline Handle(NIS_SurfaceDrawer) defaultDrawer()
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
NIS_Surface::NIS_Surface
|
||||
(const Handle(Poly_Triangulation)& theTri,
|
||||
const Handle_NCollection_BaseAllocator& theAlloc)
|
||||
: mypNodes (NULL),
|
||||
mypNormals (NULL),
|
||||
myNNodes (0),
|
||||
myNTriangles (0),
|
||||
myAlloc (theAlloc)
|
||||
NIS_Surface::NIS_Surface(const Handle_NCollection_BaseAllocator& theAlloc)
|
||||
: myAlloc (theAlloc),
|
||||
mypNodes (NULL),
|
||||
mypNormals (NULL),
|
||||
mypTriangles (NULL),
|
||||
mypEdges (NULL),
|
||||
myNNodes (0),
|
||||
myNTriangles (0),
|
||||
myNEdges (0),
|
||||
myIsWireframe(0)
|
||||
{
|
||||
if (myAlloc.IsNull())
|
||||
myAlloc = NCollection_BaseAllocator::CommonBaseAllocator();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : NIS_Surface
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
NIS_Surface::NIS_Surface (const Handle(Poly_Triangulation)& theTri,
|
||||
const Handle_NCollection_BaseAllocator& theAlloc)
|
||||
: myAlloc (theAlloc),
|
||||
mypNodes (NULL),
|
||||
mypNormals (NULL),
|
||||
mypEdges (NULL),
|
||||
myNNodes (0),
|
||||
myNTriangles (0),
|
||||
myNEdges (0),
|
||||
myIsWireframe(0)
|
||||
{
|
||||
if (myAlloc.IsNull())
|
||||
myAlloc = NCollection_BaseAllocator::CommonBaseAllocator();
|
||||
@ -107,47 +137,75 @@ NIS_Surface::NIS_Surface
|
||||
//purpose : Constructor
|
||||
//=======================================================================
|
||||
|
||||
NIS_Surface::NIS_Surface
|
||||
(const TopoDS_Shape& theShape,
|
||||
// const Standard_Real theDeflection,
|
||||
const Handle_NCollection_BaseAllocator& theAlloc)
|
||||
: mypNodes (NULL),
|
||||
NIS_Surface::NIS_Surface (const TopoDS_Shape& theShape,
|
||||
const Standard_Real theDeflection,
|
||||
const Handle_NCollection_BaseAllocator& theAlloc)
|
||||
: myAlloc (theAlloc),
|
||||
mypNodes (NULL),
|
||||
mypNormals (NULL),
|
||||
mypTriangles (NULL),
|
||||
mypEdges (NULL),
|
||||
myNNodes (0),
|
||||
myNTriangles (0),
|
||||
myAlloc (theAlloc)
|
||||
myNEdges (0),
|
||||
myIsWireframe (0)
|
||||
{
|
||||
if (myAlloc.IsNull())
|
||||
myAlloc = NCollection_BaseAllocator::CommonBaseAllocator();
|
||||
Init (theShape, theDeflection);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Init
|
||||
//purpose : Initialize the instance with a TopoDS_Shape.
|
||||
//=======================================================================
|
||||
|
||||
void NIS_Surface::Init (const TopoDS_Shape& theShape,
|
||||
const Standard_Real theDeflection)
|
||||
{
|
||||
TopLoc_Location aLoc, aLocSurf;
|
||||
|
||||
// Count the nodes and triangles in faces
|
||||
NCollection_Map<Handle_Poly_Triangulation> mapTri;
|
||||
TopExp_Explorer fexp (theShape, TopAbs_FACE);
|
||||
for ( ; fexp.More(); fexp.Next() )
|
||||
for (; fexp.More(); fexp.Next())
|
||||
{
|
||||
TopoDS_Face aFace = TopoDS::Face(fexp.Current());
|
||||
const TopoDS_Face& aFace = TopoDS::Face(fexp.Current());
|
||||
|
||||
const Handle(Poly_Triangulation)& aTriangulation
|
||||
= BRep_Tool::Triangulation (aFace, aLoc);
|
||||
const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(aFace, aLoc);
|
||||
|
||||
if (aTriangulation.IsNull())
|
||||
BRepMesh_IncrementalMesh aMeshTool(aFace, theDeflection);
|
||||
|
||||
if (aTriangulation.IsNull() == Standard_False &&
|
||||
aSurf.IsNull() == Standard_False)
|
||||
if (aTriangulation.IsNull() == Standard_False)
|
||||
{
|
||||
myNNodes += aTriangulation->NbNodes();
|
||||
myNTriangles += aTriangulation->NbTriangles();
|
||||
mapTri.Add(aTriangulation);
|
||||
}
|
||||
}
|
||||
|
||||
// Alocate arrays of entities
|
||||
// Create map of edges, to build wireframe for all edges.
|
||||
TopTools_MapOfShape mapEdges;
|
||||
TopExp_Explorer eexp (theShape, TopAbs_EDGE);
|
||||
for (; eexp.More(); eexp.Next())
|
||||
{
|
||||
const TopoDS_Shape& anEdge = eexp.Current();
|
||||
mapEdges.Add(anEdge);
|
||||
}
|
||||
|
||||
// Allocate arrays of entities
|
||||
if (myNNodes && myNTriangles) {
|
||||
mypNodes = static_cast<Standard_ShortReal*>
|
||||
mypNodes = static_cast<Standard_ShortReal *>
|
||||
(myAlloc->Allocate(sizeof(Standard_ShortReal) * 3 * myNNodes));
|
||||
mypNormals = static_cast<Standard_ShortReal *>
|
||||
(myAlloc->Allocate(sizeof(Standard_ShortReal) * 3 * myNNodes));
|
||||
mypTriangles = static_cast<Standard_Integer*>
|
||||
mypTriangles = static_cast<Standard_Integer *>
|
||||
(myAlloc->Allocate(sizeof(Standard_Integer) * 3 * myNTriangles));
|
||||
mypEdges = static_cast<Standard_Integer **>
|
||||
(myAlloc->Allocate(sizeof(Standard_Integer *) * mapEdges.Extent()));
|
||||
myNEdges = 0;
|
||||
|
||||
// The second loop: copy all nodes and triangles face-by-face
|
||||
const Standard_Real eps2 = Precision::Confusion()*Precision::Confusion();
|
||||
@ -158,8 +216,7 @@ NIS_Surface::NIS_Surface
|
||||
const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(aFace, aLocSurf);
|
||||
const Handle(Poly_Triangulation)& aTriangulation =
|
||||
BRep_Tool::Triangulation(aFace, aLoc);
|
||||
if (aTriangulation.IsNull() == Standard_False &&
|
||||
aSurf.IsNull() == Standard_False)
|
||||
if (aTriangulation.IsNull() == Standard_False)
|
||||
{
|
||||
// Prepare transformation
|
||||
Standard_Integer i, aNodeInd(nNodes)/*, aNTriangles = 0*/;
|
||||
@ -181,10 +238,20 @@ NIS_Surface::NIS_Surface
|
||||
|
||||
gp_Vec aD1U, aD1V;
|
||||
gp_Pnt aP;
|
||||
gp_XYZ aNorm(0., 0., 0.);
|
||||
|
||||
if (aTriangulation->HasNormals()) {
|
||||
// Retrieve the normal direction from the triangulation
|
||||
aNorm.SetCoord(aTriangulation->Normals().Value(3*i-2),
|
||||
aTriangulation->Normals().Value(3*i-1),
|
||||
aTriangulation->Normals().Value(3*i-0));
|
||||
} else if (aSurf.IsNull() == Standard_False)
|
||||
{
|
||||
// Compute the surface normal at the Node.
|
||||
aSurf->D1(tabUV(i).X(), tabUV(i).Y(), aP, aD1U, aD1V);
|
||||
aNorm = (aD1U.Crossed(aD1V)).XYZ();
|
||||
}
|
||||
|
||||
// Compute the surface normal at the Node.
|
||||
aSurf->D1(tabUV(i).X(), tabUV(i).Y(), aP, aD1U, aD1V);
|
||||
gp_XYZ aNorm = (aD1U.Crossed(aD1V)).XYZ();
|
||||
if (isReverse)
|
||||
aNorm.Reverse();
|
||||
const Standard_Real aMod = aNorm.SquareModulus();
|
||||
@ -203,29 +270,73 @@ NIS_Surface::NIS_Surface
|
||||
|
||||
aNodeInd++;
|
||||
}
|
||||
const Standard_Integer nNodes1 = nNodes - 1;
|
||||
// Store all triangles of the current face in the data model
|
||||
const Poly_Array1OfTriangle& tabTri = aTriangulation->Triangles();
|
||||
for (i = tabTri.Lower(); i <= tabTri.Upper(); i++)
|
||||
{
|
||||
Standard_Integer aN[3];
|
||||
tabTri(i).Get (aN[0], aN[1], aN[2]);
|
||||
if (((tabNode(aN[2]).XYZ() -
|
||||
tabNode(aN[0]).XYZ()) ^
|
||||
(tabNode(aN[1]).XYZ() -
|
||||
tabNode(aN[0]).XYZ())).SquareModulus() > eps2)
|
||||
{
|
||||
aN[0] += (nNodes - 1);
|
||||
aN[1] += (nNodes - 1);
|
||||
aN[2] += (nNodes - 1);
|
||||
mypTriangles[nTriangles*3 + 0] = aN[0];
|
||||
if (isReverse) {
|
||||
mypTriangles[nTriangles*3 + 1] = aN[2];
|
||||
mypTriangles[nTriangles*3 + 2] = aN[1];
|
||||
} else {
|
||||
mypTriangles[nTriangles*3 + 1] = aN[1];
|
||||
mypTriangles[nTriangles*3 + 2] = aN[2];
|
||||
}
|
||||
Standard_Integer * pTriangle = &mypTriangles[nTriangles*3];
|
||||
pTriangle[0] = aN[0] + nNodes1;
|
||||
if (isReverse) {
|
||||
pTriangle[1] = aN[2] + nNodes1;
|
||||
pTriangle[2] = aN[1] + nNodes1;
|
||||
} else {
|
||||
pTriangle[1] = aN[1] + nNodes1;
|
||||
pTriangle[2] = aN[2] + nNodes1;
|
||||
}
|
||||
const Standard_ShortReal aVec0[3] = {
|
||||
mypNodes[3*pTriangle[1]+0] - mypNodes[3*pTriangle[0]+0],
|
||||
mypNodes[3*pTriangle[1]+1] - mypNodes[3*pTriangle[0]+1],
|
||||
mypNodes[3*pTriangle[1]+2] - mypNodes[3*pTriangle[0]+2]
|
||||
};
|
||||
const Standard_ShortReal aVec1[3] = {
|
||||
mypNodes[3*pTriangle[2]+0] - mypNodes[3*pTriangle[0]+0],
|
||||
mypNodes[3*pTriangle[2]+1] - mypNodes[3*pTriangle[0]+1],
|
||||
mypNodes[3*pTriangle[2]+2] - mypNodes[3*pTriangle[0]+2]
|
||||
};
|
||||
const Standard_ShortReal aVecP[3] = {
|
||||
aVec0[1] * aVec1[2] - aVec0[2] * aVec1[1],
|
||||
aVec0[2] * aVec1[0] - aVec0[0] * aVec1[2],
|
||||
aVec0[0] * aVec1[1] - aVec0[1] * aVec1[0]
|
||||
};
|
||||
if (aVecP[0]*aVecP[0] + aVecP[1]*aVecP[1] + aVecP[2]*aVecP[2] > eps2)
|
||||
nTriangles++;
|
||||
}
|
||||
// Store all edge polygons on the current face.
|
||||
for (eexp.Init(aFace, TopAbs_EDGE); eexp.More(); eexp.Next())
|
||||
{
|
||||
const TopoDS_Edge& anEdge = TopoDS::Edge(eexp.Current());
|
||||
if (mapEdges.Remove(anEdge)) {
|
||||
const Handle(Poly_PolygonOnTriangulation)& aPolygon =
|
||||
BRep_Tool::PolygonOnTriangulation(anEdge, aTriangulation, aLoc);
|
||||
if (aPolygon.IsNull() == Standard_False) {
|
||||
const TColStd_Array1OfInteger& arrNode = aPolygon->Nodes();
|
||||
// Allocate memory to store the current polygon indices.
|
||||
Standard_Integer aLen = arrNode.Length();
|
||||
Standard_Integer * pEdge = static_cast<Standard_Integer *>
|
||||
(myAlloc->Allocate(sizeof(Standard_Integer) * (aLen + 1)));
|
||||
const gp_Pnt* pLast = &tabNode(arrNode(arrNode.Lower()));
|
||||
pEdge[1] = arrNode(arrNode.Lower()) + nNodes1;
|
||||
Standard_Integer iPNode(arrNode.Lower() + 1), iENode(1);
|
||||
for (; iPNode <= arrNode.Upper(); iPNode++)
|
||||
{
|
||||
const Standard_Integer aN(arrNode(iPNode));
|
||||
if (pLast->SquareDistance(tabNode(aN)) < eps2)
|
||||
{
|
||||
aLen--;
|
||||
} else {
|
||||
pLast = &tabNode(aN);
|
||||
pEdge[++iENode] = aN + nNodes1;
|
||||
}
|
||||
}
|
||||
// Do not save very short polygons
|
||||
if (aLen > 1) {
|
||||
pEdge[0] = aLen;
|
||||
mypEdges[myNEdges++] = pEdge;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nNodes += tabNode.Length();
|
||||
@ -233,6 +344,11 @@ NIS_Surface::NIS_Surface
|
||||
}
|
||||
myNTriangles = nTriangles;
|
||||
}
|
||||
if (GetDrawer().IsNull() == Standard_False)
|
||||
{
|
||||
setDrawerUpdate();
|
||||
}
|
||||
setIsUpdateBox(Standard_True);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@ -241,6 +357,16 @@ NIS_Surface::NIS_Surface
|
||||
//=======================================================================
|
||||
|
||||
NIS_Surface::~NIS_Surface ()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Clear
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void NIS_Surface::Clear ()
|
||||
{
|
||||
if (myNNodes) {
|
||||
myNNodes = 0;
|
||||
@ -251,6 +377,20 @@ NIS_Surface::~NIS_Surface ()
|
||||
myNTriangles = 0;
|
||||
myAlloc->Free(mypTriangles);
|
||||
}
|
||||
if (mypEdges) {
|
||||
for (Standard_Integer i = 0; i < myNEdges; i++) {
|
||||
myAlloc->Free(mypEdges[i]);
|
||||
}
|
||||
myNEdges = 0;
|
||||
myAlloc->Free(mypEdges);
|
||||
}
|
||||
if (GetDrawer().IsNull() == Standard_False) {
|
||||
GetDrawer()->SetUpdated(NIS_Drawer::Draw_Normal,
|
||||
NIS_Drawer::Draw_Top,
|
||||
NIS_Drawer::Draw_Transparent,
|
||||
NIS_Drawer::Draw_Hilighted);
|
||||
}
|
||||
myBox.Clear();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@ -258,9 +398,14 @@ NIS_Surface::~NIS_Surface ()
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Handle(NIS_Drawer) NIS_Surface::DefaultDrawer () const
|
||||
NIS_Drawer * NIS_Surface::DefaultDrawer (NIS_Drawer * theDrawer) const
|
||||
{
|
||||
return defaultDrawer();
|
||||
NIS_SurfaceDrawer * aDrawer =
|
||||
theDrawer ? static_cast<NIS_SurfaceDrawer *>(theDrawer)
|
||||
: new NIS_SurfaceDrawer (Quantity_NOC_SLATEBLUE4);
|
||||
aDrawer->SetBackColor (Quantity_NOC_DARKGREEN);
|
||||
aDrawer->myIsWireframe = myIsWireframe;
|
||||
return aDrawer;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@ -270,9 +415,11 @@ Handle(NIS_Drawer) NIS_Surface::DefaultDrawer () const
|
||||
|
||||
void NIS_Surface::SetColor (const Quantity_Color& theColor)
|
||||
{
|
||||
Handle(NIS_SurfaceDrawer) aDrawer = defaultDrawer();
|
||||
const Handle(NIS_SurfaceDrawer) aDrawer =
|
||||
static_cast<NIS_SurfaceDrawer *>(DefaultDrawer(0L));
|
||||
aDrawer->Assign (GetDrawer());
|
||||
aDrawer->myColor[NIS_Drawer::Draw_Normal] = theColor;
|
||||
aDrawer->myColor[NIS_Drawer::Draw_Top] = theColor;
|
||||
aDrawer->myColor[NIS_Drawer::Draw_Transparent] = theColor;
|
||||
SetDrawer (aDrawer);
|
||||
}
|
||||
@ -284,7 +431,8 @@ void NIS_Surface::SetColor (const Quantity_Color& theColor)
|
||||
|
||||
void NIS_Surface::SetBackColor (const Quantity_Color& theColor)
|
||||
{
|
||||
Handle(NIS_SurfaceDrawer) aDrawer = defaultDrawer();
|
||||
const Handle(NIS_SurfaceDrawer) aDrawer =
|
||||
static_cast<NIS_SurfaceDrawer *>(DefaultDrawer(0L));
|
||||
aDrawer->Assign (GetDrawer());
|
||||
aDrawer->myBackColor = theColor;
|
||||
SetDrawer (aDrawer);
|
||||
@ -297,23 +445,96 @@ void NIS_Surface::SetBackColor (const Quantity_Color& theColor)
|
||||
|
||||
void NIS_Surface::SetPolygonOffset (const Standard_Real theValue)
|
||||
{
|
||||
Handle(NIS_SurfaceDrawer) aDrawer = defaultDrawer();
|
||||
const Handle(NIS_SurfaceDrawer) aDrawer =
|
||||
static_cast<NIS_SurfaceDrawer *>(DefaultDrawer(0L));
|
||||
aDrawer->Assign (GetDrawer());
|
||||
aDrawer->myPolygonOffset = theValue;
|
||||
aDrawer->myPolygonOffset = static_cast<Standard_ShortReal>(theValue);
|
||||
SetDrawer (aDrawer);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetTransparency
|
||||
//function : SetDisplayMode
|
||||
//purpose : Set the display mode: Shading or Wireframe.
|
||||
//=======================================================================
|
||||
|
||||
void NIS_Surface::SetDisplayMode (const NIS_Surface::DisplayMode theMode)
|
||||
{
|
||||
Standard_Boolean isUpdate(Standard_False);
|
||||
if (myIsWireframe) {
|
||||
if (theMode != Wireframe) {
|
||||
myIsWireframe = Standard_False;
|
||||
isUpdate = Standard_True;
|
||||
}
|
||||
} else {
|
||||
if (theMode == Wireframe) {
|
||||
myIsWireframe = Standard_True;
|
||||
isUpdate = Standard_True;
|
||||
}
|
||||
}
|
||||
if (isUpdate && GetDrawer()) {
|
||||
const Handle(NIS_SurfaceDrawer) aDrawer =
|
||||
static_cast<NIS_SurfaceDrawer *>(DefaultDrawer(0L));
|
||||
aDrawer->Assign (GetDrawer());
|
||||
aDrawer->myIsWireframe = myIsWireframe;
|
||||
SetDrawer(aDrawer);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : GetDisplayMode
|
||||
//purpose : Query the current display mode: Shading or Wireframe.
|
||||
//=======================================================================
|
||||
|
||||
NIS_Surface::DisplayMode NIS_Surface::GetDisplayMode () const
|
||||
{
|
||||
return myIsWireframe ? Wireframe : Shading;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Clone
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void NIS_Surface::SetTransparency (const Standard_Real theValue)
|
||||
void NIS_Surface::Clone (const Handle_NCollection_BaseAllocator& theAlloc,
|
||||
Handle_NIS_InteractiveObject& theDest) const
|
||||
{
|
||||
Handle(NIS_SurfaceDrawer) aDrawer = defaultDrawer();
|
||||
aDrawer->Assign (GetDrawer());
|
||||
aDrawer->myTransparency = theValue;
|
||||
SetDrawer (aDrawer);
|
||||
Handle(NIS_Surface) aNewObj;
|
||||
if (theDest.IsNull()) {
|
||||
aNewObj = new NIS_Surface(theAlloc);
|
||||
theDest = aNewObj;
|
||||
} else {
|
||||
aNewObj = reinterpret_cast<NIS_Surface*> (theDest.operator->());
|
||||
aNewObj->myAlloc = theAlloc;
|
||||
}
|
||||
NIS_InteractiveObject::Clone(theAlloc, theDest);
|
||||
aNewObj->myNNodes = myNNodes;
|
||||
if (myNNodes > 0) {
|
||||
// copy nodes and normals
|
||||
const Standard_Size nBytes = myNNodes*3*sizeof(Standard_ShortReal);
|
||||
aNewObj->mypNodes = (Standard_ShortReal *)theAlloc->Allocate(nBytes);
|
||||
aNewObj->mypNormals = (Standard_ShortReal *)theAlloc->Allocate(nBytes);
|
||||
memcpy(aNewObj->mypNodes, mypNodes, nBytes);
|
||||
memcpy(aNewObj->mypNormals, mypNormals, nBytes);
|
||||
}
|
||||
aNewObj->myNTriangles = myNTriangles;
|
||||
if (myNTriangles > 0) {
|
||||
const Standard_Size nBytes = sizeof(Standard_Integer) * 3 * myNTriangles;
|
||||
aNewObj->mypTriangles = (Standard_Integer *)theAlloc->Allocate(nBytes);
|
||||
memcpy(aNewObj->mypTriangles, mypTriangles, nBytes);
|
||||
}
|
||||
aNewObj->myNEdges = myNEdges;
|
||||
if (myNEdges > 0) {
|
||||
aNewObj->mypEdges = static_cast<Standard_Integer **>
|
||||
(theAlloc->Allocate(sizeof(Standard_Integer *) * myNEdges));
|
||||
for (Standard_Integer i = 0; i < myNEdges; i++) {
|
||||
const Standard_Integer * pEdge = mypEdges[i];
|
||||
const Standard_Size nBytes = sizeof(Standard_Integer) * (pEdge[0] + 1);
|
||||
aNewObj->mypEdges[i] =
|
||||
static_cast<Standard_Integer *> (theAlloc->Allocate(nBytes));
|
||||
memcpy(aNewObj->mypEdges[i], pEdge, nBytes);
|
||||
}
|
||||
}
|
||||
aNewObj->myIsWireframe = myIsWireframe;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@ -322,7 +543,7 @@ void NIS_Surface::SetTransparency (const Standard_Real theValue)
|
||||
//=======================================================================
|
||||
|
||||
Standard_Real NIS_Surface::Intersect (const gp_Ax1& theAxis,
|
||||
const Standard_Real /*over*/) const
|
||||
const Standard_Real theOver) const
|
||||
{
|
||||
Standard_Real aResult (RealLast());
|
||||
Standard_Real start[3], dir[3];
|
||||
@ -330,15 +551,34 @@ Standard_Real NIS_Surface::Intersect (const gp_Ax1& theAxis,
|
||||
theAxis.Direction().Coord(dir[0], dir[1], dir[2]);
|
||||
double anInter;
|
||||
|
||||
for (Standard_Integer i = 0; i < myNTriangles; i++) {
|
||||
const Standard_Integer * pTri = &mypTriangles[3*i];
|
||||
if (NIS_Triangulated::tri_line_intersect (start, dir,
|
||||
&mypNodes[3*pTri[0]],
|
||||
&mypNodes[3*pTri[1]],
|
||||
&mypNodes[3*pTri[2]],
|
||||
&anInter))
|
||||
if (anInter < aResult)
|
||||
aResult = anInter;
|
||||
if (myIsWireframe == Standard_False)
|
||||
for (Standard_Integer i = 0; i < myNTriangles; i++) {
|
||||
const Standard_Integer * pTri = &mypTriangles[3*i];
|
||||
if (NIS_Triangulated::tri_line_intersect (start, dir,
|
||||
&mypNodes[3*pTri[0]],
|
||||
&mypNodes[3*pTri[1]],
|
||||
&mypNodes[3*pTri[2]],
|
||||
&anInter))
|
||||
if (anInter < aResult)
|
||||
aResult = anInter;
|
||||
}
|
||||
else {
|
||||
const Standard_Real anOver2 = theOver*theOver;
|
||||
for (Standard_Integer iEdge = 0; iEdge < myNEdges; iEdge++) {
|
||||
const Standard_Integer * anEdge = mypEdges[iEdge];
|
||||
const Standard_Integer nNodes = anEdge[0];
|
||||
for (Standard_Integer i = 1; i < nNodes; i++) {
|
||||
// Node index is incremented for the head of polygon indice array
|
||||
if (NIS_Triangulated::seg_line_intersect (theAxis.Location().XYZ(),
|
||||
theAxis.Direction().XYZ(),
|
||||
anOver2,
|
||||
&mypNodes[3*anEdge[i+0]],
|
||||
&mypNodes[3*anEdge[i+1]],
|
||||
&anInter))
|
||||
if (anInter < aResult)
|
||||
aResult = anInter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return aResult;
|
||||
@ -349,22 +589,121 @@ Standard_Real NIS_Surface::Intersect (const gp_Ax1& theAxis,
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean NIS_Surface::Intersect
|
||||
(const Bnd_B3f& theBox,
|
||||
Standard_Boolean NIS_Surface::Intersect (const Bnd_B3f& theBox,
|
||||
const gp_Trsf& theTrf,
|
||||
const Standard_Boolean isFullIn) const
|
||||
{
|
||||
Standard_Boolean aResult (isFullIn);
|
||||
|
||||
if (myNTriangles > 0) {
|
||||
for (Standard_Integer iNode = 0; iNode < myNNodes*3; iNode+=3) {
|
||||
gp_XYZ aPnt (static_cast<Standard_Real>(mypNodes[iNode+0]),
|
||||
static_cast<Standard_Real>(mypNodes[iNode+1]),
|
||||
static_cast<Standard_Real>(mypNodes[iNode+2]));
|
||||
theTrf.Transforms(aPnt);
|
||||
if (theBox.IsOut (aPnt) == isFullIn) {
|
||||
aResult = !isFullIn;
|
||||
break;
|
||||
if (myIsWireframe == Standard_False) {
|
||||
if (myNTriangles > 0) {
|
||||
for (Standard_Integer iNode = 0; iNode < myNNodes*3; iNode+=3) {
|
||||
gp_XYZ aPnt (static_cast<Standard_Real>(mypNodes[iNode+0]),
|
||||
static_cast<Standard_Real>(mypNodes[iNode+1]),
|
||||
static_cast<Standard_Real>(mypNodes[iNode+2]));
|
||||
theTrf.Transforms(aPnt);
|
||||
if (theBox.IsOut (aPnt) == isFullIn) {
|
||||
aResult = !isFullIn;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Standard_Integer iEdge = 0; iEdge < myNEdges; iEdge++) {
|
||||
const Standard_Integer * anEdge = mypEdges[iEdge];
|
||||
const Standard_Integer nNodes = anEdge[0];
|
||||
for (Standard_Integer i = 1; i < nNodes; i++) {
|
||||
// index is incremented by 1 for the head number in the array
|
||||
gp_Pnt aPnt[2] = {
|
||||
gp_Pnt(static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+0]),
|
||||
static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+1]),
|
||||
static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+2])),
|
||||
gp_Pnt(static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+0]),
|
||||
static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+1]),
|
||||
static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+2]))
|
||||
};
|
||||
aPnt[0].Transform(theTrf);
|
||||
aPnt[1].Transform(theTrf);
|
||||
if (isFullIn) {
|
||||
if (NIS_Triangulated::seg_box_included (theBox, aPnt) == 0) {
|
||||
aResult = Standard_False;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (NIS_Triangulated::seg_box_intersect (theBox, aPnt)) {
|
||||
aResult = Standard_True;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return aResult;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Intersect
|
||||
//purpose : Selection by polygon
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean NIS_Surface::Intersect
|
||||
(const NCollection_List<gp_XY> &thePolygon,
|
||||
const gp_Trsf &theTrf,
|
||||
const Standard_Boolean isFullIn) const
|
||||
{
|
||||
Standard_Boolean aResult (isFullIn);
|
||||
|
||||
if (myIsWireframe == Standard_False) {
|
||||
if (myNTriangles > 0) {
|
||||
for (Standard_Integer iNode = 0; iNode < myNNodes*3; iNode+=3) {
|
||||
gp_XYZ aPnt (static_cast<Standard_Real>(mypNodes[iNode+0]),
|
||||
static_cast<Standard_Real>(mypNodes[iNode+1]),
|
||||
static_cast<Standard_Real>(mypNodes[iNode+2]));
|
||||
theTrf.Transforms(aPnt);
|
||||
gp_XY aP2d(aPnt.X(), aPnt.Y());
|
||||
|
||||
if (!NIS_Triangulated::IsIn(thePolygon, aP2d)) {
|
||||
if (isFullIn) {
|
||||
aResult = Standard_False;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (isFullIn == Standard_False) {
|
||||
aResult = Standard_True;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Standard_Integer iEdge = 0; iEdge < myNEdges; iEdge++) {
|
||||
const Standard_Integer * anEdge = mypEdges[iEdge];
|
||||
const Standard_Integer nNodes = anEdge[0];
|
||||
for (Standard_Integer i = 1; i < nNodes; i++) {
|
||||
// index is incremented by 1 for the head number in the array
|
||||
gp_Pnt aPnt[2] = {
|
||||
gp_Pnt(static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+0]),
|
||||
static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+1]),
|
||||
static_cast<Standard_Real>(mypNodes[3*anEdge[i+0]+2])),
|
||||
gp_Pnt(static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+0]),
|
||||
static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+1]),
|
||||
static_cast<Standard_Real>(mypNodes[3*anEdge[i+1]+2]))
|
||||
};
|
||||
aPnt[0].Transform(theTrf);
|
||||
aPnt[1].Transform(theTrf);
|
||||
const gp_XY aP2d[2] = { gp_XY(aPnt[0].X(), aPnt[0].Y()),
|
||||
gp_XY(aPnt[1].X(), aPnt[1].Y()) };
|
||||
if (isFullIn) {
|
||||
if (NIS_Triangulated::seg_polygon_included (thePolygon, aP2d) == 0) {
|
||||
aResult = Standard_False;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (NIS_Triangulated::seg_polygon_intersect (thePolygon, aP2d)) {
|
||||
aResult = Standard_True;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -378,7 +717,7 @@ Standard_Boolean NIS_Surface::Intersect
|
||||
|
||||
void NIS_Surface::computeBox ()
|
||||
{
|
||||
NIS_Triangulated::ComputeBox(myBox, myNNodes, mypNodes);
|
||||
NIS_Triangulated::ComputeBox(myBox, myNNodes, mypNodes, 3);
|
||||
|
||||
const Handle(NIS_SurfaceDrawer)& aDrawer =
|
||||
static_cast<const Handle(NIS_SurfaceDrawer)&> (GetDrawer());
|
||||
|
@ -15,35 +15,66 @@ class Handle_Poly_Triangulation;
|
||||
class TopoDS_Shape;
|
||||
|
||||
/**
|
||||
* This class describes a presentation of a meshed surface.
|
||||
* Presentation of a meshed surface.
|
||||
* Consists of 4 arrays: Nodes, Triangles, Normals and Edges. Normals are
|
||||
* defined in nodes, so the number of stored normals is strictly the number of
|
||||
* nodes. Edges is an array of pointers: each pointer starts an array of
|
||||
* node indices that define a single edge (i.e., a polygon that can be closed or
|
||||
* open, no matter). The first number in the edge is the number of nodes in it.
|
||||
* <p>
|
||||
* Instances of this class can be initialized either atomically (setting every
|
||||
* node and triangle and edge) or from a TopoDS_Shape object. In side the
|
||||
* TopoDS_Shape only triangulations in faces are used; edges are taken from
|
||||
* PolygonOnTriangulation also belonging to faces.
|
||||
* <p>
|
||||
* This class is conceived as replacement of AIS_Shape; both wireframe and
|
||||
* shading modes are available for dynamic switching.
|
||||
*/
|
||||
|
||||
class NIS_Surface : public NIS_InteractiveObject
|
||||
{
|
||||
public:
|
||||
enum DisplayMode {
|
||||
Shading,
|
||||
Wireframe
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Standard_EXPORT NIS_Surface(const Handle_Poly_Triangulation& theTri,
|
||||
const Handle_NCollection_BaseAllocator&
|
||||
const Handle_NCollection_BaseAllocator&
|
||||
theAlloc =0L);
|
||||
/**
|
||||
* Constructor. Creates the presentation of all faces in 'theShape' object.
|
||||
* @aparm theShape
|
||||
* @param theShape
|
||||
* Source geometry. It should contain triangulations inside.
|
||||
* @param theAlloc
|
||||
* @param theDeflection
|
||||
* Absolute deflection for meshing 'theShape' if such meshing is needed.
|
||||
* @param theAl
|
||||
* Allocator used for nodes and triangles in this presentation.
|
||||
*/
|
||||
Standard_EXPORT NIS_Surface(const TopoDS_Shape& theShape,
|
||||
// const Standard_Real theDeflection,
|
||||
const Handle_NCollection_BaseAllocator&
|
||||
theAlloc = 0L);
|
||||
const Standard_Real theDeflection,
|
||||
const Handle_NCollection_BaseAllocator& theAl=0L);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
Standard_EXPORT virtual ~NIS_Surface ();
|
||||
|
||||
/**
|
||||
* Initialize the instance with a TopoDS_Shape. Used in constructor but can
|
||||
* be called any time to redefine the geometry.
|
||||
*/
|
||||
Standard_EXPORT void Init (const TopoDS_Shape& theShape,
|
||||
const Standard_Real theDefl);
|
||||
|
||||
/**
|
||||
* Deallocate all internal data structures.
|
||||
*/
|
||||
Standard_EXPORT void Clear ();
|
||||
|
||||
/**
|
||||
* Query the number of nodes.
|
||||
*/
|
||||
@ -54,6 +85,11 @@ public:
|
||||
*/
|
||||
inline Standard_Integer NTriangles () const { return myNTriangles;}
|
||||
|
||||
/**
|
||||
* Query the number of edges for wireframe display.
|
||||
*/
|
||||
inline Standard_Integer NEdges () const { return myNEdges; }
|
||||
|
||||
/**
|
||||
* Query the node by its index.
|
||||
* @return
|
||||
@ -76,6 +112,18 @@ public:
|
||||
return &mypTriangles[theIndex * 3];
|
||||
}
|
||||
|
||||
/**
|
||||
* Access to array of integers that represents an Edge.
|
||||
* @return
|
||||
* Pointer to array where the 0th element is the number of nodes in the edge
|
||||
* and the elements starting from the 1st are node indices.
|
||||
*/
|
||||
inline const Standard_Integer*
|
||||
Edge (const Standard_Integer theIndex) const
|
||||
{
|
||||
return mypEdges[theIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the normal vector at the given triangulation node (by index)
|
||||
* @return
|
||||
@ -90,8 +138,8 @@ public:
|
||||
/**
|
||||
* Create a default drawer instance.
|
||||
*/
|
||||
Standard_EXPORT virtual Handle_NIS_Drawer
|
||||
DefaultDrawer () const;
|
||||
Standard_EXPORT virtual NIS_Drawer *
|
||||
DefaultDrawer (NIS_Drawer *) const;
|
||||
|
||||
/**
|
||||
* Set the normal color for presentation.
|
||||
@ -115,15 +163,31 @@ public:
|
||||
Standard_EXPORT void SetPolygonOffset (const Standard_Real theValue);
|
||||
|
||||
/**
|
||||
* Set the transparency factor.
|
||||
* @param theValue
|
||||
* 1.0 means full transparency, 0.0 means opaque. Valid quantities are in
|
||||
* this interval.
|
||||
* Set the display mode: Shading or Wireframe.
|
||||
* The default mode is Shading.
|
||||
*/
|
||||
Standard_EXPORT void SetTransparency (const Standard_Real theValue);
|
||||
Standard_EXPORT void SetDisplayMode (const DisplayMode theMode);
|
||||
|
||||
/**
|
||||
* Intersect the InteractiveObject geometry with a line/ray.
|
||||
* Query the current display mode: Shading or Wireframe.
|
||||
*/
|
||||
Standard_EXPORT DisplayMode
|
||||
GetDisplayMode () const;
|
||||
|
||||
/**
|
||||
* Create a copy of theObject except its ID.
|
||||
* @param theAll
|
||||
* Allocator where the Dest should store its private data.
|
||||
* @param theDest
|
||||
* <tt>[in-out]</tt> The target object where the data are copied. If
|
||||
* passed NULL then the target should be created.
|
||||
*/
|
||||
Standard_EXPORT virtual void
|
||||
Clone (const Handle_NCollection_BaseAllocator& theAll,
|
||||
Handle_NIS_InteractiveObject& theDest) const;
|
||||
|
||||
/**
|
||||
* Intersect the surface shading/wireframe geometry with a line/ray.
|
||||
* @param theAxis
|
||||
* The line or ray in 3D space.
|
||||
* @param theOver
|
||||
@ -134,11 +198,11 @@ public:
|
||||
* on the ray. May be negative.
|
||||
*/
|
||||
Standard_EXPORT virtual Standard_Real
|
||||
Intersect (const gp_Ax1& theAxis,
|
||||
Intersect (const gp_Ax1& theAxis,
|
||||
const Standard_Real theOver) const;
|
||||
|
||||
/**
|
||||
* Intersect the InteractiveObject geometry with an oriented box.
|
||||
* Intersect the surface shading/wireframe geometry with an oriented box.
|
||||
* @param theBox
|
||||
* 3D box of selection
|
||||
* @param theTrf
|
||||
@ -153,8 +217,32 @@ public:
|
||||
const gp_Trsf& theTrf,
|
||||
const Standard_Boolean isFull)const;
|
||||
|
||||
/**
|
||||
* Intersect the surface shading/wireframe geometry with a selection polygon.
|
||||
* @param thePolygon
|
||||
* the list of vertices of a free-form closed polygon without
|
||||
* self-intersections. The last point should not coincide with the first
|
||||
* point of the list. Any two neighbor points should not be confused.
|
||||
* @param theTrf
|
||||
* Position/Orientation of the polygon.
|
||||
* @param isFullIn
|
||||
* True if full inclusion is required, False - if partial.
|
||||
* @return
|
||||
* True if the InteractiveObject geometry intersects the polygon or is
|
||||
* inside it
|
||||
*/
|
||||
Standard_EXPORT virtual Standard_Boolean Intersect
|
||||
(const NCollection_List<gp_XY> &thePolygon,
|
||||
const gp_Trsf &theTrf,
|
||||
const Standard_Boolean isFullIn) const;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Allocator for method Clone().
|
||||
*/
|
||||
Standard_EXPORT NIS_Surface (const Handle_NCollection_BaseAllocator& theAl);
|
||||
|
||||
/**
|
||||
* Create a 3D bounding box of the object.
|
||||
*/
|
||||
@ -168,15 +256,20 @@ protected:
|
||||
gp_XYZ& theNormal) const;
|
||||
|
||||
private:
|
||||
Handle_NCollection_BaseAllocator myAlloc;
|
||||
//! Array of nodes in triangles
|
||||
Standard_ShortReal * mypNodes;
|
||||
//! Array of normals (TriNodes)
|
||||
Standard_ShortReal * mypNormals;
|
||||
//! Array of triangles (node indices)
|
||||
Standard_Integer * mypTriangles;
|
||||
//! Array of edges, each edge is an array of indices prefixed by N nodes
|
||||
Standard_Integer ** mypEdges;
|
||||
//! Number of nodes in triangles
|
||||
Standard_Integer myNNodes;
|
||||
Standard_Integer myNTriangles;
|
||||
Handle_NCollection_BaseAllocator myAlloc;
|
||||
Standard_Integer myNEdges;
|
||||
Standard_Boolean myIsWireframe;
|
||||
|
||||
public:
|
||||
// Declaration of CASCADE RTTI
|
||||
|
@ -13,6 +13,11 @@
|
||||
#endif
|
||||
#include <GL/gl.h>
|
||||
|
||||
static void setColor(GLenum theFace,
|
||||
Quantity_Parameter * theAmbient,
|
||||
const Standard_Real theSpecularity,
|
||||
GLint theShininess);
|
||||
|
||||
IMPLEMENT_STANDARD_HANDLE (NIS_SurfaceDrawer, NIS_Drawer)
|
||||
IMPLEMENT_STANDARD_RTTIEXT (NIS_SurfaceDrawer, NIS_Drawer)
|
||||
|
||||
@ -26,10 +31,11 @@ NIS_SurfaceDrawer::NIS_SurfaceDrawer
|
||||
const Quantity_Color &theHilight,
|
||||
const Quantity_Color &theDynHilight)
|
||||
: myBackColor (theNormal),
|
||||
myTransparency (0.0),
|
||||
myPolygonOffset (0.f)
|
||||
myPolygonOffset (0.f),
|
||||
myIsWireframe (Standard_False)
|
||||
{
|
||||
myColor[Draw_Normal] = theNormal;
|
||||
myColor[Draw_Top] = theNormal;
|
||||
myColor[Draw_Transparent] = theNormal;
|
||||
myColor[Draw_Hilighted] = theHilight;
|
||||
myColor[Draw_DynHilighted] = theDynHilight;
|
||||
@ -40,12 +46,11 @@ NIS_SurfaceDrawer::NIS_SurfaceDrawer
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void NIS_SurfaceDrawer::SetColor(const Quantity_Color &theColor,
|
||||
const Standard_Real theTransparency)
|
||||
void NIS_SurfaceDrawer::SetColor(const Quantity_Color &theColor)
|
||||
{
|
||||
myColor[Draw_Normal] = theColor;
|
||||
myColor[Draw_Top] = theColor;
|
||||
myColor[Draw_Transparent] = theColor;
|
||||
myTransparency = theTransparency;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@ -60,10 +65,13 @@ void NIS_SurfaceDrawer::Assign (const Handle_NIS_Drawer& theOther)
|
||||
const Handle(NIS_SurfaceDrawer)& anOther =
|
||||
static_cast <const Handle(NIS_SurfaceDrawer)&> (theOther);
|
||||
myColor[Draw_Normal] = anOther->myColor[Draw_Normal];
|
||||
myColor[Draw_Top] = anOther->myColor[Draw_Top];
|
||||
myColor[Draw_Transparent] = anOther->myColor[Draw_Transparent];
|
||||
myColor[Draw_Hilighted] = anOther->myColor[Draw_Hilighted];
|
||||
myColor[Draw_DynHilighted] = anOther->myColor[Draw_DynHilighted];
|
||||
myBackColor = anOther->myBackColor;
|
||||
myPolygonOffset = anOther->myPolygonOffset;
|
||||
myIsWireframe = anOther->myIsWireframe;
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,8 +96,7 @@ Standard_Boolean NIS_SurfaceDrawer::IsEqual
|
||||
.SquareDistance (myColor[Draw_DynHilighted]) < anEpsilon2 &&
|
||||
anOther->myBackColor.SquareDistance(myBackColor) < anEpsilon2 &&
|
||||
fabs(anOther->myPolygonOffset - myPolygonOffset) < 0.999 &&
|
||||
(anOther->myTransparency - myTransparency) *
|
||||
(anOther->myTransparency - myTransparency) < 0.01);
|
||||
myIsWireframe == anOther->myIsWireframe);
|
||||
if (aResult) {
|
||||
// Arbitrary point for test
|
||||
gp_XYZ aPnt[2] = {
|
||||
@ -110,7 +117,7 @@ Standard_Boolean NIS_SurfaceDrawer::IsEqual
|
||||
//=======================================================================
|
||||
|
||||
void NIS_SurfaceDrawer::redraw (const DrawType theType,
|
||||
const Handle_NIS_View& theView)
|
||||
const Handle_NIS_View& theView)
|
||||
{
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glPushMatrix();
|
||||
@ -135,84 +142,66 @@ void NIS_SurfaceDrawer::redraw (const DrawType theType,
|
||||
//=======================================================================
|
||||
|
||||
void NIS_SurfaceDrawer::BeforeDraw (const DrawType theType,
|
||||
const NIS_DrawList&)
|
||||
const NIS_DrawList&)
|
||||
{
|
||||
glEnable(GL_LIGHTING);
|
||||
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
|
||||
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
|
||||
// glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
|
||||
glEnableClientState (GL_VERTEX_ARRAY);
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
if (myIsWireframe == Standard_False) {
|
||||
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
}
|
||||
|
||||
Quantity_Parameter aValueCol[3];
|
||||
Quantity_Parameter aValueCol[4] = {0., 0., 0., 1.};
|
||||
Quantity_TypeOfColor bidTC (Quantity_TOC_RGB);
|
||||
GLfloat aLineWidth (1.f);
|
||||
GLfloat anOffset = myPolygonOffset;
|
||||
static const GLfloat gColorN[4] = {0.f, 0.f, 0.f, 1.f};
|
||||
|
||||
switch (theType) {
|
||||
case Draw_DynHilighted:
|
||||
aLineWidth = 3.f;
|
||||
myColor[theType].Values (aValueCol[0], aValueCol[1], aValueCol[2], bidTC);
|
||||
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
|
||||
glColor3d (aValueCol[0], aValueCol[1], aValueCol[2]);
|
||||
setColor(GL_FRONT_AND_BACK, &aValueCol[0], 0.1, 5);
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, &gColorN[0]);
|
||||
glLineWidth (aLineWidth);
|
||||
// glEnable(GL_POLYGON_OFFSET_LINE);
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(1.f, -(anOffset + 11.f));
|
||||
if (myIsWireframe == Standard_False)
|
||||
glPolygonOffset(1.f, -(anOffset + 11.f));
|
||||
return;
|
||||
case Draw_Hilighted:
|
||||
anOffset += 10.f;
|
||||
case Draw_Normal:
|
||||
case Draw_Top:
|
||||
case Draw_Transparent:
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(1.f, -anOffset);
|
||||
glEnableClientState (GL_NORMAL_ARRAY);
|
||||
if (myIsWireframe == Standard_False) {
|
||||
glPolygonOffset(1.f, -anOffset);
|
||||
glEnableClientState (GL_NORMAL_ARRAY);
|
||||
}
|
||||
myColor[theType].Values (aValueCol[0], aValueCol[1], aValueCol[2], bidTC);
|
||||
aValueCol[3] = 1. - myTransparency;
|
||||
if (theType == Draw_Transparent) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
// don't write triangles into depth test
|
||||
glDepthMask(GL_FALSE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
// glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
|
||||
static const GLfloat gColorN[4] = {0.f, 0.f, 0.f, 1.f};
|
||||
GLfloat gColorS[4] = {
|
||||
0.5f * static_cast<GLfloat> (1. + aValueCol[0]),
|
||||
0.5f * static_cast<GLfloat> (1. + aValueCol[1]),
|
||||
0.5f * static_cast<GLfloat> (1. + aValueCol[2]),
|
||||
1.f
|
||||
};
|
||||
// glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
|
||||
if (theType == Draw_Hilighted ||
|
||||
myBackColor.SquareDistance(myColor[Draw_Normal]) < 1.e-7)
|
||||
{
|
||||
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glColor4d (aValueCol[0], aValueCol[1], aValueCol[2], aValueCol[3]);
|
||||
// glColor3d (aValueCol[0], aValueCol[1], aValueCol[2]);
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &gColorS[0]);
|
||||
glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 10);
|
||||
setColor(GL_FRONT_AND_BACK, &aValueCol[0], 0.5, 10);
|
||||
} else {
|
||||
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glColor4d (aValueCol[0], aValueCol[1], aValueCol[2], aValueCol[3]);
|
||||
// glColor3d (aValueCol[0], aValueCol[1], aValueCol[2]);
|
||||
glMaterialfv(GL_FRONT, GL_SPECULAR, &gColorS[0]);
|
||||
setColor(GL_FRONT, &aValueCol[0], 0.4, 10);
|
||||
myBackColor.Values (aValueCol[0], aValueCol[1], aValueCol[2], bidTC);
|
||||
glColorMaterial(GL_BACK, GL_AMBIENT_AND_DIFFUSE);
|
||||
glColor3d (aValueCol[0], aValueCol[1], aValueCol[2]);
|
||||
glMateriali(GL_FRONT, GL_SHININESS, 10);
|
||||
gColorS[0] = 0.9f * static_cast<GLfloat> (aValueCol[0]) + 0.1f;
|
||||
gColorS[1] = 0.9f * static_cast<GLfloat> (aValueCol[1]) + 0.1f;
|
||||
gColorS[2] = 0.9f * static_cast<GLfloat> (aValueCol[2]) + 0.1f;
|
||||
glMaterialfv(GL_BACK, GL_SPECULAR, &gColorS[0]);
|
||||
glMateriali(GL_BACK, GL_SHININESS, 5);
|
||||
setColor(GL_BACK, &aValueCol[0], 0.8, 5);
|
||||
}
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, &gColorN[0]);
|
||||
|
||||
if (theType == Draw_Hilighted)
|
||||
glColor3d(0.9, 0.9, 0.9); // for the polygon presentation
|
||||
|
||||
glLineWidth (aLineWidth);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@ -221,25 +210,23 @@ void NIS_SurfaceDrawer::BeforeDraw (const DrawType theType,
|
||||
//=======================================================================
|
||||
|
||||
void NIS_SurfaceDrawer::AfterDraw (const DrawType theType,
|
||||
const NIS_DrawList&)
|
||||
const NIS_DrawList&)
|
||||
{
|
||||
// Reset transformation matrix.
|
||||
// glPopMatrix();
|
||||
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
switch (theType) {
|
||||
case Draw_DynHilighted:
|
||||
// glDisable(GL_POLYGON_OFFSET_LINE);
|
||||
break;
|
||||
case Draw_Transparent:
|
||||
glDisable(GL_BLEND);
|
||||
glDepthMask(GL_TRUE);
|
||||
case Draw_Hilighted:
|
||||
case Draw_Normal:
|
||||
case Draw_Transparent:
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
case Draw_Top:
|
||||
if (myIsWireframe == Standard_False)
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
default:;
|
||||
}
|
||||
if (myIsWireframe == Standard_False)
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@ -248,23 +235,64 @@ void NIS_SurfaceDrawer::AfterDraw (const DrawType theType,
|
||||
//=======================================================================
|
||||
|
||||
void NIS_SurfaceDrawer::Draw (const Handle_NIS_InteractiveObject& theObj,
|
||||
const DrawType theType,
|
||||
const NIS_DrawList&)
|
||||
const DrawType theType,
|
||||
const NIS_DrawList&)
|
||||
{
|
||||
// Assertion for the type of the drawn object
|
||||
#ifdef _DEBUG
|
||||
static const Handle(Standard_Type) ThisType = STANDARD_TYPE(NIS_Surface);
|
||||
Standard_ProgramError_Raise_if (theObj->IsKind(ThisType) == Standard_False,
|
||||
"NIS_Surface::Draw: "
|
||||
"irrelevant object type");
|
||||
"NIS_Surface::Draw: irrelevant object type");
|
||||
#endif
|
||||
const NIS_Surface * pObject =
|
||||
static_cast <const NIS_Surface *> (theObj.operator->());
|
||||
if (pObject->NTriangles())
|
||||
glVertexPointer (3, GL_FLOAT, 0, pObject->Node(0));
|
||||
|
||||
// In Highlited mode the shape must be shown as wireframe
|
||||
Standard_Boolean isWireframe(myIsWireframe);
|
||||
if (isWireframe == Standard_False && theType == Draw_DynHilighted)
|
||||
if (pObject->NEdges() > 0)
|
||||
isWireframe = Standard_True;
|
||||
|
||||
if (isWireframe)
|
||||
{
|
||||
glVertexPointer (3, GL_FLOAT, 0, pObject->Node(0));
|
||||
glNormalPointer (GL_FLOAT, 0, pObject->Normal(0));
|
||||
glDrawElements (GL_TRIANGLES, pObject->NTriangles()*3,
|
||||
GL_UNSIGNED_INT, pObject->Triangle(0));
|
||||
for (Standard_Integer i = 0; i < pObject->NEdges(); i++) {
|
||||
const GLint * pEdge = static_cast<const GLint *> (pObject->Edge(i));
|
||||
glDrawElements (GL_LINE_STRIP, pEdge[0], GL_UNSIGNED_INT, &pEdge[1]);
|
||||
}
|
||||
} else {
|
||||
if (pObject->NTriangles()) {
|
||||
if (theType != Draw_DynHilighted)
|
||||
glNormalPointer (GL_FLOAT, 0, pObject->Normal(0));
|
||||
glDrawElements (GL_TRIANGLES, pObject->NTriangles()*3,
|
||||
GL_UNSIGNED_INT, pObject->Triangle(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : setColor
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void setColor(GLenum theFace,
|
||||
Quantity_Parameter * theAmbient,
|
||||
const Standard_Real theSpecularity,
|
||||
GLint theShininess)
|
||||
{
|
||||
GLfloat aSpec = static_cast<GLfloat>(theSpecularity);
|
||||
GLfloat aValueCol[4] = {
|
||||
GLfloat(theAmbient[0]),
|
||||
GLfloat(theAmbient[1]),
|
||||
GLfloat(theAmbient[2]),
|
||||
GLfloat(theAmbient[3])
|
||||
};
|
||||
glMaterialfv(theFace, GL_AMBIENT_AND_DIFFUSE, &aValueCol[0]);
|
||||
aValueCol[0] = aSpec * (aValueCol[0] - 1.f) + 1.f;
|
||||
aValueCol[1] = aSpec * (aValueCol[1] - 1.f) + 1.f;
|
||||
aValueCol[2] = aSpec * (aValueCol[2] - 1.f) + 1.f;
|
||||
aValueCol[3] = 1.f;
|
||||
glMaterialfv(theFace, GL_SPECULAR, &aValueCol[0]);
|
||||
glMateriali(theFace, GL_SHININESS, theShininess);
|
||||
}
|
||||
|
||||
|
@ -26,15 +26,14 @@ class NIS_SurfaceDrawer : public NIS_Drawer
|
||||
*/
|
||||
Standard_EXPORT NIS_SurfaceDrawer(const Quantity_Color &theNormal,
|
||||
const Quantity_Color &theHilight
|
||||
= Quantity_NOC_GRAY80,
|
||||
= Quantity_NOC_GRAY65,
|
||||
const Quantity_Color &theDynHilight
|
||||
= Quantity_NOC_CYAN1);
|
||||
|
||||
/**
|
||||
* Sets the color and transparency of the drawer.
|
||||
* Sets the color of the drawer.
|
||||
*/
|
||||
Standard_EXPORT void SetColor (const Quantity_Color &theColor,
|
||||
const Standard_Real theTransparency);
|
||||
Standard_EXPORT void SetColor (const Quantity_Color &theColor);
|
||||
|
||||
/**
|
||||
* Define the color used for the back side of rendered triangles.
|
||||
@ -66,7 +65,7 @@ class NIS_SurfaceDrawer : public NIS_Drawer
|
||||
*/
|
||||
inline void SetPolygonOffset (const Standard_Real theOffset)
|
||||
{
|
||||
myPolygonOffset = static_cast<const Standard_ShortReal>(theOffset);
|
||||
myPolygonOffset = static_cast<Standard_ShortReal>(theOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -74,10 +73,9 @@ class NIS_SurfaceDrawer : public NIS_Drawer
|
||||
*/
|
||||
inline Standard_Real GetPolygonOffset () const
|
||||
{
|
||||
return static_cast<const Standard_Real>(myPolygonOffset);
|
||||
return static_cast<Standard_Real>(myPolygonOffset);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy the relevant information from another instance of Drawer.
|
||||
* raises exception if theOther has incompatible type (test IsKind).
|
||||
@ -115,11 +113,11 @@ class NIS_SurfaceDrawer : public NIS_Drawer
|
||||
|
||||
|
||||
private:
|
||||
Quantity_Color myColor[4];
|
||||
Quantity_Color myColor[5];
|
||||
Quantity_Color myBackColor;
|
||||
gp_Trsf myTrsf;
|
||||
Standard_Real myTransparency;
|
||||
Standard_ShortReal myPolygonOffset;
|
||||
Standard_Boolean myIsWireframe;
|
||||
|
||||
friend class NIS_Surface;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -10,29 +10,67 @@
|
||||
#include <NIS_InteractiveObject.hxx>
|
||||
#include <Quantity_Color.hxx>
|
||||
|
||||
#ifdef WNT
|
||||
// Disable the warning "operator new unmatched by delete"
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable:4291)
|
||||
#endif
|
||||
|
||||
class Handle_NIS_TriangulatedDrawer;
|
||||
class NCollection_BaseAllocator;
|
||||
class Handle_NCollection_BaseAllocator;
|
||||
class NIS_TriangulatedDrawer;
|
||||
|
||||
/**
|
||||
* Block of comments describing class NIS_Triangulated
|
||||
* Interactive object that consists of triangles, lines and polygons without
|
||||
* normals. Particularly can be used to render planar 2D shapes.
|
||||
*
|
||||
* @par 2D and 3D model
|
||||
* Vertices are stored in an array of float numbers, 2 or 3 numbers per vertex.
|
||||
* The number of dimensions is defined in the constructor, see the parameter
|
||||
* 'is2D'. When 2D is defined then for all vertices the Z coordinate is 0.
|
||||
* To display planar objects in a plane different from XOY you should subclass
|
||||
* this type together with the correponding Drawer and store the transformation
|
||||
* parameters. In Drawer subclass either in method BeforeDraw() or in method
|
||||
* Draw() you would call glTranslate() or glMultMatrix() so that all vertices
|
||||
* should be located in their proper positions.
|
||||
*
|
||||
* @par Compressed storage
|
||||
* For efficient memory utilization, indice (triangles, segments, polygons) are
|
||||
* 8-bit, 16-bit or 32-bit numbers. The width of this numeric representation is
|
||||
* chosen automatically when the total number of nodes is passed in the
|
||||
* constructor or in any Set* method. For example, if this number of nodes is
|
||||
* smaller than 256 then 8-bit representation is selected. The choice is stored
|
||||
* in 'myIndexType' data member.
|
||||
*/
|
||||
|
||||
class NIS_Triangulated : public NIS_InteractiveObject
|
||||
{
|
||||
protected:
|
||||
// Constants defining the mode (type) of presentation. They allow mixed type,
|
||||
// e.g., Triangulation+Line. Line and Segments are not mixable, their mix is
|
||||
// treated as Line only.
|
||||
/**
|
||||
* Constants defining the mode (type) of presentation. They allow mixed type,
|
||||
* e.g., Triangulation+Line. Line and Segments are not mixable, their mix is
|
||||
* treated as Line only.
|
||||
*/
|
||||
enum {
|
||||
Type_None = 0,
|
||||
Type_Loop = 1, // modifier to Line
|
||||
Type_Loop = 1, //!< modifier to Line
|
||||
Type_Line = 2,
|
||||
Type_Segments = 4,
|
||||
Type_Triangulation = 8,
|
||||
Type_Polygons = 16
|
||||
};
|
||||
|
||||
public:
|
||||
/**
|
||||
* Enumerated type of polygon rendering.
|
||||
*/
|
||||
enum PolygonType {
|
||||
Polygon_Default = 0, //!< Polygon as LINE, Triangulation as FILL
|
||||
Polygon_Line = 1, //!< Both Polygon and Triangulation as LINE
|
||||
Polygon_Fill = 2 //!< Both Polygon and Triangulation as FILL
|
||||
};
|
||||
|
||||
public:
|
||||
// ---------- PUBLIC METHODS ----------
|
||||
|
||||
@ -42,9 +80,17 @@ class NIS_Triangulated : public NIS_InteractiveObject
|
||||
* (this number may be defined later in methods Set*Prs) as well as the
|
||||
* memory allocator where the nodes, lines and triangles will be stored by
|
||||
* this instance.
|
||||
* @param nNodes
|
||||
* Total number of nodes that will be initialized for this object
|
||||
* @param is2D
|
||||
* If true then the nodes will be 2D in plane Z=0, otherwise normal 3D.
|
||||
* @param theAlloc
|
||||
* Allocator for internal data
|
||||
*/
|
||||
Standard_EXPORT NIS_Triangulated(const Standard_Integer nNodes = 0,
|
||||
const Handle_NCollection_BaseAllocator& =0L);
|
||||
const Standard_Boolean is2D = Standard_False,
|
||||
const Handle_NCollection_BaseAllocator&
|
||||
theAlloc = 0L);
|
||||
|
||||
/**
|
||||
* Define the polygonal presentration.
|
||||
@ -137,9 +183,8 @@ class NIS_Triangulated : public NIS_InteractiveObject
|
||||
/**
|
||||
* Create a default drawer instance.
|
||||
*/
|
||||
Standard_EXPORT virtual Handle_NIS_Drawer
|
||||
DefaultDrawer () const;
|
||||
|
||||
Standard_EXPORT virtual NIS_Drawer *
|
||||
DefaultDrawer (NIS_Drawer *) const;
|
||||
|
||||
/**
|
||||
* Define the coordinates of node [ind].
|
||||
@ -163,16 +208,14 @@ class NIS_Triangulated : public NIS_InteractiveObject
|
||||
|
||||
/**
|
||||
* Allocate a single polygon, should be called for each polygon following
|
||||
* the call SetPolygonsPrs().
|
||||
* the call SetPolygonsPrs(). The polygon can be filled by node indices using
|
||||
* the method SetPolygonNode().
|
||||
* @param ind
|
||||
* Index of the polygon, should be [0..Npolygons-1]
|
||||
* @param theSz
|
||||
* Number of points (segments) in the polygon.
|
||||
* @return
|
||||
* Pointer to the allocated buffer where you should store the indices
|
||||
* of all polygon nodes in order, total "theSz" integers.
|
||||
*/
|
||||
Standard_EXPORT Standard_Integer* SetPolygon (const Standard_Integer ind,
|
||||
Standard_EXPORT void SetPolygon (const Standard_Integer ind,
|
||||
const Standard_Integer theSz);
|
||||
|
||||
/**
|
||||
@ -203,48 +246,43 @@ class NIS_Triangulated : public NIS_InteractiveObject
|
||||
* Query the number of polygons.
|
||||
*/
|
||||
inline Standard_Integer NPolygons () const
|
||||
{ return myNPolygons; }
|
||||
{ return static_cast<Standard_Integer>(myNPolygons); }
|
||||
|
||||
/**
|
||||
* Query the node by its index.
|
||||
* @return
|
||||
* pointer to array of 3 Standard_ShortReal values (X,Y,Z coordinates)
|
||||
* pointer to array of 2 or 3 Standard_ShortReal values {X,Y(,Z) coord}
|
||||
*/
|
||||
inline const Standard_ShortReal * Node (const Standard_Integer ind) const
|
||||
{ return &mypNodes[ind*3]; }
|
||||
{ return &mypNodes[ind * myNodeCoord]; }
|
||||
|
||||
/**
|
||||
* Query the triangle by its index.
|
||||
* @return
|
||||
* pointer to array of 3 Standard_Integer values (nodes 0, 1, 2)
|
||||
*/
|
||||
inline const Standard_Integer * Triangle (const Standard_Integer ind) const
|
||||
{ return &mypTriangles[ind*3]; }
|
||||
|
||||
/**
|
||||
* Query the node of line or segments by index in the array of node indices.
|
||||
* This method does not make distinction of the presentation type
|
||||
* (field myType), so the correct definition of ind is to be done by the
|
||||
* caller.
|
||||
* @return
|
||||
* pointer to the Integer value representing the index of the node.
|
||||
*/
|
||||
inline const Standard_Integer * LineNode (const Standard_Integer ind) const
|
||||
{ return &mypLines[ind]; }
|
||||
|
||||
|
||||
/**
|
||||
* Query the polygon.
|
||||
* Define the node of a polygon by index.
|
||||
* @param indPoly
|
||||
* Index of the Polygon, should be less than the number of polygons that is
|
||||
* defined in SetPolygonsPrs() and can be returned by NPOlygons().
|
||||
* @param ind
|
||||
* rank of the polygon [0 .. N-1]
|
||||
* @param outInd
|
||||
* <tt>[out]</tt> array of vertex indice
|
||||
* @return
|
||||
* number of vertice in the polygon - the dimension of outInd array
|
||||
* Index of the node in the Polygon. Should be less than the parameter theSz
|
||||
* in the corresponding previous SetPolygon() call.
|
||||
* @param iNode
|
||||
* Index of the node in the given position of the Polygon.
|
||||
*/
|
||||
inline const Standard_Integer Polygon (const Standard_Integer ind,
|
||||
Standard_Integer* & outInd) const
|
||||
{ return * (outInd = mypPolygons[ind])++; }
|
||||
Standard_EXPORT void SetPolygonNode
|
||||
(const Standard_Integer indPoly,
|
||||
const Standard_Integer ind,
|
||||
const Standard_Integer iNode);
|
||||
|
||||
/**
|
||||
* Get the node with index 'ind' from the polygon number 'indPoly'.
|
||||
*/
|
||||
Standard_EXPORT Standard_Integer PolygonNode(const Standard_Integer indPoly,
|
||||
const Standard_Integer ind)const;
|
||||
|
||||
/**
|
||||
* Get the number of nodes for the polygon number 'indPoly'.
|
||||
*/
|
||||
Standard_EXPORT Standard_Integer NPolygonNodes
|
||||
(const Standard_Integer indPoly)const;
|
||||
|
||||
/**
|
||||
* Set the boolean flag defining if the polygons or the triangulation
|
||||
@ -252,24 +290,22 @@ class NIS_Triangulated : public NIS_InteractiveObject
|
||||
* Line/Segments.
|
||||
* @param isDrawPolygons
|
||||
* True defines that no triangulation is drawn, only polygons are. False
|
||||
* defines that only triangulation is draw, no polygons.
|
||||
* @param isUpdateV
|
||||
* True if all views should be updated, otherwise wait till the next update
|
||||
* defines that only triangulation is drawn, no polygons.
|
||||
*/
|
||||
Standard_EXPORT void SetDrawPolygons
|
||||
(const Standard_Boolean isDrawPolygons,
|
||||
const Standard_Boolean isUpdateViews
|
||||
= Standard_True);
|
||||
(const Standard_Boolean isDrawPolygons);
|
||||
/**
|
||||
* Set the type of polygon rendering.
|
||||
*/
|
||||
Standard_EXPORT void SetPolygonType
|
||||
(const PolygonType theType);
|
||||
|
||||
/**
|
||||
* Set the normal color for presentation.
|
||||
* @param theColor
|
||||
* New color to use for the presentation.
|
||||
* @param isUpdateV
|
||||
* True if all views should be updated, otherwise wait till the next update
|
||||
*/
|
||||
Standard_EXPORT void SetColor (const Quantity_Color& theColor,
|
||||
const Standard_Boolean isUpdateV
|
||||
= Standard_True);
|
||||
Standard_EXPORT void SetColor (const Quantity_Color& theColor);
|
||||
|
||||
/**
|
||||
* Get Normal, Transparent or Hilighted color of the presentation.
|
||||
@ -283,34 +319,34 @@ class NIS_Triangulated : public NIS_InteractiveObject
|
||||
* Set the color for hilighted presentation.
|
||||
* @param theColor
|
||||
* New color to use for the presentation.
|
||||
* @param isUpdateV
|
||||
* True if all views should be updated, otherwise wait till the next update
|
||||
*/
|
||||
Standard_EXPORT void SetHilightColor (const Quantity_Color& theColor,
|
||||
const Standard_Boolean isUpdateV
|
||||
= Standard_True);
|
||||
Standard_EXPORT void SetHilightColor (const Quantity_Color& theColor);
|
||||
|
||||
/**
|
||||
* Set the color for dynamic hilight presentation.
|
||||
* @param theColor
|
||||
* New color to use for the presentation.
|
||||
* @param isUpdateV
|
||||
* True if all views should be updated, otherwise wait till the next update
|
||||
*/
|
||||
Standard_EXPORT void SetDynHilightColor(const Quantity_Color& theColor,
|
||||
const Standard_Boolean isUpdateV
|
||||
= Standard_True);
|
||||
Standard_EXPORT void SetDynHilightColor(const Quantity_Color& theColor);
|
||||
|
||||
/**
|
||||
* Set the width of line presentations in pixels.
|
||||
* @param theWidth
|
||||
* New line width to use for the presentation.
|
||||
* @param isUpdateV
|
||||
* True if all views should be updated, otherwise wait till the next update
|
||||
*/
|
||||
Standard_EXPORT void SetLineWidth (const Standard_Real theWidth,
|
||||
const Standard_Boolean isUpdateV
|
||||
= Standard_True);
|
||||
Standard_EXPORT void SetLineWidth (const Standard_Real theWidth);
|
||||
|
||||
/**
|
||||
* Create a copy of theObject except its ID.
|
||||
* @param theAll
|
||||
* Allocator where the Dest should store its private data.
|
||||
* @param theDest
|
||||
* <tt>[in-out]</tt> The target object where the data are copied. If
|
||||
* passed NULL then the target should be created.
|
||||
*/
|
||||
Standard_EXPORT virtual void
|
||||
Clone (const Handle_NCollection_BaseAllocator& theAll,
|
||||
Handle_NIS_InteractiveObject& theDest) const;
|
||||
|
||||
/**
|
||||
* Intersect the InteractiveObject geometry with a line/ray.
|
||||
@ -323,7 +359,7 @@ class NIS_Triangulated : public NIS_InteractiveObject
|
||||
* detected. Otherwise returns the coordinate of thePnt on the ray. May be
|
||||
* negative.
|
||||
*/
|
||||
Standard_EXPORT Standard_Real
|
||||
Standard_EXPORT virtual Standard_Real
|
||||
Intersect (const gp_Ax1& theAxis,
|
||||
const Standard_Real theOver) const;
|
||||
|
||||
@ -343,19 +379,52 @@ class NIS_Triangulated : public NIS_InteractiveObject
|
||||
const gp_Trsf& theTrf,
|
||||
const Standard_Boolean isFull)const;
|
||||
|
||||
Standard_EXPORT static int tri_line_intersect (const double start[3],
|
||||
const double dir[3],
|
||||
const float V0[3],
|
||||
const float V1[3],
|
||||
const float V2[3],
|
||||
double * tInter);
|
||||
/**
|
||||
* Intersect the InteractiveObject geometry with a selection polygon.
|
||||
* @param thePolygon
|
||||
* the list of vertices of a free-form closed polygon without
|
||||
* self-intersections. The last point should not coincide with the first
|
||||
* point of the list. Any two neighbor points should not be confused.
|
||||
* @param theTrf
|
||||
* Position/Orientation of the polygon.
|
||||
* @param isFullIn
|
||||
* True if full inclusion is required, False - if partial.
|
||||
* @return
|
||||
* True if the InteractiveObject geometry intersects the polygon or is
|
||||
* inside it
|
||||
*/
|
||||
Standard_EXPORT virtual Standard_Boolean Intersect
|
||||
(const NCollection_List<gp_XY> &thePolygon,
|
||||
const gp_Trsf &theTrf,
|
||||
const Standard_Boolean isFullIn) const;
|
||||
|
||||
Standard_EXPORT static int seg_line_intersect (const gp_XYZ& aStart,
|
||||
const gp_XYZ& aDir,
|
||||
const double over2,
|
||||
const float V0[3],
|
||||
const float V1[3],
|
||||
double * tInter);
|
||||
Standard_EXPORT static int tri_line_intersect (const double start[3],
|
||||
const double dir[3],
|
||||
const float V0[3],
|
||||
const float V1[3],
|
||||
const float V2[3],
|
||||
double * tInter);
|
||||
|
||||
Standard_EXPORT static int tri2d_line_intersect(const double start[3],
|
||||
const double dir[3],
|
||||
const float V0[2],
|
||||
const float V1[2],
|
||||
const float V2[2],
|
||||
double * tInter);
|
||||
|
||||
Standard_EXPORT static int seg_line_intersect (const gp_XYZ& aStart,
|
||||
const gp_XYZ& aDir,
|
||||
const double over2,
|
||||
const float V0[3],
|
||||
const float V1[3],
|
||||
double * tInter);
|
||||
|
||||
Standard_EXPORT static int seg2d_line_intersect(const gp_XYZ& aStart,
|
||||
const gp_XYZ& aDir,
|
||||
const double over2,
|
||||
const float V0[2],
|
||||
const float V1[2],
|
||||
double * tInter);
|
||||
|
||||
Standard_EXPORT static int seg_box_intersect (const Bnd_B3f& theBox,
|
||||
const gp_Pnt thePnt[2]);
|
||||
@ -363,12 +432,58 @@ class NIS_Triangulated : public NIS_InteractiveObject
|
||||
Standard_EXPORT static int seg_box_included (const Bnd_B3f& theBox,
|
||||
const gp_Pnt thePnt[2]);
|
||||
|
||||
Standard_EXPORT static int seg_polygon_intersect
|
||||
(const NCollection_List<gp_XY> &thePolygon,
|
||||
const gp_XY thePnt[2]);
|
||||
|
||||
Standard_EXPORT static int seg_polygon_included
|
||||
(const NCollection_List<gp_XY> &thePolygon,
|
||||
const gp_XY thePnt[2]);
|
||||
|
||||
Standard_EXPORT static void ComputeBox (Bnd_B3f& theBox,
|
||||
const Standard_Integer nNodes,
|
||||
const Standard_ShortReal* pNodes);
|
||||
const Standard_ShortReal* pNodes,
|
||||
const Standard_Integer nCoord);
|
||||
|
||||
/**
|
||||
* Classification of thePoint with respect to thePolygon.
|
||||
* @param thePolygon
|
||||
* the list of vertices of a free-form closed polygon without
|
||||
* self-intersections. The last point should not coincide with the first
|
||||
* point of the list. Any two neighbor points should not be confused.
|
||||
* @param thePoint
|
||||
* the point to be classified.
|
||||
* @return
|
||||
* Standard_True if thePoint in inside thePolygon or lies on its boundary.
|
||||
*/
|
||||
Standard_EXPORT static Standard_Boolean
|
||||
IsIn (const NCollection_List<gp_XY> &thePolygon,
|
||||
const gp_XY &thePoint);
|
||||
|
||||
/**
|
||||
* Implements deallocation of the object instance
|
||||
*/
|
||||
Standard_EXPORT virtual void Delete () const;
|
||||
|
||||
/**
|
||||
* Operator new for memory allocation uses Open CASCADE memory manager
|
||||
*/
|
||||
void* operator new (size_t size)
|
||||
{
|
||||
return Standard::Allocate(size);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Allocator-based operator new for dynamic allocations in method Clone()
|
||||
*/
|
||||
void* operator new (Standard_Size theSz,
|
||||
const Handle(NCollection_BaseAllocator)& theAllocator)
|
||||
{
|
||||
return theAllocator->Allocate(theSz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a 3D bounding box of the object.
|
||||
*/
|
||||
@ -380,30 +495,49 @@ class NIS_Triangulated : public NIS_InteractiveObject
|
||||
*/
|
||||
Standard_EXPORT void allocateNodes (const Standard_Integer nNodes);
|
||||
|
||||
/**
|
||||
* Get the node pointed by the i-th index in the array.
|
||||
*/
|
||||
Standard_EXPORT gp_Pnt nodeAtInd (const Standard_Integer * theArr,
|
||||
const Standard_Integer i) const;
|
||||
|
||||
/**
|
||||
* Get the node pointed by the i-th index in the array.
|
||||
*/
|
||||
Standard_EXPORT float* nodeArrAtInd (const Standard_Integer * theArr,
|
||||
const Standard_Integer i) const;
|
||||
|
||||
protected:
|
||||
// ---------- PROTECTED FIELDS ----------
|
||||
|
||||
/**
|
||||
* Combination of Type_* constants
|
||||
*/
|
||||
Standard_Integer myType;
|
||||
Standard_ShortReal * mypNodes;
|
||||
Standard_Integer * mypTriangles;
|
||||
Standard_Integer * mypLines;
|
||||
Standard_Integer ** mypPolygons;
|
||||
Standard_Integer myNNodes;
|
||||
Standard_Integer myNTriangles;
|
||||
Standard_Integer myNPolygons;
|
||||
Standard_Integer myNLineNodes;
|
||||
NCollection_BaseAllocator * myAlloc;
|
||||
Standard_Boolean myIsDrawPolygons;
|
||||
NCollection_BaseAllocator * myAlloc; //!< Usually from InteractiveContext
|
||||
Standard_Integer myType; //!< Combination of Type_* constants
|
||||
Standard_ShortReal * mypNodes;
|
||||
Standard_Integer * mypTriangles;
|
||||
Standard_Integer * mypLines;
|
||||
Standard_Integer ** mypPolygons;
|
||||
Standard_Integer myNNodes;
|
||||
Standard_Integer myNTriangles;
|
||||
Standard_Integer myNLineNodes;
|
||||
unsigned int myNPolygons : 24;
|
||||
Standard_Boolean myIsDrawPolygons : 1;
|
||||
Standard_Boolean myIsCloned : 1; //!< How it is allocated
|
||||
unsigned int myIndexType : 2; //!< 0:8bit, 1:16bit, 2:32bit
|
||||
unsigned int myNodeCoord : 2; //!< 2 or 3 coordinates
|
||||
unsigned int myPolygonType : 2;
|
||||
|
||||
public:
|
||||
// Declaration of CASCADE RTTI
|
||||
DEFINE_STANDARD_RTTI (NIS_Triangulated)
|
||||
|
||||
friend class NIS_TriangulatedDrawer;
|
||||
};
|
||||
|
||||
// Definition of HANDLE object using Standard_DefineHandle.hxx
|
||||
DEFINE_STANDARD_HANDLE (NIS_Triangulated, NIS_InteractiveObject)
|
||||
|
||||
#ifdef WNT
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -37,9 +37,12 @@ NIS_TriangulatedDrawer::NIS_TriangulatedDrawer
|
||||
const Quantity_Color theHilight,
|
||||
const Quantity_Color theDynHilight)
|
||||
: myLineWidth (1.f),
|
||||
myIsDrawPolygons (Standard_False)
|
||||
myIsDrawPolygons (Standard_False),
|
||||
myPolygonType (NIS_Triangulated::Polygon_Default),
|
||||
myPolygonAsLineLoop (Standard_False)
|
||||
{
|
||||
myColor[Draw_Normal] = theNormal;
|
||||
myColor[Draw_Top] = theNormal;
|
||||
myColor[Draw_Transparent] = theNormal;
|
||||
myColor[Draw_Hilighted] = theHilight;
|
||||
myColor[Draw_DynHilighted] = theDynHilight;
|
||||
@ -57,14 +60,18 @@ void NIS_TriangulatedDrawer::Assign (const Handle_NIS_Drawer& theOther)
|
||||
const Handle(NIS_TriangulatedDrawer)& anOther =
|
||||
static_cast <const Handle(NIS_TriangulatedDrawer)&> (theOther);
|
||||
myColor[Draw_Normal] = anOther->myColor[Draw_Normal];
|
||||
myColor[Draw_Top] = anOther->myColor[Draw_Top];
|
||||
myColor[Draw_Transparent] = anOther->myColor[Draw_Transparent];
|
||||
myColor[Draw_Hilighted] = anOther->myColor[Draw_Hilighted];
|
||||
myColor[Draw_DynHilighted] = anOther->myColor[Draw_DynHilighted];
|
||||
myLineWidth = anOther->myLineWidth;
|
||||
myIsDrawPolygons = anOther->myIsDrawPolygons;
|
||||
myPolygonType = anOther->myPolygonType;
|
||||
}
|
||||
}
|
||||
|
||||
static const Standard_Integer nObjPerDrawer = 64;
|
||||
|
||||
//=======================================================================
|
||||
//function : IsEqual
|
||||
//purpose : Comparison of two Drawers (for Map impementation)
|
||||
@ -86,7 +93,8 @@ Standard_Boolean NIS_TriangulatedDrawer::IsEqual
|
||||
.SquareDistance (myColor[Draw_DynHilighted]) < anEpsilon2 &&
|
||||
(anOther->myLineWidth - myLineWidth) *
|
||||
(anOther->myLineWidth - myLineWidth) < 0.01 &&
|
||||
anOther->myIsDrawPolygons == myIsDrawPolygons);
|
||||
anOther->myIsDrawPolygons == myIsDrawPolygons &&
|
||||
anOther->myPolygonType == myPolygonType);
|
||||
return aResult;
|
||||
}
|
||||
|
||||
@ -98,7 +106,7 @@ Standard_Boolean NIS_TriangulatedDrawer::IsEqual
|
||||
void NIS_TriangulatedDrawer::BeforeDraw (const DrawType theType,
|
||||
const NIS_DrawList&)
|
||||
{
|
||||
Quantity_Parameter aValue[3];
|
||||
Quantity_Parameter aValue[4];
|
||||
Quantity_TypeOfColor bidTC (Quantity_TOC_RGB);
|
||||
GLfloat aLineWidth (myLineWidth);
|
||||
Standard_Integer anOffsetHilighted = 0;
|
||||
@ -109,10 +117,17 @@ void NIS_TriangulatedDrawer::BeforeDraw (const DrawType theType,
|
||||
anOffsetHilighted = -11;
|
||||
#endif
|
||||
case Draw_Hilighted:
|
||||
if (myIsDrawPolygons)
|
||||
glEnable(GL_POLYGON_OFFSET_LINE);
|
||||
else
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
switch (myPolygonType) {
|
||||
default:
|
||||
case NIS_Triangulated::Polygon_Default:
|
||||
if (myIsDrawPolygons) {
|
||||
case NIS_Triangulated::Polygon_Line:
|
||||
glEnable(GL_POLYGON_OFFSET_LINE);
|
||||
} else {
|
||||
case NIS_Triangulated::Polygon_Fill:
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
}
|
||||
}
|
||||
if (theType == Draw_Hilighted)
|
||||
{
|
||||
#ifdef NEGATIVE_POFFSET
|
||||
@ -121,12 +136,22 @@ void NIS_TriangulatedDrawer::BeforeDraw (const DrawType theType,
|
||||
anOffsetHilighted = 1;
|
||||
#endif
|
||||
}
|
||||
myColor[theType].Values (aValue[0], aValue[1], aValue[2], bidTC);
|
||||
glColor3d (aValue[0], aValue[1], aValue[2]);
|
||||
break;
|
||||
case Draw_Normal:
|
||||
case Draw_Top:
|
||||
case Draw_Transparent:
|
||||
#ifndef NEGATIVE_POFFSET
|
||||
anOffsetHilighted = 11;
|
||||
#endif
|
||||
myColor[theType].Values (aValue[0], aValue[1], aValue[2], bidTC);
|
||||
aValue[3] = 1. - myTransparency;
|
||||
if (myTransparency > 0.01) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
glColor4d (aValue[0], aValue[1], aValue[2], aValue[3]);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
@ -134,12 +159,19 @@ void NIS_TriangulatedDrawer::BeforeDraw (const DrawType theType,
|
||||
if (anOffsetHilighted)
|
||||
glPolygonOffset(1.f, static_cast<GLfloat>(anOffsetHilighted));
|
||||
|
||||
myColor[theType].Values (aValue[0], aValue[1], aValue[2], bidTC);
|
||||
glColor3d (aValue[0], aValue[1], aValue[2]);
|
||||
if (myIsDrawPolygons)
|
||||
glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
|
||||
else
|
||||
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
|
||||
// myColor[theType].Values (aValue[0], aValue[1], aValue[2], bidTC);
|
||||
// glColor3d (aValue[0], aValue[1], aValue[2]);
|
||||
switch (myPolygonType) {
|
||||
default:
|
||||
case NIS_Triangulated::Polygon_Default:
|
||||
if (myIsDrawPolygons) {
|
||||
case NIS_Triangulated::Polygon_Line:
|
||||
glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
|
||||
} else {
|
||||
case NIS_Triangulated::Polygon_Fill:
|
||||
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
}
|
||||
glEnableClientState (GL_VERTEX_ARRAY);
|
||||
glLineWidth (aLineWidth);
|
||||
glShadeModel(GL_FLAT);
|
||||
@ -157,16 +189,27 @@ void NIS_TriangulatedDrawer::AfterDraw (const DrawType theType,
|
||||
switch (theType) {
|
||||
case Draw_Hilighted:
|
||||
case Draw_DynHilighted:
|
||||
if (myIsDrawPolygons)
|
||||
glDisable(GL_POLYGON_OFFSET_LINE);
|
||||
else
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
switch (myPolygonType) {
|
||||
default:
|
||||
case NIS_Triangulated::Polygon_Default:
|
||||
if (myIsDrawPolygons) {
|
||||
case NIS_Triangulated::Polygon_Line:
|
||||
glDisable(GL_POLYGON_OFFSET_LINE);
|
||||
} else {
|
||||
case NIS_Triangulated::Polygon_Fill:
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
}
|
||||
}
|
||||
case Draw_Normal:
|
||||
case Draw_Top:
|
||||
case Draw_Transparent:
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
if (myTransparency > 0.01)
|
||||
glDisable(GL_BLEND);
|
||||
default:;
|
||||
}
|
||||
if (myIsDrawPolygons)
|
||||
if (myPolygonType == NIS_Triangulated::Polygon_Line ||
|
||||
(myPolygonType == NIS_Triangulated::Polygon_Default && myIsDrawPolygons))
|
||||
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
|
||||
@ -188,35 +231,57 @@ void NIS_TriangulatedDrawer::Draw (const Handle_NIS_InteractiveObject& theObj,
|
||||
#endif
|
||||
const NIS_Triangulated * pObject =
|
||||
static_cast <const NIS_Triangulated *> (theObj.operator->());
|
||||
glVertexPointer (3, GL_FLOAT, 0, pObject->Node(0));
|
||||
glVertexPointer (pObject->myNodeCoord, GL_FLOAT, 0, pObject->Node(0));
|
||||
|
||||
GLenum aType = GL_UNSIGNED_INT;
|
||||
if (pObject->myIndexType == 0)
|
||||
aType = GL_UNSIGNED_BYTE;
|
||||
else if (pObject->myIndexType == 1)
|
||||
aType = GL_UNSIGNED_SHORT;
|
||||
|
||||
if (myIsDrawPolygons == Standard_False) {
|
||||
if (pObject->IsTriangulation())
|
||||
if (pObject->IsTriangulation()) {
|
||||
glDrawElements (GL_TRIANGLES, pObject->NTriangles()*3,
|
||||
GL_UNSIGNED_INT, pObject->Triangle(0));
|
||||
aType, pObject->mypTriangles);
|
||||
}
|
||||
} else {
|
||||
if (pObject->IsPolygons()) {
|
||||
GLenum aMode = GL_POLYGON;
|
||||
if (myPolygonAsLineLoop &&
|
||||
(myPolygonType == NIS_Triangulated::Polygon_Line ||
|
||||
(myPolygonType == NIS_Triangulated::Polygon_Default &&
|
||||
myIsDrawPolygons)))
|
||||
aMode = GL_LINE_LOOP;
|
||||
const Standard_Integer nPoly = pObject->NPolygons();
|
||||
for (Standard_Integer i = 0; i < nPoly; i++) {
|
||||
Standard_Integer * arrNodes;
|
||||
const Standard_Integer nSize = pObject->Polygon (i, arrNodes);
|
||||
glDrawElements (GL_LINE_LOOP, nSize, GL_UNSIGNED_INT, arrNodes);
|
||||
const Standard_Integer nSize = pObject->NPolygonNodes(i);
|
||||
void* anArray;
|
||||
if (pObject->myIndexType == 0)
|
||||
anArray = reinterpret_cast<unsigned char *>(pObject->mypPolygons[i]) + 1;
|
||||
else if (pObject->myIndexType == 1)
|
||||
anArray = reinterpret_cast<unsigned short *>(pObject->mypPolygons[i]) + 1;
|
||||
else
|
||||
anArray = pObject->mypPolygons[i] + 1;
|
||||
glDrawElements (aMode, nSize, aType, anArray);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pObject->IsSegments())
|
||||
glDrawElements (GL_LINES, pObject->NLineNodes(),
|
||||
GL_UNSIGNED_INT, pObject->LineNode(0));
|
||||
aType, pObject->mypLines);
|
||||
else {
|
||||
Standard_Boolean isLoop;
|
||||
if (pObject->IsLine(isLoop))
|
||||
if (isLoop) {
|
||||
glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
|
||||
// glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
|
||||
glDrawElements (GL_LINE_LOOP, pObject->NLineNodes(),
|
||||
GL_UNSIGNED_INT, pObject->LineNode(0));
|
||||
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
|
||||
aType, pObject->mypLines);
|
||||
// glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
|
||||
} else {
|
||||
glDrawElements (GL_LINE_STRIP, pObject->NLineNodes(),
|
||||
GL_UNSIGNED_INT, pObject->LineNode(0));
|
||||
aType, pObject->mypLines);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -60,10 +60,20 @@ class NIS_TriangulatedDrawer : public NIS_Drawer
|
||||
*/
|
||||
Standard_EXPORT virtual Standard_Boolean
|
||||
IsEqual (const Handle_NIS_Drawer& theOth)const;
|
||||
private:
|
||||
Quantity_Color myColor[4];
|
||||
|
||||
protected:
|
||||
/**
|
||||
* If myPolygonAsLineLoop is true then draw polygons of the object
|
||||
* in the mode GL_LINE_LOOP instead of GL_POLYGON in the case if no filling
|
||||
* was requested. This will eliminate the bug with Intel integrated graphic
|
||||
* cards (e.g. 945G Express) for the sake of polygon offset functionality.
|
||||
*/
|
||||
Standard_Boolean myPolygonAsLineLoop;
|
||||
|
||||
Quantity_Color myColor[5];
|
||||
Standard_ShortReal myLineWidth;
|
||||
Standard_Boolean myIsDrawPolygons;
|
||||
unsigned int myPolygonType;
|
||||
|
||||
friend class NIS_Triangulated;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,10 @@
|
||||
#include <V3d_OrthographicView.hxx>
|
||||
#include <Standard_DefineHandle.hxx>
|
||||
#include <NCollection_List.hxx>
|
||||
#include <NCollection_Vector.hxx>
|
||||
#include <Bnd_B3f.hxx>
|
||||
#include <TColStd_PackedMapOfInteger.hxx>
|
||||
#include <gp_XY.hxx>
|
||||
|
||||
class NIS_InteractiveContext;
|
||||
class gp_Ax1;
|
||||
@ -58,9 +62,49 @@ class NIS_View : public V3d_OrthographicView
|
||||
Standard_EXPORT void SetWindow(const Handle_Aspect_Window &theWindow);
|
||||
|
||||
/**
|
||||
* Zoom the view to fit to visible objects size and positions.
|
||||
* Indicate whether to draw hilighted objects on top of all other ones
|
||||
*/
|
||||
Standard_EXPORT void FitAll3d ();
|
||||
inline void SetHilightOnTop(const Standard_Boolean theTop = Standard_True)
|
||||
{ myIsTopHilight = theTop; }
|
||||
|
||||
/**
|
||||
* Indicate whether to hilight selected object dynamically
|
||||
* By default dynamic hilight works on all objects independently on its
|
||||
* selected/non-selected state.
|
||||
* This behaviour differs from the behaviour of AIS interactive context,
|
||||
* that doesn't hilight dynamically (on mouse movements) selected objects.
|
||||
* In the case both context are used in the same view the behaviour of both
|
||||
* context can be made consistent by setting this flag to False
|
||||
*/
|
||||
inline void SetDynHilightSelected (const Standard_Boolean
|
||||
theHilight = Standard_True)
|
||||
{ myDoHilightSelected = theHilight; }
|
||||
|
||||
/**
|
||||
* Zoom the view to fit to visible objects size and positions.
|
||||
* @param theCoef
|
||||
* Relative margin in both X and Y dimensions. For example, value 1.0
|
||||
* will fit to twice the actual size.
|
||||
* @return
|
||||
* True if operation performed, False if failed (most likely because of
|
||||
* very big actual scale)
|
||||
*/
|
||||
Standard_EXPORT Standard_Boolean FitAll3d (const Quantity_Coefficient theCoef
|
||||
= 0.01);
|
||||
|
||||
/**
|
||||
* Gets bounding box covering objects displayed in viewer.
|
||||
*/
|
||||
Standard_EXPORT Bnd_B3f GetBndBox() const;
|
||||
|
||||
/**
|
||||
* Gets bounding box covering objects displayed in viewer.
|
||||
* If operation is fails when Xmax < Xmin abd Ymax < Ymin
|
||||
*/
|
||||
Standard_EXPORT void GetBndBox(Standard_Integer& theXMin,
|
||||
Standard_Integer& theXMax,
|
||||
Standard_Integer& theYMin,
|
||||
Standard_Integer& theYMax ) const;
|
||||
|
||||
// /**
|
||||
// * Destructor.
|
||||
@ -80,21 +124,30 @@ class NIS_View : public V3d_OrthographicView
|
||||
*/
|
||||
Standard_EXPORT void DynamicUnhilight(const Handle_NIS_InteractiveObject&);
|
||||
|
||||
/**
|
||||
* Unhilights the currently hilighted object.
|
||||
*/
|
||||
inline void DynamicUnhilight() { DynamicUnhilight(myDynHilighted); }
|
||||
|
||||
/**
|
||||
* Set or unset the selected (hilighted) state of the object that is under
|
||||
* the coordinates theX, theY.
|
||||
* @param theX
|
||||
* X coordinate of the view window
|
||||
* @param theX
|
||||
* @param theY
|
||||
* X coordinate of the view window
|
||||
* @param isForceMult
|
||||
* True if the effect of multi-Selection should be forced (e.g., when Shift
|
||||
* is pressed).
|
||||
* @param theRedraw
|
||||
* True to redraw view automatically (default value).
|
||||
*/
|
||||
Standard_EXPORT void Select (const Standard_Integer theX,
|
||||
const Standard_Integer theY,
|
||||
const Standard_Boolean isForceMult
|
||||
= Standard_False);
|
||||
= Standard_False,
|
||||
const Standard_Boolean theRedraw
|
||||
= Standard_True);
|
||||
|
||||
/**
|
||||
* Set or unset the selected (hilighted) state of the objects that are
|
||||
@ -114,6 +167,8 @@ class NIS_View : public V3d_OrthographicView
|
||||
* True if only those objects are processed that are fully inside the
|
||||
* selection rectangle. False if objects fully or partially included in
|
||||
* the rectangle are processed.
|
||||
* @param theRedraw
|
||||
* True to redraw view automatically (default value).
|
||||
*/
|
||||
Standard_EXPORT void Select (const Standard_Integer theXmin,
|
||||
const Standard_Integer theYmin,
|
||||
@ -122,7 +177,35 @@ class NIS_View : public V3d_OrthographicView
|
||||
const Standard_Boolean isForceMult
|
||||
= Standard_False,
|
||||
const Standard_Boolean isFullyIncluded
|
||||
= Standard_False);
|
||||
= Standard_False,
|
||||
const Standard_Boolean theRedraw
|
||||
= Standard_True);
|
||||
|
||||
/**
|
||||
* Set or unset the selected (hilighted) state of the objects that are
|
||||
* intersected by 2D polygon in the view
|
||||
* @param thePolygon
|
||||
* defines the vertices of a free-form closed polygon without
|
||||
* self-intersections. The last point should not coincide with the first
|
||||
* point of the list. Points are interpreted as X and Y integer coordinates
|
||||
* of the view window. Any two neighbor points should not be confused.
|
||||
* @param isForceMult
|
||||
* True if the effect of multi-Selection should be forced (e.g., when Shift
|
||||
* is pressed).
|
||||
* @param isFullyIncluded
|
||||
* True if only those objects are processed that are fully inside the
|
||||
* selection rectangle. False if objects fully or partially included in
|
||||
* the rectangle are processed.
|
||||
* @param theRedraw
|
||||
* True to redraw view automatically (default value).
|
||||
*/
|
||||
Standard_EXPORT void Select (const NCollection_List<gp_XY> &thePolygon,
|
||||
const Standard_Boolean isForceMult
|
||||
= Standard_False,
|
||||
const Standard_Boolean isFullyIncluded
|
||||
= Standard_False,
|
||||
const Standard_Boolean theRedraw
|
||||
= Standard_True);
|
||||
|
||||
/**
|
||||
* Interactive selection by mouse click. Selection itself is performed in each
|
||||
@ -138,7 +221,7 @@ class NIS_View : public V3d_OrthographicView
|
||||
*/
|
||||
Standard_EXPORT Handle_NIS_InteractiveObject
|
||||
Pick (const Standard_Integer theX,
|
||||
const Standard_Integer theY) const;
|
||||
const Standard_Integer theY);
|
||||
|
||||
/**
|
||||
* Interactive selection by mouse click. Selection itself is performed in each
|
||||
@ -148,7 +231,7 @@ class NIS_View : public V3d_OrthographicView
|
||||
* 3D axis for objects selection
|
||||
* @param theOver
|
||||
* Overlap for the selecting axis
|
||||
* @param isOnlySelectable
|
||||
* @param isOnlySel
|
||||
* If False, any displayed object can be picked, otherwise only selectable
|
||||
* ones.
|
||||
* @return
|
||||
@ -156,9 +239,21 @@ class NIS_View : public V3d_OrthographicView
|
||||
* all contexts attached to this View.
|
||||
*/
|
||||
Standard_EXPORT Handle_NIS_InteractiveObject
|
||||
Pick (const gp_Ax1& theAxis,
|
||||
const Standard_Real theOver,
|
||||
const Standard_Boolean isOnlySelectable) const;
|
||||
Pick (const gp_Ax1& theAxis,
|
||||
const Standard_Real theOver,
|
||||
const Standard_Boolean isOnlySel);
|
||||
|
||||
/**
|
||||
* Gets all objects detected by last call of Pick() method
|
||||
*/
|
||||
inline NCollection_Vector<NIS_InteractiveObject *> GetDetected() const
|
||||
{ return myDetected; }
|
||||
|
||||
/**
|
||||
* Obtain the IDs of ex-lists.
|
||||
*/
|
||||
inline TColStd_PackedMapOfInteger& GetExListId ()
|
||||
{ return myExListId; }
|
||||
|
||||
protected:
|
||||
// ---------- PROTECTED METHODS ----------
|
||||
@ -182,6 +277,10 @@ class NIS_View : public V3d_OrthographicView
|
||||
|
||||
NCollection_List<NIS_InteractiveContext *> myContexts;
|
||||
Handle_NIS_InteractiveObject myDynHilighted;
|
||||
Standard_Boolean myIsTopHilight : 1;
|
||||
Standard_Boolean myDoHilightSelected : 1;
|
||||
NCollection_Vector<NIS_InteractiveObject *> myDetected;
|
||||
TColStd_PackedMapOfInteger myExListId;
|
||||
|
||||
friend class NIS_InteractiveContext;
|
||||
|
||||
|
@ -438,12 +438,12 @@ void ViewerTest::Clear()
|
||||
} else if (it.Key1()->IsKind(STANDARD_TYPE(NIS_InteractiveObject))) {
|
||||
const Handle(NIS_InteractiveObject) anObj =
|
||||
Handle(NIS_InteractiveObject)::DownCast (it.Key1());
|
||||
TheNISContext()->Remove(anObj,Standard_False);
|
||||
TheNISContext()->Remove(anObj);
|
||||
}
|
||||
it.Next();
|
||||
}
|
||||
TheAISContext()->UpdateCurrentViewer();
|
||||
TheNISContext()->UpdateViews();
|
||||
// TheNISContext()->UpdateViews();
|
||||
GetMapOfAIS().Clear();
|
||||
}
|
||||
}
|
||||
@ -1391,7 +1391,7 @@ static int VDonly2(Draw_Interpretor& , Standard_Integer argc, const char** argv)
|
||||
} else if (it.Key1()->IsKind(STANDARD_TYPE(NIS_InteractiveObject))) {
|
||||
const Handle(NIS_InteractiveObject) aShape =
|
||||
Handle(NIS_InteractiveObject)::DownCast(it.Key1());
|
||||
TheNISContext()->Erase(aShape,Standard_False);
|
||||
TheNISContext()->Erase(aShape);
|
||||
}
|
||||
it.Next();
|
||||
}
|
||||
@ -1407,14 +1407,14 @@ static int VDonly2(Draw_Interpretor& , Standard_Integer argc, const char** argv)
|
||||
Handle(AIS_InteractiveObject)::DownCast (anObj);
|
||||
TheAISContext()->Display(aShape, Standard_False);
|
||||
} else if (anObj->IsKind(STANDARD_TYPE(NIS_InteractiveObject))) {
|
||||
const Handle(NIS_InteractiveObject) aShape =
|
||||
Handle(NIS_InteractiveObject) aShape =
|
||||
Handle(NIS_InteractiveObject)::DownCast (anObj);
|
||||
TheNISContext()->Display(aShape, 0L, Standard_False);
|
||||
TheNISContext()->Display(aShape);
|
||||
}
|
||||
}
|
||||
}
|
||||
TheAISContext() ->UpdateCurrentViewer();
|
||||
TheNISContext() ->UpdateViews();
|
||||
// TheNISContext() ->UpdateViews();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1473,12 +1473,12 @@ static int VErase2(Draw_Interpretor& , Standard_Integer argc, const char** arg
|
||||
} else if (it.Key1()->IsKind(STANDARD_TYPE(NIS_InteractiveObject))) {
|
||||
const Handle(NIS_InteractiveObject) aShape =
|
||||
Handle(NIS_InteractiveObject)::DownCast(it.Key1());
|
||||
TheNISContext()->Erase(aShape,Standard_False);
|
||||
TheNISContext()->Erase(aShape);
|
||||
}
|
||||
it.Next();
|
||||
}
|
||||
TheAISContext() ->UpdateCurrentViewer();
|
||||
TheNISContext()->UpdateViews();
|
||||
// TheNISContext()->UpdateViews();
|
||||
}
|
||||
|
||||
//===============================================================
|
||||
@ -1497,12 +1497,12 @@ static int VErase2(Draw_Interpretor& , Standard_Integer argc, const char** arg
|
||||
} else if (anObj->IsKind(STANDARD_TYPE(NIS_InteractiveObject))) {
|
||||
const Handle(NIS_InteractiveObject) aShape =
|
||||
Handle(NIS_InteractiveObject)::DownCast (anObj);
|
||||
TheNISContext()->Erase(aShape,Standard_False);
|
||||
TheNISContext()->Erase(aShape);
|
||||
}
|
||||
}
|
||||
}
|
||||
TheAISContext() ->UpdateCurrentViewer();
|
||||
TheNISContext() ->UpdateViews();
|
||||
// TheNISContext() ->UpdateViews();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1530,12 +1530,12 @@ static int VEraseAll(Draw_Interpretor& di, Standard_Integer argc, const char** a
|
||||
} else if (it.Key1()->IsKind(STANDARD_TYPE(NIS_InteractiveObject))) {
|
||||
const Handle(NIS_InteractiveObject) aShape =
|
||||
Handle(NIS_InteractiveObject)::DownCast(it.Key1());
|
||||
TheNISContext()->Erase(aShape,Standard_False);
|
||||
TheNISContext()->Erase(aShape);
|
||||
}
|
||||
it.Next();
|
||||
}
|
||||
TheAISContext() ->UpdateCurrentViewer();
|
||||
TheNISContext() ->UpdateViews();
|
||||
// TheNISContext() ->UpdateViews();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1563,7 +1563,7 @@ static int VDisplayAll( Draw_Interpretor& di, Standard_Integer argc, const char*
|
||||
} else if (it.Key1()->IsKind(STANDARD_TYPE(NIS_InteractiveObject))) {
|
||||
const Handle(NIS_InteractiveObject) aShape =
|
||||
Handle(NIS_InteractiveObject)::DownCast(it.Key1());
|
||||
TheNISContext()->Erase(aShape,Standard_False);
|
||||
TheNISContext()->Erase(aShape);
|
||||
}
|
||||
it.Next();
|
||||
}
|
||||
@ -1574,14 +1574,14 @@ static int VDisplayAll( Draw_Interpretor& di, Standard_Integer argc, const char*
|
||||
Handle(AIS_InteractiveObject)::DownCast(it.Key1());
|
||||
TheAISContext()->Display(aShape, Standard_False);
|
||||
} else if (it.Key1()->IsKind(STANDARD_TYPE(NIS_InteractiveObject))) {
|
||||
const Handle(NIS_InteractiveObject) aShape =
|
||||
Handle(NIS_InteractiveObject) aShape =
|
||||
Handle(NIS_InteractiveObject)::DownCast(it.Key1());
|
||||
TheNISContext()->Display(aShape, 0L, Standard_False);
|
||||
TheNISContext()->Display(aShape);
|
||||
}
|
||||
it.Next();
|
||||
}
|
||||
TheAISContext() ->UpdateCurrentViewer();
|
||||
TheNISContext() ->UpdateViews();
|
||||
// TheNISContext() ->UpdateViews();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1865,7 +1865,7 @@ static int VDisplay2 (Draw_Interpretor& di, Standard_Integer argc, const char**
|
||||
} else if (anObj->IsKind(STANDARD_TYPE(NIS_InteractiveObject))) {
|
||||
Handle(NIS_InteractiveObject) aShape =
|
||||
Handle(NIS_InteractiveObject)::DownCast(anObj);
|
||||
TheNISContext()->Display(aShape, 0L, Standard_False);
|
||||
TheNISContext()->Display(aShape);
|
||||
}
|
||||
}
|
||||
else { // Create the AIS_Shape from a name
|
||||
@ -1879,7 +1879,7 @@ static int VDisplay2 (Draw_Interpretor& di, Standard_Integer argc, const char**
|
||||
}
|
||||
// Upadate the screen and redraw the view
|
||||
TheAISContext()->UpdateCurrentViewer();
|
||||
TheNISContext()->UpdateViews();
|
||||
// TheNISContext()->UpdateViews();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user