~/ttk
) and decompress them by entering the following commands (omit
the $
character) in
a terminal (this assumes that you downloaded the tarballs to the
~/Downloads
directory):$ mkdir ~/ttk
$ mv ~/Downloads/ttk-0.9.2.tar.gz ~/ttk/
$ mv ~/Downloads/bettiData.tar.gz ~/ttk/
$ cd ~/ttk
$ tar xvzf ttk-0.9.2.tar.gz
$ tar xvzf bettiData.tar.gz
$ rm ttk-0.9.2.tar.gz
$ rm bettiData.tar.gz
Clip1
); second, the
boundary of the input PL 3-manifold is extracted
(ExtractSurface1
), third the connected components of the boundary
are isolated and clipped with the same parameters as the rest of the volume
(Clip2
).GenerateSurfaceNormals1
).
The display properties of the output of a filter in the main central view can
also be modified from this panel.Ctrl+space
keystroke (under Linux) and enter keywords
as shown above to quickly call filters.File
, Save state...
and choosing the Python
state file type. In the Python script, each filter instance is modeled by an
independent Python object, for which attributes can be changed and functions
can be called.pvpython
interpreter is then recommended). Thus, ParaView can be
viewed as an interactive designer of advanced analysis Python programs.
Then, writing up your own TTK module will not only expose your C++ code to
ParaView, but it will also make it readily available in Python.
To
learn more about the available ParaView filters, please see the following
tutorials:
HERE
and
THERE.
$
character):$ paraview ~/ttk/bettiData/skull.vtu
$
character):$ cd ~/ttk/ttk-0.9.2/
$ scripts/createTTKmodule.sh BettiNumbers
~/ttk/ttk-0.9.2/CMakeLists.txt
to remove all entries, except the
first line and all the lines containing the word BettiNumbers
.N
is the number of available cores on your system (omit
the $
character):$ cd ~/ttk/ttk-0.9.2/
$ mkdir build
$ cd build
$ cmake ../
$ make -jN
make -jN
).Tools
, Manage Plugins...
,
then click on the Load New...
button. Next, from the file browser
dialog, select the library we've just built:
~/ttk/ttk-0.9.2/build/paraview/BettiNumbers/libBettiNumbers.so
.
Next, you may want to check the checkbox AutoLoad
as shown above
(available after expending your plugin entry) to force ParaView to
automatically load your plugin at startup.TTK BettiNumbers
under the menu Filters
then
TTK - Misc
, as shown below.~/ttk/ttk-0.9.2/core/baseCode/bettiNumbers/BettiNumbers.h
. In the
function execute()
, add the line cout << endl <<
"Hello World!" << endl << endl;
before the return
statement. Now build your module again, load the skull data set in ParaView and
apply your BettiNumbers plugin. You should see your message "Hello World!"
appear in the terminal, as shown below.B0
) corresponds to the number of
connected component of the input manifold M
. In the following, we
will compute this number and display it in the output of the terminal (next to
our "Hello World!" message).find()
on this object returns its parent, that is
a
unique representative UF object which represents the connected component
of the
queried vertex.v0
and v1
,
the makeUnion()
operation is called between the UF objects of
v0
and v1
. This will have the effect of merging the
representatives of the corresponding connected components.M
,
one just needs to proceed as follows. First, one should iterate over the edges
of M
, call the makeUnion()
operation between the UF
objects of the vertices of each edge of M
. Finally, one should
iterate over all the UF objects, call the find()
operation and
enumerate the number of unique remaining representatives. This number
corresponds to the number of remaining connected components after all edges have
been added (initially, the number of connected components is equal to the
number of vertices in M
).~/ttk/ttk-0.9.2/core/baseCode/bettiNumbers/bettiNumbers.cmake
and
add the line ttk_add_baseCode_package(unionFind)
at the
top of the file. Next, in
~/ttk/ttk-0.9.2/core/baseCode/bettiNumbers/BettiNumbers.h
, add the
line #include <UnionFind.h>
in the file preamble.~/ttk/ttk-0.9.2/core/baseCode/bettiNumbers/BettiNumbers.h
, a
pointer to an object of this class (triangulation_
) is
readily available and correctly initialized to the triangulation passed on the
input of your module.getEdgeVertex()
), you will need, before the actual
traversal, to call the pre-conditioning function
preprocessEdges()
in a pre-process, as explained in the
documentation of the
getEdgeVertex()
function.
Note that each traversal function comes with its own pre-conditioning function,
to be called in the pre-processing stage of your module.
~/ttk/ttk-0.9.2/core/baseCode/bettiNumbers/BettiNumbers.h
, the
function setupTriangulation()
is the right placeholder to put such
a pre-conditioning statement, while the actual traversal should happen in the
execute()
function, next to our prior "Hello World!"
message.B0
, the number of connected components of
M
.UnionFind
objects with as many entries as vertices in
M
. Next, you'll need to iterate over the edges of M
and call the makeUnion()
operation on the UF objects of each edge.
Finally, you'll need to iterate over your initial array of UF objects,
re-assign to each entry the result of its find()
operation (to
obtain the latest representative) and enumerate the number of unique remaining
representatives.
B2
) corresponds to the number of
voids of the input manifold M
. To compute B2
, we will
exploit one of the results by Dey and Guha, published in their 1998 paper
"Computing Homology Groups of Simplicial Complexes in R3".B2
. From
there, edit the function execute()
of
~/ttk/ttk-0.9.2/core/baseCode/bettiNumbers/BettiNumbers.h
to also
compute and display B2
.
B1
) corresponds to the number of
independent cycles
of the input manifold M
.
To compute B1
, we will
exploit one of the results by Dey and Guha, published in their 1998 paper
"Computing Homology Groups of Simplicial Complexes in R3".B1
.
From there, edit the function execute()
of
~/ttk/ttk-0.9.2/core/baseCode/bettiNumbers/BettiNumbers.h
to also
compute and display B1
.
X
of M
.
How does it relate to the Betti numbers of M
?Threshold
filter on your input
triangulation and modify the Maximum
parameter (the upper bound).
Since our test data sets come with an attached scalar field, this will have the
effect of selecting all the tetrahedra of M
with vertices having a
default scalar value below the Maximum
parameter.Maximum
parameter again and click on Apply
. The
Betti numbers should be updated automatically.Maximum
. Where do the Betti numbers
change? What do these configurations correspond to?~/ttk/bettiData/
directory. Note that for at.vti
, you
will need to call the filter Tetrahedralize
prior to any other
processing.Maximum
parameter of the
Threshold
filter, change the Minimum
parameter
instead. What do you observe in terms of the changes of Betti numbers?