#ifndef vtkLabelHierarchyPrivate_h #define vtkLabelHierarchyPrivate_h #include #include "octree/octree" //---------------------------------------------------------------------------- // vtkLabelHierarchy::Implementation class vtkLabelHierarchy::Implementation { public: Implementation() { this->Hierarchy2 = nullptr; this->Hierarchy3 = nullptr; this->ActualDepth = 5; this->Z2 = 0.; } ~Implementation() { delete this->Hierarchy2; delete this->Hierarchy3; } bool ComparePriorities( vtkIdType a, vtkIdType b ) { vtkDataArray* priorities = this->Husk->GetPriorities(); return priorities ? priorities->GetTuple1( a ) > priorities->GetTuple1( b ) : a < b; } struct PriorityComparator { vtkLabelHierarchy* Hierarchy; PriorityComparator() { // See comment near declaration of Current for more info: this->Hierarchy = vtkLabelHierarchy::Implementation::Current; } PriorityComparator( vtkLabelHierarchy* h ) { this->Hierarchy = h; } PriorityComparator( const PriorityComparator& src ) { this->Hierarchy = src.Hierarchy; } PriorityComparator& operator=(const PriorityComparator& rhs) { if (this != &rhs) { this->Hierarchy = rhs.Hierarchy; } return *this; } ~PriorityComparator() { } bool operator () ( const vtkIdType& a, const vtkIdType& b ) const { if (nullptr == this->Hierarchy) { vtkGenericWarningMacro( "error: NULL this->Hierarchy in PriorityComparator" ); return a < b; } if (nullptr == this->Hierarchy->GetImplementation()) { vtkGenericWarningMacro( "error: NULL this->Hierarchy->GetImplementation() in PriorityComparator" ); return a < b; } return this->Hierarchy->GetImplementation()->ComparePriorities( a, b ); } }; class LabelSet : public std::multiset { public: LabelSet( vtkLabelHierarchy* hierarchy ) : std::multiset( PriorityComparator(hierarchy) ) { this->TotalAnchors = 0; this->Size = 1.; for ( int i = 0; i < 3; ++ i ) { this->Center[i] = 0.; } } LabelSet( const LabelSet& src ) : std::multiset( src ) { this->TotalAnchors = src.TotalAnchors; this->Size = src.Size; for ( int i = 0; i < 3; ++ i ) { this->Center[i] = src.Center[i]; } } LabelSet() : std::multiset() { this->TotalAnchors = 0; this->Size = 1.; for ( int i = 0; i < 3; ++ i ) { this->Center[i] = 0.; } } LabelSet& operator = ( const LabelSet& rhs ) { if ( this != &rhs ) { std::multiset::operator = ( rhs ); this->TotalAnchors = rhs.TotalAnchors; this->Size = rhs.Size; for ( int i = 0; i < 3; ++ i ) { this->Center[i] = rhs.Center[i]; } } return *this; } const double* GetCenter() const { return this->Center; } double GetSize() const { return this->Size; } void SetGeometry( const double center[3], double length ); void SetChildGeometry( octree::octree_node_pointer self ); void SetChildGeometry( octree::octree_node_pointer self ); void AddChildren( octree::octree_node_pointer self, LabelSet& emptyNode ); void AddChildren( octree::octree_node_pointer self, LabelSet& emptyNode ); void Insert( vtkIdType anchor ) { this->insert( anchor ); ++ this->TotalAnchors; } void Increment() { ++ this->TotalAnchors; } vtkIdType GetLocalAnchorCount() const { return static_cast(this->size()); } vtkIdType GetTotalAnchorCount() const { return this->TotalAnchors; } vtkIdType TotalAnchors; // Count of all anchors stored in this node and its children. double Center[3]; // Geometric coordinates of this node's center. double Size; // Length of each edge of this node. }; typedef octree HierarchyType2; typedef octree::cursor HierarchyCursor2; typedef octree::iterator HierarchyIterator2; typedef octree HierarchyType3; typedef octree::cursor HierarchyCursor3; typedef octree::iterator HierarchyIterator3; //typedef std::map > >::iterator MapCoordIter; // Description: // Computes the depth of the generated hierarchy. //void ComputeActualDepth(); // Description: // Routines called by ComputeHierarchy() void BinAnchorsToLevel( int level ); void PromoteAnchors(); void DemoteAnchors( int level ); void RecursiveNodeDivide( HierarchyCursor2& cursor ); void RecursiveNodeDivide( HierarchyCursor3& cursor ); // Description: // Routines called by ComputeHierarchy() void PrepareSortedAnchors( LabelSet& anchors ); void FillHierarchyRoot( LabelSet& anchors ); void DropAnchor2( vtkIdType anchor ); void DropAnchor3( vtkIdType anchor ); void SmudgeAnchor2( HierarchyCursor2& cursor, vtkIdType anchor, double* x ); void SmudgeAnchor3( HierarchyCursor3& cursor, vtkIdType anchor, double* x ); double Z2; // common z-coordinate of all label anchors when quadtree (Hierarchy2) is used. HierarchyType2* Hierarchy2; // 2-D quadtree of label anchors (all input points have same z coord) HierarchyType3* Hierarchy3; // 3-D octree of label anchors (input point bounds have non-zero z range) vtkTimeStamp HierarchyTime; HierarchyType3::size_type ActualDepth; vtkLabelHierarchy* Husk; static vtkLabelHierarchy* Current; }; inline void vtkLabelHierarchy::Implementation::LabelSet::SetGeometry( const double center[3], double length ) { for ( int i = 0; i < 3; ++ i ) { this->Center[i] = center[i]; } this->Size = length; } inline void vtkLabelHierarchy::Implementation::LabelSet::SetChildGeometry( octree::octree_node_pointer self ) { double sz2 = this->Size / 2.; double x[3]; for ( int i = 0; i < self->num_children(); ++ i ) { for ( int j = 0; j < 2; ++ j ) { x[j] = this->Center[j] + ( ( i & (1<Center[2]; (*self)[i].value().SetGeometry( x, sz2 ); } } inline void vtkLabelHierarchy::Implementation::LabelSet::SetChildGeometry( octree::octree_node_pointer self ) { double sz2 = this->Size / 2.; double x[3]; for ( int i = 0; i < self->num_children(); ++ i ) { for ( int j = 0; j < 3; ++ j ) { x[j] = this->Center[j] + ( ( i & (1<::octree_node_pointer self, LabelSet& emptyNode ) { self->add_children( emptyNode ); this->SetChildGeometry( self ); } inline void vtkLabelHierarchy::Implementation::LabelSet::AddChildren( octree::octree_node_pointer self, LabelSet& emptyNode ) { self->add_children( emptyNode ); this->SetChildGeometry( self ); } #endif // vtkLabelHierarchyPrivate_h // VTK-HeaderTest-Exclude: vtkLabelHierarchyPrivate.h