OpenWalnut  1.5.0dev
WJoinContourTree.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <algorithm>
26 #include <memory>
27 #include <set>
28 #include <string>
29 #include <vector>
30 
31 #include "../../common/WStringUtils.h"
32 #include "../../common/WTransferable.h"
33 #include "../../common/datastructures/WUnionFind.h"
34 #include "../../common/exceptions/WNotImplemented.h"
35 #include "../WValueSet.h"
36 #include "WJoinContourTree.h"
37 
39  : WTransferable()
40 {
41 }
42 
43 WJoinContourTree::WJoinContourTree( std::shared_ptr< WDataSetSingle > dataset )
44  : WTransferable(),
45  m_elementIndices( dataset->getValueSet()->size() ),
46  m_joinTree( dataset->getValueSet()->size() ),
47  m_lowestVoxel( dataset->getValueSet()->size() )
48 {
49  if( dataset->getValueSet()->order() != 0 || dataset->getValueSet()->dimension() != 1 )
50  {
51  throw WNotImplemented( std::string( "ATM there is only support for scalar fields" ) );
52  }
53  m_valueSet = std::dynamic_pointer_cast< WValueSet< double > >( dataset->getValueSet() );
54  if( !m_valueSet )
55  {
56  throw WNotImplemented( std::string( "ATM there is only support for scalar fields with doubles as scalars" ) );
57  }
58  m_grid = std::dynamic_pointer_cast< WGridRegular3D >( dataset->getGrid() );
59  if( !m_grid )
60  {
61  throw WNotImplemented( std::string( "Only WGridRegular3D is supported, despite that its not a simplicial mesh!" ) );
62  }
63  for( size_t i = 0; i < m_elementIndices.size(); ++i )
64  {
65  m_joinTree[i] = m_elementIndices[i] = i;
66  }
67 }
68 
70 {
72  std::sort( m_elementIndices.begin(), m_elementIndices.end(), comp );
73 }
74 
76 {
78 
79  WUnionFind uf( m_joinTree.size() );
80 
81  for( size_t i = 0; i < m_joinTree.size(); ++i )
82  {
84  std::vector< size_t > neighbours = m_grid->getNeighbours( m_elementIndices[i] );
85  std::vector< size_t >::const_iterator n = neighbours.begin();
86  for( ; n != neighbours.end(); ++n )
87  {
88  if( uf.find( m_elementIndices[i] ) == uf.find( *n ) || m_valueSet->getScalar( *n ) <= m_valueSet->getScalar( m_elementIndices[i] ) )
89  {
90  continue;
91  }
92  else
93  {
94  uf.merge( m_elementIndices[i], *n );
95  m_joinTree[ m_lowestVoxel[ uf.find( *n ) ] ] = m_elementIndices[i];
96  m_lowestVoxel[ uf.find( *n ) ] = m_elementIndices[i];
97  }
98  }
99  }
100 }
101 
102 std::shared_ptr< std::set< size_t > > WJoinContourTree::getVolumeVoxelsEnclosedByIsoSurface( const double isoValue ) const
103 {
104  std::shared_ptr< std::vector< size_t > > result( new std::vector< size_t >( m_elementIndices ) );
105  WUnionFind uf( m_elementIndices.size() );
106 
107  // using string_utils::operator<<;
108  // std::cout << "m_element: " << m_elementIndices << std::endl;
109 
110  //std::stringstream ss;
111  // assume the m_elementIndices array is still sorted descending on its iso values in the valueset
112  for( size_t i = 0; i < m_elementIndices.size() && m_valueSet->getScalar( m_elementIndices[i] ) >= isoValue; ++i )
113  {
114  // std::cout << "processing element: " << i << std::endl;
115  // std::cout << "having index: " << m_elementIndices[i] << std::endl;
116  // using string_utils::operator<<;
117  // std::cout << "xyz: " << m_grid->getNeighbours( m_elementIndices[i] ) << std::endl;
118  // std::cout << "having isovalue: " << m_valueSet->getScalar( m_elementIndices[i] ) << std::endl;
119  // ss << " m_elementIndices[i]:isovalue=" << m_valueSet->getScalar( m_elementIndices[i] ) << ", ";
120  size_t target = m_joinTree[ m_elementIndices[i] ];
121  // std::cout << "having edge to: " << target << std::endl;
122  if( m_valueSet->getScalar( target ) >= isoValue )
123  {
124  uf.merge( target, m_elementIndices[i] );
125  }
126  }
127  //std::cout << ss.str() << std::endl;
128  return uf.getMaxSet();
129 }
130 
132  : m_valueSet( valueSet )
133 {
134 }
135 
137 {
138  return ( m_valueSet->getScalar( i ) > m_valueSet->getScalar( j ) );
139 }
140 
141 // make the class beeing a WTransferrable:
142 // ---------------------------------------
143 std::shared_ptr< WPrototyped > WJoinContourTree::m_prototype = std::shared_ptr< WPrototyped >();
144 
145 std::shared_ptr< WPrototyped > WJoinContourTree::getPrototype()
146 {
147  if( !m_prototype )
148  {
149  m_prototype = std::shared_ptr< WPrototyped >( new WJoinContourTree() );
150  }
151  return m_prototype;
152 }
Comperator for indirect sort so the value set is not modified.
bool operator()(size_t i, size_t j)
Compares the isovalue of the elments with index i and j.
IndirectCompare(std::shared_ptr< WValueSet< double > > valueSet)
Since we must have access to the value set we need a reference to it.
Processes a dataset for join tree computation.
std::vector< size_t > m_elementIndices
Stores the component number for the i'th vertex in the value set.
std::vector< size_t > m_lowestVoxel
Stores the index of lowest element for the i'th component.
std::vector< size_t > m_joinTree
For each index stores which node it is connected to.
std::shared_ptr< WGridRegular3D > m_grid
Stores the reference to the grid of the given dataset to get the neighbours of a voxel.
void buildJoinTree()
Build the join tree.
WJoinContourTree(std::shared_ptr< WDataSetSingle > dataset)
Initialize this with a data set for which the join tree should be computed.
static std::shared_ptr< WPrototyped > m_prototype
The prototype as singleton.
static std::shared_ptr< WPrototyped > getPrototype()
Returns a prototype instantiated with the true type of the deriving class.
void sortIndexArray()
Sort the indices on their element value of the value set in descending order.
std::shared_ptr< std::set< size_t > > getVolumeVoxelsEnclosedByIsoSurface(const double isoValue) const
For a given isovalue all the voxel which are enclosed by the biggest isosurface are computed.
std::shared_ptr< WValueSet< double > > m_valueSet
Stores reference to the isovalues, so we may sort them indirect on their value.
Indicates invalid element access of a container.
Class building the interface for classes that might be transferred using WModuleConnector.
Definition: WTransferable.h:38
Implements a very simple union-find datastructure aka disjoint_sets.
Definition: WUnionFind.h:74
std::shared_ptr< std::set< size_t > > getMaxSet()
Computes the set with maximum number of elements.
Definition: WUnionFind.cpp:82
void merge(size_t i, size_t j)
Merges two components (iow: makes a union) where the given elements are members of.
Definition: WUnionFind.cpp:60
size_t find(size_t x)
Find the canonical element of the given element and do path compression.
Definition: WUnionFind.cpp:45
Base Class for all value set types.
Definition: WValueSet.h:47