#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() = default; 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 << j)) ? 0.5 : -0.5) * sz2; } x[2] = this->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 << j)) ? 0.5 : -0.5) * sz2; } (*self)[i].value().SetGeometry(x, sz2); } } inline void vtkLabelHierarchy::Implementation::LabelSet::AddChildren( octree::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