1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-05-06 10:36:12 +03:00
occt/src/NCollection/NCollection_EBTree.hxx
oan 01a6e62bc2 0024968: Impove BRepMesh_Classifier to cope with intersection of huge number of wires
BRepMesh_Classifier: Two-pass approach for intersection check with possibility to run it in parallel mode.
First pass - bounding boxes of segments are checked for overlapping;
Second pass - intersection point is calculated in case if overlapping is detected.

Make NCollection_UBTree::ChangeLastNode() exported due to compilation error on Linux platform.
Reason: method does not depend on template parameters, so it should be available.

Revert previous change and try to use another trick for Linux

Fix compilation warning on MacOS: remove redundant constant
Fix regressions: do not consider insignificant loops in case of self intersections on the same wire.
More sugar solution for compilation errors on NCollection_EBTree on Linux

Test cases for issue CR24968
2014-07-10 14:41:09 +04:00

221 lines
8.7 KiB
C++

// Created on: 2002-07-30
// Created by: Michael SAZONOV
// Copyright (c) 2002-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef NCollection_EBTree_HeaderFile
#define NCollection_EBTree_HeaderFile
#include <NCollection_UBTree.hxx>
#include <Standard_DefineHandle.hxx>
#include <MMgt_TShared.hxx>
#include <NCollection_List.hxx>
#include <TColStd_SequenceOfInteger.hxx>
#include <NCollection_DataMap.hxx>
/**
* The algorithm of unbalanced binary tree of overlapped bounding boxes with
* the possibility of deleting objects from the tree.
*
* In addition to the requirements to the object type defined in the parent
* class this class requires that the object can be hashed and compared to
* another object (functions HashCode and IsEqual are defined for it), since
* the class NCollection_DataMap is used where the object plays the role of
* the key.
*/
template <class TheObjType, class TheBndType> class NCollection_EBTree
: public NCollection_UBTree <TheObjType, TheBndType>
{
public:
typedef NCollection_UBTree <TheObjType, TheBndType> UBTree;
typedef TYPENAME UBTree::TreeNode TreeNode;
// ---------- PUBLIC METHODS ----------
/**
* Constructor.
*/
NCollection_EBTree (const Handle(NCollection_BaseAllocator)& theAllocator=0L)
: UBTree (theAllocator) {}
/**
* Extends the functionality of the parent method by maintaining
* the map myObjNodeMap. Redefined virtual method
* @return
* False if the tree already contains theObj.
*/
Standard_EXPORT Standard_Boolean Add (const TheObjType& theObj,
const TheBndType& theBnd);
/**
* Removes the given object and updates the tree.
* @return
* False if the tree does not contain theObj
*/
Standard_EXPORT Standard_Boolean Remove (const TheObjType& theObj);
/**
* @return
* True if the tree contains the object.
*/
Standard_Boolean Contains (const TheObjType& theObj) const
{ return myObjNodeMap.IsBound (theObj); }
/**
* @return
* The leaf node containing the object.
*/
const TreeNode& FindNode (const TheObjType& theObj) const
{ return *myObjNodeMap.Find (theObj); }
/**
* Clears the contents of the tree. Redefined virtual method
*/
void Clear (const Handle(NCollection_BaseAllocator)& aNewAlloc = 0L)
{ myObjNodeMap.Clear(); UBTree::Clear(aNewAlloc); }
private:
// ---------- PRIVATE METHODS ----------
/// Copy constructor (prohibited).
NCollection_EBTree (const NCollection_EBTree&);
/// Assignment operator (prohibited).
NCollection_EBTree& operator = (const NCollection_EBTree&);
// ---------- PRIVATE FIELDS ----------
NCollection_DataMap <TheObjType, TreeNode*>
myObjNodeMap; ///< map of object to node pointer
};
// ================== METHODS TEMPLATES =====================
//=======================================================================
//function : Add
//purpose : Updates the tree with a new object and its bounding box.
// Returns false if the tree already contains theObj.
//=======================================================================
template <class TheObjType, class TheBndType>
Standard_Boolean NCollection_EBTree<TheObjType,TheBndType>::Add
(const TheObjType& theObj,
const TheBndType& theBnd)
{
Standard_Boolean result = Standard_False;
if (!Contains (theObj)) {
// Add object in the tree using parent method
UBTree::Add (theObj, theBnd);
// Update the map
TreeNode& aNewNode = this->ChangeLastNode();
myObjNodeMap.Bind (theObj, &aNewNode);
// If the new node is not the root (has a parent) check the neighbour node
if (!aNewNode.IsRoot()) {
TreeNode& aNeiNode = aNewNode.ChangeParent().ChangeChild(0);
if (aNeiNode.IsLeaf()) {
myObjNodeMap.UnBind (aNeiNode.Object());
myObjNodeMap.Bind (aNeiNode.Object(), &aNeiNode);
}
}
result = Standard_True;
}
return result;
}
//=======================================================================
//function : Remove
//purpose : Removes the given object and updates the tree.
// Returns false if the tree does not contain theObj.
//=======================================================================
template <class TheObjType, class TheBndType>
Standard_Boolean NCollection_EBTree<TheObjType,TheBndType>::Remove
(const TheObjType& theObj)
{
Standard_Boolean result = Standard_False;
if (Contains (theObj)) {
TreeNode* pNode = myObjNodeMap (theObj);
if (pNode->IsRoot()) {
// it is the root, so clear all the tree
Clear();
}
else {
// it is a child of some parent,
// so kill the child that contains theObj
// and update bounding boxes of all ancestors
myObjNodeMap.UnBind (theObj);
TreeNode* pParent = &pNode->ChangeParent();
pParent->Kill ((pNode == &pParent->Child(0) ? 0 : 1),
this->Allocator());
if (pParent->IsLeaf()) {
// the parent node became a leaf, so update the map
myObjNodeMap.UnBind (pParent->Object());
myObjNodeMap.Bind (pParent->Object(), pParent);
}
while (!pParent->IsRoot()) {
pParent = &pParent->ChangeParent();
pParent->ChangeBnd() = pParent->Child(0).Bnd();
pParent->ChangeBnd().Add (pParent->Child(1).Bnd());
}
}
result = Standard_True;
}
return result;
}
// ======================================================================
// Declaration of handled version of NCollection_EBTree.
// In the macros below the arguments are:
// _HEBTREE - the desired name of handled class
// _OBJTYPE - the name of the object type
// _BNDTYPE - the name of the bounding box type
// _HUBTREE - the name of parent class
// (defined using macro DEFINE_HUBTREE)
#define DEFINE_HEBTREE(_HEBTREE, _OBJTYPE, _BNDTYPE, _HUBTREE) \
class _HEBTREE : public _HUBTREE \
{ \
public: \
typedef NCollection_UBTree <_OBJTYPE, _BNDTYPE> UBTree; \
typedef NCollection_EBTree <_OBJTYPE, _BNDTYPE> EBTree; \
\
_HEBTREE () : _HUBTREE(new EBTree) {} \
/* Empty constructor */ \
\
/* Access to the methods of EBTree */ \
\
Standard_Boolean Remove (const _OBJTYPE& theObj) \
{ return ChangeETree().Remove (theObj); } \
\
Standard_Boolean Contains (const _OBJTYPE& theObj) const \
{ return ETree().Contains (theObj); } \
\
const UBTree::TreeNode& FindNode (const _OBJTYPE& theObj) const \
{ return ETree().FindNode (theObj); } \
\
/* Access to the extended tree algorithm */ \
\
const EBTree& ETree () const { return (const EBTree&) Tree(); } \
EBTree& ChangeETree () { return (EBTree&) ChangeTree(); } \
\
DEFINE_STANDARD_RTTI (_HEBTREE) \
/* Type management */ \
}; \
DEFINE_STANDARD_HANDLE (_HEBTREE, _HUBTREE)
#define IMPLEMENT_HEBTREE(_HEBTREE, _HUBTREE) \
IMPLEMENT_STANDARD_HANDLE (_HEBTREE, _HUBTREE) \
IMPLEMENT_STANDARD_RTTIEXT(_HEBTREE, _HUBTREE)
#endif