1 % ==========================================
2 \documentclass[11pt,final,a4paper]{article}
5 \title{The Black Box Toolkit\\Package Developers' Guide}
7 \author{Laurent Guigues}
9 % ==========================================
11 % ==========================================
14 % ==========================================
16 % ==========================================
18 % ==========================================
19 % ==========================================
21 %\section{Creating your own black boxes}
23 % ==========================================
25 % ==========================================
26 \section{Steps in the creation of new black boxes}
27 % ==========================================
28 Any black box must be included in a \bbtk package,
29 that is in a particular shared library which can be loaded
30 dynamically by \bbtk (hence applications which use \bbtk,
31 such as the interpreter \bbi).
34 \item \textbf{Create a new package. }
35 Before defining any black box you
36 have to create a package, or more precisely
37 the files which will allow you to generate the package
38 (compile and link the shared library) and may be install it.
39 The utility \texttt{bbCreatePackage} does it for you.
43 \item The black boxes you want to create are based on
44 a processing code (\CPP classes or \C functions) which
45 is in an existing project handled by \cmake
46 and you want the new package to be part of your existing project.
47 You will have to create your new package into the source tree of your
49 \item You do not have an already existing project (you want
50 to create the new boxes from scratch) or you want/are imposed
51 that the existing project remain external to the package project.
52 You will have to create your new package in a new location and
53 may be include/link against existing libraries.
56 \item \textbf{Describe your new box. }
57 You can do it either :
59 \item In \CPP code. You will have to write the class for
60 your box, mostly using \bbtk macros.
62 When configuring your project with \cmake,
63 the utility \bbfy will then generate the corresponding \CPP code.
68 % ==========================================
69 \section{Creating a new black box package}
70 % ==========================================
72 The utility \texttt{bbCreatePackage} allows to
73 create a new void package. It is a command script
74 (a \texttt{bash} script on linux,
75 a \texttt{dos} script on windows)
76 which creates the directory structure and the \texttt{cmake}
77 files necessary to build the project.
79 Its usage is as follows :
81 > bbCreatePackage <package-folder-with-complete-path>
84 You must then decide the name of your new package.
85 It will be the name used to load the package in \texttt{bbi}.
87 For example, on linux, turn to an empty folder and type :
90 > bbCreatePackage pack1
96 ----- Creating new black box package in 'pack1' -----
97 -> Creating directory 'pack1'
98 -> Creating file 'pack1/CMakeLists.txt'
99 -> Creating directory 'pack1/cmake'
100 -> Copying files in 'pack1/cmake'
102 Edit the file 'pack1/CMakeLists.txt' to customize your package
105 the file tree obtained is :
113 |-- ConfigurePackage.cmake
115 |-- FindLibrary.cmake.in
117 |-- GenerateLibraryConfig.cmake
118 |-- InstallLibrary.cmake
119 |-- LibraryConfig.cmake.in
120 |-- UseLibrary.cmake.in
124 1 directory, 12 files
127 The directory \texttt{pack1} is the directory of your new package,
128 in which you will create the files describing your black boxes.
129 But first, you have to customize your new package, by editing the file
130 \texttt{CMakeLists.txt} in the \texttt{pack1} directory.
133 \begin{file}{pack1/CMakeLists.txt}
136 #...........................................................................
137 # CMake configuration file for a bbtk package.
138 # Automatically generated by bbCreatePackage.
139 # - The lines which are between dotted comments (#...) must be left unchanged
140 # - The lines which are between dashed comments (#===) can be edited to customize the package
141 #...........................................................................
143 #...........................................................................
144 INCLUDE(cmake/Configure.cmake)
145 #...........................................................................
148 #===========================================================================
149 # THE NAME OF THE PACKAGE
150 SET(PACKAGE_NAME Example)
151 #===========================================================================
154 #...........................................................................
155 # DOES THE USER WANT TO BUILD THE PACKAGE ?
156 OPTION(BUILD_PACKAGE_${PACKAGE_NAME}
157 "Build the bbtk package ${PACKAGE_NAME}" ON)
158 #...........................................................................
160 #...........................................................................
161 # IF THE USER HAS CHOSEN TO BUILD THE PACKAGE
162 IF(BUILD_PACKAGE_${PACKAGE_NAME})
163 #...........................................................................
166 #===========================================================================
167 # UNCOMMENT NEXT LINES IF THE PACKAGE USES THE VTK LIBRARY, THE ITK LIB, ETC.
168 # SET(${PACKAGE_NAME}_USE_VTK ON)
169 # SET(${PACKAGE_NAME}_USE_ITK ON)
170 # SET(${PACKAGE_NAME}_USE_GDCM ON)
171 # SET(${PACKAGE_NAME}_USE_GSMIS ON)
172 # SET(${PACKAGE_NAME}_USE_WXWIDGETS ON)
173 #===========================================================================
175 #===========================================================================
176 # PACKAGE AUTHOR : PREFERABLY PROVIDE YOUR EMAIL ADDRESS
177 SET(PACKAGE_AUTHOR "foo.bar@creatis.insa-lyon.fr")
178 #===========================================================================
180 #===========================================================================
181 # PACKAGE DESCRIPTION
182 SET(PACKAGE_DESCRIPTION "My marvelous black box package")
183 #===========================================================================
185 #===========================================================================
186 # PACKAGE VERSION NUMBER
187 SET(PACKAGE_MAJOR_VERSION 1)
188 SET(PACKAGE_MINOR_VERSION 0)
189 SET(PACKAGE_BUILD_VERSION 0)
190 #===========================================================================
192 #===========================================================================
193 # THE xml SOURCES OF THE PACKAGE
194 # EITHER UNCOMMENT NEXT LINE TO bbfy ALL .xml OF THE DIRECTORY :
195 SET(COMPILE_ALL_XML ON)
196 # ... OR LIST THE FILES TO COMPILE MANUALLY :
197 #SET(PACKAGE_XML_SOURCES
198 # LIST HERE THE FILES TO bbfy TO BUILD THE LIB
199 # E.G. TO bbfy "toto.xml" ADD "toto" (NO EXTENSION)
201 #===========================================================================
203 #===========================================================================
204 # THE C++ SOURCES OF THE PACKAGE
205 # EITHER UNCOMMENT NEXT LINE TO COMPILE ALL .cxx OF THE DIRECTORY :
206 SET(COMPILE_ALL_CXX ON)
207 # ... OR LIST THE FILES TO COMPILE MANUALLY :
208 #SET(PACKAGE_CXX_SOURCES
209 # LIST HERE THE FILES TO COMPILE TO BUILD THE LIB
210 # E.G. TO COMPILE "toto.cxx" ADD "toto" (NO EXTENSION)
212 #===========================================================================
214 #===========================================================================
216 # LIST HERE YOUR ADDITIONAL INCLUDE DIRECTORIES (EXCEPT BBTK'S)
218 #===========================================================================
220 #===========================================================================
222 # LIST HERE THE ADDITIONAL LIBS TO LINK AGAINST (EXCEPT BBTK'S)
224 #===========================================================================
227 #...........................................................................
228 INCLUDE(cmake/ConfigurePackage.cmake)
229 #...........................................................................
231 ENDIF(BUILD_PACKAGE_\${PACKAGE_NAME})
232 #...........................................................................
234 #...........................................................................
238 The comments in the file should be easily understandable !
239 You have to customize the lines which are enclosed
240 between dashed comment lines.
241 In these sections, you can set :
243 \item The \textbf{name} of your package. This will be the name used to load it in \bbi. The shared library however will be called \texttt{bb}name hence on
244 \lin the object file will be called \texttt{libbb}name\texttt{.so}
245 and on \win it will be called \texttt{bb}name\texttt{.dll}.
246 \item The \textbf{libraries used} by the package : \vtk, \itk, \gdcm, \gsmis, \wx. The mecanisms to find these libraries, their sources and to link against them are automatically handled by the \cmake files installed by \bbCreatePackage. You just have to uncomment a line to use one of these libraries.
247 \item The \textbf{author(s)} of the package. Preferably provide e-mail adresses.
248 \item A \textbf{description} of the package, which will appear in the help of your package or in its html documentation automatically generated by \bbdoc.
249 \item The \textbf{version} of the package.
250 \item The \textbf{\xml sources} of the package : you can list each input \xml file explicitly or tell \cmake to include in the project all the \xml files of the directory.
251 \item The \textbf{\CPP sources} of the package : you can list each input \CPP file explicitly or tell \cmake to include in the project all the \CPP files of the directory.
252 \item \textbf{Additional include directories}. Set it if your package needs to include source files which are not in the package directory, typically if it depends on another library which is not one the libraries automatically handled (\vtk, \itk...).
253 \item \textbf{Additional libraries} to link against. Set it if your package needs to link against another library which is not one the libraries automatically handled (\vtk, \itk...).
256 Of course, this is only a framework and you can add any other \cmake commands
259 % ==========================================
260 \section{Creating a new box}
261 % ==========================================
263 % ==========================================
264 \subsection{Principles}
265 % ==========================================
267 \subsubsection{\texttt{C++} or \texttt{XML} ?}
268 There are two ways to create a new black box in an existing package :
270 \item Write an \xml description file which will be automatically
271 translated in \CPP by the \bbfy application (recommanded).
272 \item Write the \CPP code of the box using \bbtk macros.
275 \subsubsection{From which \bbtk class inherit ?}
277 Apart from this choice of the description langage to use,
278 there is an important choice to do concerning the implementation of the box.
279 In \CPP, a black box is nothing but a class which has the standard
280 interface of all black boxes : what's its name ? inputs ? outputs ? and so on.
281 The abstract description of this interface is done in the class
282 \texttt{bbtk::BlackBox} and is implemented in its child classes :
283 \texttt{bbtk::UserBlackBox} and \texttt{bbtk::WxBlackBox}
284 \footnote{all the classes of the \bbtk library are in a \emph{namespace}
286 and the \CPP header of a class called \texttt{NameOfAClass} is
287 in the file called \texttt{bbtkNameOfAClass.h}}.
288 To create a new black box, you have to inherit one of these two
289 concrete classes in order to inherit the black box interface and a
290 particular implementation of this interface.
291 If your black box is a \emph{Widget} black box,
292 that is a black box which has (or is)
293 a piece of a graphical interface based on the \wx library,
294 then it must inherit the class \texttt{bbtk::WxBlackBox}.
295 Concretely, a \texttt{bbtk::WxBlackBox} is associated
296 a \texttt{wxWindow} and must be able to return a pointer to it.
297 If your black box is not a widget black box, it must inherit
298 \texttt{bbtk::UserBlackBox}.
300 \subsubsection{Inherit or encapsulate ?}
302 Now, your black box will do something (hopefully !).
303 When you decide to write a new black box,
304 you should be in one of these three cases :
306 \item You already have a \texttt{C}-like function which
307 does the processing that you wish to 'blackboxify'
308 \item You already have a \CPP class which
309 does the processing that you wish to 'blackboxify'
310 \item You start from scratch without any existing code
313 The idea of \BBTK is to embed processing codes into
314 \CPP objects which have a standard and generic interface -
315 namely black boxes - to be able to chain arbitrary
316 processes afterwards.
318 In \CPP, in order to embed an existing processing \emph{class}
319 into a standard interface you only have two possibilities :
321 \item {\bf Inherit} the existing processing class
322 \emph{and} the interface class (e.g. \texttt{bbtk::UserBlackBox}).
323 In this case you have to :
325 \item make the link between the inputs and outputs of the black box
326 and the interface of the inherited class
327 \item call the processing
328 method of the inherited class in the processing method of the black box.
330 \item {\bf Encapsulate} the existing processing class
331 in a class inherited from
332 the interface class (e.g. \texttt{bbtk::UserBlackBox}).
333 In this case you have to :
335 \item declare it as a member of the black box,
336 \item instantiate it at the right time
337 (either in the constructor or in the processing method of the black box)
338 \item in the processing method of the black box :
340 \item set the inputs of the member procesing class with the inputs of the black box,
341 \item call the processing method of the encapsulated class
342 \item set the ouputs of the black box with the outputs of the encapsulated
348 If you wish to 'blackboxify' a C-like \emph{function},
349 you do not have the choice, you can only use the second mechanism,
350 namely encapsulation.
352 Obviously, the inheritance mechanism is more powerfull
353 and - when it is possible to use it - it demands less effort
354 because, as we will see, in \bbtk you can directly
355 link the accessors to the input and output data of the box
356 to the accessors of the inherited processing class,
357 as well as the procesing method of the black box
358 to the processing method of the inherited processing class,
359 very much like a callback mechanism.
361 \subsubsection{Informations to provide}
363 Finally, to create a new black box, you will have to give :
365 \item The {\bf name} of the box
366 \item The {\bf author} of the box
367 \item A {\bf description} of the box
368 \item The {\bf package} to which the box belongs (can we do it automatically ? LG : think about it)
369 \item Its {\bf parent black box}, either \texttt{bbtk::UserBlackBox} or \texttt{bbtk::WxBlackBox}
370 \item $[$Optional$]$ The additional {\bf include files} which are necessary for the code to compile (classes or functions declarations ...)
371 \item $[$Optional$]$ The other {\bf parent(s)} of the box (which must be known hence their header included)
372 \item $[$Optional$]$ The {\bf namespace} to which the box belongs
373 \item The box {\bf inputs} and {\bf outputs}, and for each one :
375 \item Its {\bf name} : the string which will identify the input or output
376 \item Its {\bf type} : any \CPP type, either a basic type or a user defined type (class ...) but which must be known, hence the necessary files must be included.
377 \item Its {\bf help} : a string describing the input / output
379 \item Its {\bf processing} code, which can be a simple callback or an arbitrary complex code
382 \subsubsection{Input and output accessors}
384 When you encapsulate a processing class or a C function
385 or when you write down a black box from scratch,
386 you must access the inputs and outputs of the black box,
387 in order to interface it manually with your processing method
388 or simply write your processing code
389 (there are other cases in which you also need to access the
390 inputs and outputs, we will talk about them later).
392 The only thing you must know about the \CPP code generated
393 from your \xml or your \CPP macro-based description
394 is that when you declare an input
395 or an output of a black box then
396 two \emph{accessors} for this input or output are generated :
397 one to \emph{get} the value of the input or output and
398 one to \emph{set} it.
399 These accessors have normalized names :
402 \item The declaration of an {\bf input} called \texttt{NAME} and
403 of type \texttt{TYPE} generates the two accessors
404 \footnote{For the sake of simplicity, the parameters and return value are
405 shown here as if they were all passed by value.
406 However the actual code can use references.
407 The same way, the issue of const or non const methods is eluded here.
408 Different cases occur in practice.}:
410 \item \texttt{void bbSetInput<NAME>(<TYPE>);}
411 \item \texttt{<TYPE> bbGetInput<NAME>();}
413 \item The declaration of an {\bf output} called \texttt{NAME} and
414 of type \texttt{TYPE} generates the two accessors:
416 \item \texttt{void bbSetOutput<NAME>(<TYPE>);}
417 \item \texttt{<TYPE> bbGetOutput<NAME>();}
421 For example, declaring an input called \texttt{Image}
422 would generate the two accessors \texttt{bbSetInputImage} and
423 \texttt{bbGetInputImage}.
427 \item All \bbtk methods are prefixed by \texttt{bb}
428 to avoid conflicts with potential inherited methods.
429 \item An input and an output can have the same name (e.g. 'Image').
430 No conflict between accessors occur (e.g.
431 four distinct accessors are created :
432 \texttt{bbSetInputImage},
433 \texttt{bbGetInputImage},
434 \texttt{bbSetOutputImage} and
435 \texttt{bbGetOutputImage}).
438 % ==========================================
439 \subsection{\texttt{XML} description of a box}
440 % ==========================================
442 % ==========================================
443 \subsubsection{General \texttt{xml} tags}
444 % ==========================================
446 Let us examine the \texttt{xml} file
447 describing the \texttt{Add} box of the \texttt{std} package :
449 \begin{file}{\texttt{src/packages/std/bbAdd.xml}}
452 <?xml version="1.0" encoding="iso-8859-1"?>
454 <blackbox name="Add">
456 <description> Adds its inputs </description>
457 <author> laurent.guigues@creatis.insa-lyon.fr </author>
458 <package> std </package>
460 <parentblackbox> bbtk::UserBlackBox </parentblackbox>
461 <namespace> bbstd </namespace>
463 <input name="In1" type="double"> First number to add </input>
464 <input name="In2" type="double"> Second number to add </input>
465 <output name="Out" type="double"> Result </output>
468 bbSetOutputOut( bbGetInputIn1() + bbGetInputIn2() );
475 The tags and their role are easily understandable.
477 As the box is not a widget, we inherit from
478 \texttt{bbtk::UserBlackBox} (\texttt{parentblackbox} tag).
480 Note that we decided to include the generated class
481 into the namespace \texttt{bbstd}.
483 The only part of the file which demand a bit of explaination is
484 the body of the \texttt{process} tag, which describes the
485 actual code to execute in the box.
486 This code must be enclosed in a \texttt{<PRE></PRE>} tag
487 to tell the \xml parser not to interpret it as \xml instructions.
488 This is necessary to be able to use any symbol,
489 like the \texttt{<} and \texttt{>} which have a
490 special meaning in \xml.
491 In the case of the \texttt{Add} box, the process code
492 is very simple : remember that
493 \texttt{bbGetInputIn1} is the
494 accessor to the input \texttt{In1} declared above and
495 \texttt{bbGetInputIn2} is the
496 accessor to the input \texttt{In2};
497 the code simply adds the values of the two inputs
498 and sets the output \texttt{Out} with the resulting value.
500 To describe your own black boxes in \xml code,
501 you can use the template \texttt{xml} file
502 \texttt{examples/TEMPLATE\_bbPackagenameBoxname.xml}.
504 If \texttt{MyPack} is the name of your package and
505 \texttt{MyBox} the name of your box, then :
507 \item Copy this file in your package folder with
508 the normalised name \texttt{bbMyPackMyBox.xml}
509 \item Replace each occurrence of \$PACKAGENAME\$ by MyPack
510 and each occurrence of \$BOXNAME\$ by MyBox.
511 \item Fill in the description and author tags
512 \item Create your inputs and outputs
513 \item Fill in the process tag
517 % ==========================================
518 \subsubsection{Specific \texttt{xml} tags for \texttt{itk::ImageToImageFilter} classes bbfication}
519 % ==========================================
521 % ==========================================
522 \subsubsection{Specific \texttt{xml} tags for \texttt{vtkImageAlgorithm} classes bbfication}
523 % ==========================================
525 % ==========================================
526 \subsubsection{Specific \texttt{xml} tags for \texttt{vtkPolyDataAlgorithm} classes bbfication}
527 % ==========================================
529 % ==========================================
530 \subsubsection{\bbfy \texttt{xml} tags reference}
531 % ==========================================
533 % ==========================================
535 \caption{\label{xml_tags}
536 \bbfy \texttt{xml} tags reference}
538 \begin{tabular}{|lcllm{6cm}|}
540 Tag & Attributes & Condition & Multiplicity & Description
543 \texttt{<blackbox>} & \texttt{name} & - & 1 & The name of the box \\ \hline
544 & \texttt{type} & - & 1 & The type of the box. In:
545 \{\texttt{standard} (default),
546 \texttt{itkImageToImageFilter},
547 \texttt{vtkImageAlgorithm},
548 \texttt{vtkPolyDataAlgorithm}\} \\\hline
549 & \texttt{generic} & a) & 0-1 &
550 Generate the generic filter (see text)\\ \hline
552 \texttt{<description>} & - & - & 0-n & The description of the box. Multiple occurrence are concatenated \\\hline
553 \texttt{<author>} & - & - & 0-n & The author of the box. Multiple occurrence are concatenated \\\hline
554 \texttt{<parentblackbox>} & - & - & 1 & The parent black box of the box.
555 In: \{\texttt{bbtk::BlackBox, bbtk::WxBlackBox, bbtk::WxContainerBlackBox}\}\\\hline
556 \texttt{<package>} & - & - & 1 & The package of the box \\\hline
557 \texttt{<namespace>} & - & - & 0-1 & The namespace of the box.
558 Use \texttt{bbPACKAGE}, where \texttt{PACKAGE} is the name of the package\\\hline
559 \texttt{<include>} & - & - & 0-n & Additionnal file to include
560 (generates : \texttt{\#include 'value'})\\\hline
562 \texttt{<template>} & - & - & 0-n & Template parameter of the box. The template parameter list is generated in the order of appearance of the tag. \\\hline
564 \texttt{<itkparent>} & - & a) & 1 & The parent itk class (with namespace) \\\hline
566 \texttt{<vtkparent>} & - & b) & 1 & The parent vtk class \\\hline
568 \texttt{<input>} & \texttt{name} & - & 1 & The name of the input \\\hline
569 & \texttt{type} & - & 1 & The type of the input \\\hline
570 & \texttt{special} & - & 0-1 & In: \{\texttt{``itk input'',
571 ``vtk input'', ``itk parameter'', ``vtk parameter''}\} (see below).\\\hline
572 & \texttt{generic\_type} & c) & 0-1 & The ``generic'' type of the input (see text). \\\hline
573 \texttt{<output>} & \texttt{name} & - & 1 & The name of the output \\\hline
574 & \texttt{type} & - & 1 & The type of the output \\\hline
575 & \texttt{special} & - & 0-1 & In: \{\texttt{``itk output'',
576 ``vtk output''}\} (see below).\\\hline
577 & \texttt{generic\_type} & c) & 0-1 & The ``generic'' type of the output (see text).\\\hline
579 \texttt{<process>} & - & - & 0-1 & The code of the processing method of the box. Must be put between clear tags : \texttt{<PRE></PRE>} \\\hline
584 % ==========================================
586 \caption{\label{xml_tags}
587 \bbfy \texttt{xml} tags conditions}
589 \begin{tabular}{|ll|}
591 a) & \texttt{<blackbox type == ''itkImageToImageFilter''>} \\ \hline
592 b) & \texttt{<blackbox type == ''vtkImageAlgorithm'' or ''vtkPolyDataAlgorithm''>} \\ \hline
593 c) & \texttt{<blackbox type == ''itkImageToImageFilter''>} and
594 \texttt{<blackbox generic>} is present. \\ \hline
599 % ==========================================
600 \subsection{\CPP description of a box}
601 % ==========================================
605 Look at the files \texttt{examples/TEMPLATE\_bbPackagenameBoxname.h/cxx}
606 and \texttt{examples/TEMPLATE\_bbPackagenameWXBoxname.h/cxx}
612 %\section{Conclusion}