]> Creatis software - bbtk.git/blob - kernel/appli/bbfy/bbfy.cpp
By Leonardo Florez
[bbtk.git] / kernel / appli / bbfy / bbfy.cpp
1 /*
2 # ---------------------------------------------------------------------
3 #
4 # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
5 #                        pour la SantÈ)
6 # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
7 # Previous Authors : Laurent Guigues, Jean-Pierre Roux
8 # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
9 #
10 #  This software is governed by the CeCILL-B license under French law and
11 #  abiding by the rules of distribution of free software. You can  use,
12 #  modify and/ or redistribute the software under the terms of the CeCILL-B
13 #  license as circulated by CEA, CNRS and INRIA at the following URL
14 #  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
15 #  or in the file LICENSE.txt.
16 #
17 #  As a counterpart to the access to the source code and  rights to copy,
18 #  modify and redistribute granted by the license, users are provided only
19 #  with a limited warranty  and the software's author,  the holder of the
20 #  economic rights,  and the successive licensors  have only  limited
21 #  liability.
22 #
23 #  The fact that you are presently reading this means that you have had
24 #  knowledge of the CeCILL-B license and that you accept its terms.
25 # ------------------------------------------------------------------------ */
26
27 #ifdef WIN32
28 #define _CRT_SECURE_NO_DEPRECATE
29 #endif
30
31 #include <stdio.h>
32 #include "bbtkXML.h"
33 #include <iostream>
34 #include <fstream>
35 #include <sstream>
36 #include <vector>
37
38 //==========================================================================
39 class bbfyException
40 {
41 public: 
42   bbfyException(const std::string& message) : mMessage(message) {}
43
44   std::string mMessage;
45 };
46 //==========================================================================
47
48 const std::string itkImageToImageFilterString = "ITK_ImageToImageFilter";
49 const std::string vtkImageAlgorithmString     = "VTK_ImageAlgorithm";
50 const std::string vtkPolyDataAlgorithmString  = "VTK_PolyDataAlgorithm";
51
52 //==========================================================================
53 class bbfy
54 {
55 public:
56   bbfy(const std::string& filename, 
57        const std::string& package = "PACKAGE_NAME",
58        const std::string& output_path = "",
59        bool verbose = false);
60   
61   void CreateBlackBox();
62   void ParseXML();
63   void CreateHeader();
64   void CreateCode();
65
66   void WriteGenericITKFilterHeader();
67
68   void BeginNamespace();
69   void EndNamespace();
70
71 private:
72   //
73   std::string mFilename;
74   std::string mOutputPath;
75   bool mVerbose;
76
77   //
78   std::string mName;
79   typedef enum 
80     {
81       STD,
82       itkImageToImageFilter,
83       vtkImageAlgorithm,
84       vtkPolyDataAlgorithm,
85     }
86     BoxType;
87
88   BoxType mType;
89   bool mIsWidget;
90   std::string mParentBlackBox;
91   std::string mItkParent;
92   std::string mVtkObject;
93   bool mGeneric;
94   std::string mAuthor;
95   std::string mDescription;
96   std::string mCategory;
97   std::string mPackage;
98   // bool mIsInNamespace;
99   std::string mNamespace;
100   // int mNbTemplateParam;
101   std::vector<std::string> mTemplateParam;
102   std::string mTemplateDeclaration;
103   std::string mTemplateImplementation;
104
105   std::vector<std::string> mInclude;
106   std::string mVerbosePreprocessor;
107   std::vector<std::string> mTypedef;
108
109   std::string mUserSetDefaultValues;
110   std::string mUserInitializeProcessing;
111   std::string mUserFinalizeProcessing;
112
113   typedef struct
114   {
115     std::string name;
116     std::string type;
117     std::string nature;
118     std::string descr;
119     std::string special;
120     std::string generic_type;
121   }
122     IO;
123   
124   std::vector<IO> mInput;
125   std::vector<IO> mOutput;
126
127   std::string mProcess;
128   std::string mCreateWidget;
129
130   //
131   std::ofstream mFile;
132   std::string mHName;
133   std::string mCxxName;
134
135   void AlertString();
136
137 };
138 //==========================================================================
139
140
141
142 //==========================================================================
143 bbfy::bbfy(const std::string& filename, 
144            const std::string& package,
145            const std::string& output_path,
146            bool verbose)
147 {
148   mIsWidget = false;
149   
150   mFilename = filename;
151   mPackage = package;
152   mNamespace = "bb" + mPackage;
153
154   mOutputPath = output_path;
155   mVerbose = verbose;
156
157   CreateBlackBox();
158 }
159 //==========================================================================
160
161 //==========================================================================
162 void bbfy::CreateBlackBox()
163 {
164   // Parse XML input file
165   ParseXML();
166   // Create output files
167   CreateHeader();
168   CreateCode();
169 }
170 //==========================================================================
171
172 void bbfy::AlertString()
173 {
174         
175       mFile << "//===== \n";
176       mFile << "// Before editing this file, make sure it's a file of your own ";
177       mFile << "(i.e.: it wasn't generated from xml description; if so : your modifications will be lost)\n";
178       mFile << "//===== \n";
179           
180 }
181
182 //==========================================================================
183 void bbfy::ParseXML()
184 {
185
186
187
188   XMLResults* res = new XMLResults;
189   XMLNode BB = XMLNode::parseFile(mFilename.c_str(),"blackbox",res);
190
191   if ( res->error != eXMLErrorNone ) 
192     {
193       std::ostringstream str;
194       str << XMLNode::getError(res->error);
195       str << " [line " << res->nLine << ", col "<<res->nColumn<<"]"; 
196       delete res;
197       throw bbfyException(str.str());
198     }
199   delete res;
200
201   // Name
202   if (!BB.isAttributeSet("name")) 
203     {
204       throw bbfyException("Error : <blackbox> tag : no 'name' attribute found (mandatory)");
205     }
206   mName = BB.getAttribute("name");
207
208   if (mVerbose) std::cout << "* Creating BlackBox '"<<mName<<"'"<<std::endl;
209
210   // Type 
211   mGeneric = false;
212   mType = STD;
213
214
215   if (BB.isAttributeSet("type")) 
216     {
217       std::string bbtype = BB.getAttribute("type");
218       if (bbtype=="standard")
219         {
220           mGeneric = false;
221           mType = STD;
222         }
223       else if (bbtype==itkImageToImageFilterString)
224         {
225           mType = itkImageToImageFilter;
226           // Looks for <itkparent> tag
227           if (!BB.nChildNode("itkparent")) 
228             {
229               throw bbfyException("Error : blackbox type '"+itkImageToImageFilterString+"' but no <itkparent> tag found (mandatory)");
230             }
231           bbtk::GetTextOrClear(BB.getChildNode("itkparent"),mItkParent);
232           // 
233           mGeneric = false;
234           if (BB.isAttributeSet("generic")) mGeneric=true;
235         }
236       else if (bbtype == vtkImageAlgorithmString)
237         {
238           mType = vtkImageAlgorithm;
239           // Looks for <vtkobject> tag
240           if (!BB.nChildNode("vtkobject")) 
241             {
242               throw bbfyException("Error : blackbox type '"
243                                   +vtkImageAlgorithmString
244                                   +"' but no <vtkobject> tag found (mandatory)");
245             }
246           bbtk::GetTextOrClear(BB.getChildNode("vtkobject"),mVtkObject);
247           // 
248         }
249     else if (bbtype == vtkPolyDataAlgorithmString )
250         {
251           mType = vtkPolyDataAlgorithm;
252           // Looks for <vtkobject> tag
253           if (!BB.nChildNode("vtkobject")) 
254             {
255               throw bbfyException("Error : blackbox type '"
256                                   +vtkPolyDataAlgorithmString
257                                   +"' but no <vtkobject> tag found (mandatory)");
258             }
259           bbtk::GetTextOrClear(BB.getChildNode("vtkobject"),mVtkObject);
260           // 
261         }
262      else 
263         {
264           std::string mess("Error : blackbox type '");
265           mess += bbtype;
266           mess += "' unknown. Known types :";
267           mess += "'" + itkImageToImageFilterString + "' ";
268           mess += "'" + vtkImageAlgorithmString + "' ";
269           mess += "'" + vtkPolyDataAlgorithmString + "' ";
270           throw bbfyException(mess);
271         }
272     }
273
274   // Is a widget box ?
275   if (BB.isAttributeSet("widget")) 
276     {
277       mIsWidget = true;
278       mParentBlackBox = "bbtk::WxBlackBox";
279       mInclude.push_back("bbtkWxBlackBox.h");
280     }
281   else 
282     {
283       mIsWidget = false;
284       mParentBlackBox = "bbtk::AtomicBlackBox";
285       mInclude.push_back("bbtkAtomicBlackBox.h");
286     }
287
288   // Author
289   int i,j;
290   for (i=0,j=0; i<BB.nChildNode("author"); i++) 
291     {
292       std::string val;
293       bbtk::GetTextOrClear(BB.getChildNode("author",&j),val);
294       mAuthor += val;
295     }
296
297   // Verbose preprocessor
298   for (i=0,j=0; i<BB.nChildNode("verbosePreprocessor"); i++) 
299   {
300     std::string val;
301     bbtk::GetTextOrClear(BB.getChildNode("verbosePreprocessor",&j),val);
302     mVerbosePreprocessor += val + "\n";
303   }
304
305   // Description
306   for (i=0,j=0; i<BB.nChildNode("description"); i++) 
307     {
308       std::string val;
309       bbtk::GetTextOrClear(BB.getChildNode("description",&j),val);
310       mDescription += val;
311     }
312   
313   // Category
314   for (i=0,j=0; i<BB.nChildNode("category"); i++) 
315     {
316       std::string val;
317       bbtk::GetTextOrClear(BB.getChildNode("category",&j),val);
318       mCategory += val;
319     }
320
321   // Namespace
322   if (BB.nChildNode("namespace"))
323     {
324       bbtk::GetTextOrClear(BB.getChildNode("namespace"),mNamespace);
325     }
326
327   // UserSetDefaultValues body
328   if (BB.nChildNode("defaultValues"))
329     {
330       bbtk::GetTextOrClear(BB.getChildNode("defaultValues"),
331                            mUserSetDefaultValues);
332     }
333     
334   // UserInitializeProcessing body
335   if (BB.nChildNode("initializeProcessing"))
336     {
337       bbtk::GetTextOrClear(BB.getChildNode("initializeProcessing"),
338                            mUserInitializeProcessing);
339     }
340     
341  // UserFinalizeProcessing body
342   if (BB.nChildNode("finalizeProcessing"))
343     {
344       bbtk::GetTextOrClear(BB.getChildNode("finalizeProcessing"),
345                            mUserFinalizeProcessing);
346     }
347
348
349
350      // Template parameters
351   //  mNbTemplateParam = BB.nChildNode("template");
352
353   if ( BB.nChildNode("template") > 0)
354     {
355       mTemplateDeclaration = "<";
356       mTemplateImplementation = "<";
357       
358       for (i=0,j=0; i<BB.nChildNode("template")-1; i++) 
359         {
360           mTemplateDeclaration += "class ";
361           std::string val;
362           bbtk::GetTextOrClear(BB.getChildNode("template",&j),val);
363           mTemplateDeclaration += val;
364           mTemplateDeclaration +=  ",";
365           mTemplateImplementation += val;
366           mTemplateImplementation +=  ",";
367           mTemplateParam.push_back(val);
368         }
369       mTemplateDeclaration += "class ";
370       std::string val;
371       bbtk::GetTextOrClear(BB.getChildNode("template",&j),val);
372       mTemplateDeclaration += val;
373       mTemplateDeclaration +=  ">";
374       mTemplateImplementation += val;
375       mTemplateImplementation +=  ">";
376       mTemplateParam.push_back(val);
377     }
378
379   // Includes 
380   for (i=0,j=0; i<BB.nChildNode("include"); i++) 
381     {
382       std::string val;
383       bbtk::GetTextOrClear(BB.getChildNode("include",&j),val);
384       mInclude.push_back(val);
385     }
386   // Typedef
387   for (i=0,j=0; i<BB.nChildNode("typedef"); i++) 
388     {
389       std::string val;
390       bbtk::GetTextOrClear(BB.getChildNode("typedef",&j),val);
391       mTypedef.push_back(val);
392     }
393   
394   // Inputs
395   for (i=0,j=0; i<BB.nChildNode("input"); i++) 
396     {
397       IO io;
398       XMLNode n = BB.getChildNode("input",&j); 
399       if (!n.isAttributeSet("name"))
400         {
401           throw bbfyException("Error : <input> attribute 'name' not found (mandatory)");
402         }
403       io.name = n.getAttribute("name");
404       if (!n.isAttributeSet("type"))
405         {
406           throw bbfyException("Error : <input name=\""+io.name+"\"> attribute 'type' not found (mandatory)");
407         }
408       io.type = n.getAttribute("type"); 
409       if (!n.isAttributeSet("description"))
410         {
411           throw bbfyException("Error : <input name=\""+io.name+"\"> attribute 'description' not found (mandatory)");
412         }
413       io.descr = n.getAttribute("description"); 
414
415       if (n.isAttributeSet("special")) 
416         {
417           io.special =  n.getAttribute("special");  
418         }
419
420       if (n.isAttributeSet("nature")) 
421         {
422           io.nature =  n.getAttribute("nature");  
423         }
424
425       if (n.isAttributeSet("generic_type")) 
426         {
427           io.generic_type =  n.getAttribute("generic_type");  
428         }
429
430       mInput.push_back(io);
431     }
432   
433   // Outputs
434   for (i=0,j=0; i<BB.nChildNode("output"); i++) 
435     {
436       IO io;
437       XMLNode n = BB.getChildNode("output",&j); 
438       if (!n.isAttributeSet("name"))
439         {
440           throw bbfyException("Error : <output> attribute 'name' not found (mandatory)");
441         }
442       io.name = n.getAttribute("name"); 
443       if (!n.isAttributeSet("type"))
444         {
445           throw bbfyException("Error : <output name=\""+io.name+"\"> attribute 'type' not found (mandatory)");
446         }
447       io.type = n.getAttribute("type"); 
448       if (!n.isAttributeSet("description"))
449         {
450           throw bbfyException("Error : <output name=\""+io.name+"\"> attribute 'description' not found (mandatory)");
451         }
452       io.descr = n.getAttribute("description"); 
453
454       if (n.isAttributeSet("special")) 
455         {
456           io.special =  n.getAttribute("special");  
457         }
458
459       if (n.isAttributeSet("nature")) 
460         {
461           io.nature =  n.getAttribute("nature");  
462         }
463
464       if (n.isAttributeSet("generic_type")) 
465         {
466           io.generic_type =  n.getAttribute("generic_type");  
467         }
468
469       mOutput.push_back(io);
470     }
471
472
473   // Process
474   // process tag given ?
475    if (BB.nChildNode("process"))
476      {
477                  bbtk::GetTextOrClear(BB.getChildNode("process"),mProcess);
478      }
479      
480   // CreateWidget
481   // createwidget tag given ?
482    if (BB.nChildNode("createwidget"))
483      {
484        bbtk::GetTextOrClear(BB.getChildNode("createwidget"),mCreateWidget);
485      }
486
487
488
489
490
491
492
493    // OBSOLETE/UNSUPPORTED TAGS
494   // WARN IF OBSOLETE TAGS PROVIDED
495   if (BB.nChildNode("constructor"))
496     {
497       std::cout << "WARNING !!! The tag <constructor> is obsolete !!"<<std::endl;
498     }
499   if (BB.nChildNode("destructor"))
500     {
501       std::cout << "WARNING !!! The tag <destructor> is obsolete !!"<<std::endl;
502     }
503   if (BB.nChildNode("copy_constructor"))
504     {
505       std::cout << "WARNING !!! The tag <copy_constructor> is obsolete !!"<<std::endl;
506     }
507
508
509
510 }
511 //==========================================================================
512
513
514 //==========================================================================
515 void bbfy::BeginNamespace()
516 {
517   //  if (mIsInNamespace)
518   // {
519   mFile << "namespace "<<mNamespace <<"\n{\n\n";
520   //  }
521 }
522 //==========================================================================
523
524 //==========================================================================
525 void bbfy::EndNamespace()
526 {
527   // if (mIsInNamespace)
528   //  {
529   mFile << "}\n// EO namespace "<<mNamespace<<"\n\n";
530   //  }
531 }
532 //==========================================================================
533
534
535 //==========================================================================
536 void bbfy::CreateHeader()
537 {
538
539   mHName = "bb";
540   mHName += mPackage;
541   mHName += mName;
542   mHName += ".h";
543   if (mVerbose) std::cout << " - Creating header '"<<mHName<<"'"<<std::endl;
544   std::string fullname = mOutputPath + mHName;
545   mFile.open(fullname.c_str());
546   if (!mFile.good())
547     {
548       std::string mess("Error : could not open file \"");
549       mess += fullname + "\"";
550       throw bbfyException(mess);
551     }
552
553         AlertString();
554
555   // If is widget 
556   if (mIsWidget)
557     {
558       mFile << "#ifdef _USE_WXWIDGETS_\n";
559     }
560
561   // Prevent multiple inclusions
562   std::string included("__bb");
563   included += mPackage + mName + "_h_INCLUDED__";
564   mFile << "#ifndef " << included <<"\n";
565   mFile << "#define " << included <<"\n";
566
567   // Verbose preprocessor
568   mFile << mVerbosePreprocessor << "\n";
569
570   // Includes 
571   mFile << "#include \"bb" << mPackage << "_EXPORT.h\"\n";
572   std::vector<std::string>::iterator i;
573   for (i=mInclude.begin(); i!=mInclude.end(); ++i) 
574     {
575       mFile << "#include \"" << *i <<"\"\n";
576     }
577   if (mGeneric) mFile << "#include \"bbitkImage.h\"\n";
578   mFile << "\n";
579
580   if (mType == itkImageToImageFilter )
581     {
582       mFile << "#include \"bbtkItkBlackBoxMacros.h\"\n";
583     }
584   else if ( (mType == vtkImageAlgorithm) ||
585             (mType == vtkPolyDataAlgorithm) )
586     {
587       mFile << "#include \"bbtkVtkBlackBoxMacros.h\"\n";
588     }
589   // Namespace
590   BeginNamespace();
591
592   // Interface
593
594   // If it is a template class
595   if (mTemplateParam.size() > 0)
596     {
597       mFile << "template " << mTemplateDeclaration <<"\n";
598     }
599   
600   // Class declaration and parents
601   mFile << "class bb"<<mPackage<<"_EXPORT "<<mName<<"\n";
602   mFile << " : \n";
603
604   /*
605   if (mBB.nChildNode("inherits"))
606     {
607       mFile << ",\n";
608       for (i=0,j=0; i<mBB.nChildNode("inherits")-1; i++) 
609         {
610           mFile << "   public " 
611                 << mBB.getChildNode("inherits",&j).getText()
612                 << ",\n";
613         }
614       mFile << "   public " 
615             << mBB.getChildNode("Inherits",&j).getText()
616             <<"\n";
617     }
618   */
619
620   if (mType == itkImageToImageFilter )
621     {
622       mFile << "   public " << mItkParent <<",\n";
623     }
624
625   mFile << "   public "<<mParentBlackBox << "\n";
626
627   mFile << "{\n";
628
629   // Interface
630
631   // ITK 
632   if (mType == itkImageToImageFilter)
633     {
634       mFile << "  BBTK_ITK_BLACK_BOX_INTERFACE("
635             << mName << ","
636             << mParentBlackBox << ","
637             << mItkParent 
638             << ");\n";
639     }
640   // VTK
641   else if ( (mType == vtkImageAlgorithm) ||
642        (mType == vtkPolyDataAlgorithm) )
643     {
644       mFile << "  BBTK_VTK_BLACK_BOX_INTERFACE("
645             << mName << ","
646             << mParentBlackBox << ","
647             << mVtkObject
648             << ");\n";
649     }
650         
651   // Default
652   else 
653     {
654       mFile << "  BBTK_BLACK_BOX_INTERFACE("
655             << mName << ","
656             << mParentBlackBox << ");\n";
657     }
658
659   for (i=mTypedef.begin(); i!=mTypedef.end(); ++i) 
660     {
661       mFile << *i <<"\n";
662     }
663
664
665         AlertString();
666
667   // Inputs
668   std::vector<IO>::iterator ioi;
669   for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi) 
670     {
671       if (ioi->special=="") 
672         {
673           mFile << "  BBTK_DECLARE_INPUT(" 
674                 << ioi->name
675                 << ","
676                 << ioi->type
677                 << ");\n";
678         }
679       else if (ioi->special=="itk input")
680         {
681           mFile << "  BBTK_DECLARE_ITK_INPUT(" 
682                 << ioi->name
683                 << ","
684                 << ioi->type
685                 << ");\n";
686         }
687       else if (ioi->special=="vtk input")
688         {
689           if (mType == vtkImageAlgorithm) {
690           mFile << "  BBTK_DECLARE_VTK_IMAGE_ALGORITHM_INPUT(" 
691                 << ioi->name
692                 << ","
693                 << ioi->type
694                 << ");\n";
695           } 
696           else if (mType == vtkPolyDataAlgorithm) {
697           mFile << "  BBTK_DECLARE_POLY_DATA_ALGORITHM_INPUT(" 
698                 << ioi->name
699                 << ","
700                 << ioi->type
701                 << ");\n";
702           }
703         }
704       else if (ioi->special=="itk parameter")
705         {
706           mFile << "  BBTK_DECLARE_ITK_PARAM(" 
707                 << ioi->name
708                 << ","
709                 << ioi->type
710                 << ");\n";
711         }
712       else if (ioi->special=="vtk parameter")
713         {
714           mFile << "  BBTK_DECLARE_VTK_PARAM(" 
715                 << ioi->name
716                 << ","
717                 << ioi->type
718                 << ");\n";
719         }
720       else 
721         {
722           std::string mess("Error : input '");
723           mess += ioi->name;
724           mess += "', 'special' attribute '";
725           mess += ioi->special;
726           mess += "' unknown";
727           throw bbfyException(mess);
728         }
729     }
730
731   
732   // Outputs
733   for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi) 
734     {
735       if (ioi->special=="") 
736         {
737           mFile << "  BBTK_DECLARE_OUTPUT(" 
738                 << ioi->name
739                 << ","
740                 << ioi->type
741                 << ");\n";
742         }
743       else if (ioi->special=="itk output")
744         {
745           mFile << "  BBTK_DECLARE_ITK_OUTPUT(" 
746                 << ioi->name
747                 << ","
748                 << ioi->type
749                 << ");\n";
750         }  
751       else if (ioi->special=="vtk output")
752         {
753           mFile << "  BBTK_DECLARE_VTK_OUTPUT(" 
754                 << ioi->name
755                 << ","
756                 << ioi->type
757                 << ");\n";
758         }  
759       else 
760         {
761           std::string mess("Error : output '");
762           mess += ioi->name;
763           mess += "', 'special' attribute '";
764           mess += ioi->special;
765           mess += "' unknown";
766           throw bbfyException(mess);
767         }
768     }
769   
770   // Process
771   if ((mType == STD)||(mProcess.size()))
772     {
773       mFile << "  BBTK_PROCESS(Process);\n" ;
774       mFile << "  void Process();\n";
775     }
776   else if (mType == itkImageToImageFilter)
777     {   
778       mFile << "  BBTK_ITK_PROCESS();\n" ;
779     }
780   else if ((mType == vtkImageAlgorithm) ||
781            (mType == vtkPolyDataAlgorithm) )
782
783     {   
784       mFile << "  BBTK_VTK_PROCESS();\n" ;
785     }
786
787   // CreateWidget
788   if (mIsWidget) 
789     {
790        mFile << "  BBTK_CREATE_WIDGET(CreateWidget);\n" ;
791        mFile << "  void CreateWidget(wxWindow*);\n";
792     }
793
794         AlertString();
795
796   // EO black box declaration
797   mFile << "};\n\n";
798
799   // BO black box description
800   if (mTemplateParam.size()==0)
801     {
802       mFile << "BBTK_BEGIN_DESCRIBE_BLACK_BOX("
803             << mName << ","
804             << mParentBlackBox << ");\n";
805       mFile << "BBTK_NAME(\"" << mName <<"\");\n";
806     }
807   else if (mTemplateParam.size()==1)
808     {
809       mFile << "BBTK_BEGIN_DESCRIBE_TEMPLATE_BLACK_BOX("
810             << mName //<< ","
811         //<< mParentBlackBox //<< ","
812         //   << mTemplateParam[0] 
813             << ");\n";
814       mFile << "BBTK_NAME(\"" << mName 
815             << "<\"+bbtk::TypeName<" << mTemplateParam[0]
816             <<">()+\">\");\n";
817     }
818  else 
819     {
820       throw bbfyException("template bb with more than 1 templ param not impl");
821     } 
822
823
824   // Author
825   mFile << "BBTK_AUTHOR(\""<<mAuthor<< "\");\n";
826
827   // Description
828   mFile << "BBTK_DESCRIPTION(\""<<mDescription<< "\");\n"; 
829   
830   // Category
831   mFile << "BBTK_CATEGORY(\""<<mCategory<< "\");\n"; 
832
833   for (i=mTypedef.begin(); i!=mTypedef.end(); ++i) 
834     {
835       mFile << *i <<"\n";
836     }
837   
838   // Inputs
839   for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi) 
840     {
841       if (mTemplateParam.size()>0)
842         {
843           mFile << "BBTK_TEMPLATE_INPUT(";
844         } 
845       else 
846         {
847           mFile << "BBTK_INPUT(";
848         } 
849       mFile << mName << "," << ioi->name << ",\""
850             << ioi->descr << "\"," <<  ioi->type << ",\"" 
851             << ioi->nature<<"\");\n";
852     }
853   
854   // Outputs
855   for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi) 
856     {
857       if (mTemplateParam.size()>0)
858         {
859           mFile << "BBTK_TEMPLATE_OUTPUT(";
860         } 
861       else 
862         {
863           mFile << "BBTK_OUTPUT(";
864         } 
865       mFile << mName << "," << ioi->name << ",\""
866             << ioi->descr << "\"," <<  ioi->type << ",\"" 
867             << ioi->nature<<"\");\n";
868     }
869   
870   // EO black box description
871   if (mTemplateParam.size()==0)
872     {
873       mFile << "BBTK_END_DESCRIBE_BLACK_BOX("
874             << mName << ");\n";
875     }
876   else if (mTemplateParam.size()==1)
877     {
878       mFile << "BBTK_END_DESCRIBE_TEMPLATE_BLACK_BOX("
879             << mName //<< ","
880         // << mTemplateParam[0] 
881             << ");\n";
882     }
883   else 
884     {
885       throw bbfyException("template bb with more than 1 templ param not impl");
886      
887     } 
888   
889   // Untemplatization of itk filters
890   if ( mGeneric )
891     {
892       WriteGenericITKFilterHeader();
893     }
894
895         AlertString();
896
897   // EO namespace
898   EndNamespace();
899   
900   // Prevent multiple inclusions
901   mFile << "#endif // " << included <<"\n";
902   // If is widget 
903   if (mIsWidget)
904     {
905       mFile << "#endif // _USE_WXWIDGETS_\n";
906     }
907
908   // EOF
909   mFile << "\n";
910
911   mFile.close();
912 }
913 //==========================================================================
914
915
916
917 //==========================================================================
918 void bbfy::WriteGenericITKFilterHeader()
919 {
920   mFile << "\n//===================================================\n";
921   mFile << "// Generic \"untemplatized\" filter\n";
922   mFile << "//===================================================\n";
923
924   // Class declaration and parents
925   mFile << "class /*BBTK_EXPORT*/ "<<mName<<"Generic\n";
926   mFile << " : \n";
927   mFile << "   public bbtk::AtomicBlackBox\n";
928   mFile << "{\n";
929
930   // Interface
931   mFile << "  BBTK_BLACK_BOX_INTERFACE("
932         << mName << "Generic,bbtk::AtomicBlackBox);\n";
933
934   // Inputs
935   std::vector<IO>::iterator ioi;
936   for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi) 
937     {
938       mFile << "  BBTK_DECLARE_INPUT(" 
939             << ioi->name
940             << ","
941             << ioi->generic_type
942             << ");\n";
943     }
944   
945   // Outputs
946   for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi) 
947     {
948       mFile << "  BBTK_DECLARE_OUTPUT(" 
949             << ioi->name
950             << ","
951             << ioi->generic_type
952             << ");\n";
953     }
954     
955   // Process
956   mFile << "  BBTK_PROCESS(ProcessSwitch);\n";
957   mFile << "  private :\n";
958   mFile << "    inline void ProcessSwitch();\n";
959   mFile << "    template <class T, unsigned int D> void Process();\n";
960   // EO black box declaration
961   mFile << "};\n\n";
962
963
964
965   // BO black box description
966   mFile << "BBTK_BEGIN_DESCRIBE_BLACK_BOX("
967         << mName << "Generic,bbtk::AtomicBlackBox);\n";
968   mFile << "BBTK_NAME(\"" << mName <<"\");\n";
969
970   // Author
971   mFile << "BBTK_AUTHOR(\""<<mAuthor<< "\");\n";
972
973   // Description
974   mFile << "BBTK_DESCRIPTION(\""<<mDescription<< "\");\n"; 
975   
976   // Inputs
977   for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi) 
978     {
979       mFile << "BBTK_INPUT(";
980       mFile << mName << "Generic," << ioi->name << ",\""
981             << ioi->descr << "\"," <<  ioi->generic_type <<");\n";
982     }
983   
984   // Outputs
985   for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi) 
986     {
987       mFile << "BBTK_OUTPUT(";
988       mFile << mName << "Generic," << ioi->name << ",\""
989             << ioi->descr << "\"," <<  ioi->generic_type <<");\n";
990     }
991   
992   // EO black box description
993   mFile << "BBTK_END_DESCRIBE_BLACK_BOX("
994         << mName << "Generic);\n";
995
996
997   //=================================================================
998   // ProcessSwitch implementation
999   mFile << "void "<< mName <<"Generic::ProcessSwitch()\n"
1000         << "{\n"
1001         << "CALL_FOR_ALL_TYPES_AND_DIM(bbGetInputIn()->GetType(),\n"
1002         << "                           bbGetInputIn()->GetDimension(),\n"
1003         << "                           Process);\n"
1004         << "}\n";
1005   //=================================================================
1006
1007
1008   //=================================================================
1009   // Template process implementation
1010   mFile << "template <class T, unsigned int D>\n"
1011         << "void "<<mName<<"Generic::Process()\n"
1012         << "{\n"
1013         << "  bbtkDebugMessageInc(\"Kernel\",9,\n"
1014         << "      \""<<mName 
1015         << "Generic::Process<\"<<TypeName<T>()<<\",\"<<D<<\">()\"<<std::endl);\n"
1016     
1017         << "  typedef itk::Image<T,D> ImageType;\n"
1018         << "  typedef "<<mName<<"<ImageType> FilterType;\n"
1019     
1020         << "  FilterType* f = new FilterType(\"Temp\");\n"
1021     
1022         << "  f->bbSetInputIn( this->bbGetInputIn()->GetImage<T,D>() );\n";
1023   
1024   for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi) 
1025     {
1026       if (ioi->name == "In") continue;
1027       mFile << "  f->bbSetInput"<<ioi->name<<" ( this->bbGetInput" 
1028             << ioi->name << "() );\n";
1029     }
1030   
1031   mFile << "  f->bbUpdate();\n"
1032         << "  this->bbSetOutputOut( new itkImage( f->bbGetOutputOut() ) );\n"
1033         << "  f->UnRegister();\n"
1034         << "  bbtkDebugDecTab(\"Kernel\",9);\n"
1035         << "}\n\n";
1036   //=================================================================
1037
1038
1039 }
1040 //==========================================================================
1041
1042
1043 //==========================================================================
1044 void bbfy::CreateCode()
1045 {
1046   mCxxName = "bb";
1047   mCxxName += mPackage;
1048   mCxxName += mName;
1049   mCxxName += ".cxx";
1050   if (mVerbose) std::cout << " - Creating code   '"<<mCxxName<<"'"<<std::endl;
1051   std::string fullname = mOutputPath + mCxxName;
1052   mFile.open(fullname.c_str());
1053   if (!mFile.good()) 
1054     {
1055       std::string mess("Error : could not open file \"");
1056       mess += fullname;
1057       mess += "\"";
1058       throw bbfyException(mess);
1059     }
1060
1061         AlertString();
1062
1063
1064   // Includes
1065   // Header of the class
1066   mFile << "#include \"" << mHName << "\"\n";
1067
1068   // Include Package header
1069   mFile << "#include \"bb"<<mPackage << "Package.h\"\n";
1070
1071   // BO namespace
1072   BeginNamespace();
1073  
1074   
1075   // Template class ?
1076   if (mTemplateParam.size()>0) 
1077     {
1078       // Implementation
1079       mFile << "BBTK_BLACK_BOX_TEMPLATE_IMPLEMENTATION("
1080             << mName << ","  
1081             << mParentBlackBox << ");\n";
1082      
1083       if (mGeneric) 
1084         {       
1085           // Implementation
1086           mFile << "BBTK_BLACK_BOX_IMPLEMENTATION("
1087                 << mName << "Generic,bbtk::AtomicBlackBox);\n";
1088           // Package
1089           mFile << "BBTK_ADD_BLACK_BOX_TO_PACKAGE("
1090                 << mPackage << ","
1091                 << mName << "Generic)\n";
1092         }
1093     }
1094   else 
1095     {
1096       // Non template class
1097       // Package
1098       mFile << "BBTK_ADD_BLACK_BOX_TO_PACKAGE("
1099             << mPackage << ","
1100             << mName << ")\n";
1101
1102       // Implementation
1103       mFile << "BBTK_BLACK_BOX_IMPLEMENTATION("
1104             << mName << ","  
1105             << mParentBlackBox << ");\n"; 
1106     }
1107   // Process
1108   if ((mType == STD)||(mProcess.size()))
1109     {
1110         AlertString();
1111       mFile << "void "<<mName<<"::Process()\n{\n";
1112       mFile << mProcess << "\n";
1113       mFile << "}\n";
1114     }
1115   // CreateWidget
1116   if (mIsWidget)
1117     {
1118         AlertString();
1119       mFile << "void "<<mName<<"::CreateWidget(wxWindow* parent)\n{\n";
1120       mFile << mCreateWidget << "\n";
1121       mFile << "}\n";
1122     }
1123
1124                 
1125   // User Set Default Values  
1126         AlertString();
1127   mFile <<"void "<<mName<<"::bbUserSetDefaultValues()"<<std::endl;
1128   mFile << "{"<<std::endl;  
1129         if ( (mType == vtkImageAlgorithm) || (mType == vtkPolyDataAlgorithm) )
1130         {
1131                 mFile << "   BBTK_VTK_SET_DEFAULT_VALUES();\n";
1132         }
1133         mFile << mUserSetDefaultValues << std::endl;
1134   mFile << "}" << std::endl;
1135
1136   // User Initialize Processing
1137         AlertString();
1138   mFile <<"void "<<mName<<"::bbUserInitializeProcessing()"
1139         <<std::endl;
1140   mFile << "{"<<std::endl;
1141         if ( (mType == vtkImageAlgorithm) || (mType == vtkPolyDataAlgorithm) )
1142         {
1143                 mFile <<  "  BBTK_VTK_INITIALIZE_PROCESSING();\n";
1144         }
1145         mFile << mUserInitializeProcessing << std::endl;
1146   mFile << "}" << std::endl;
1147
1148         // User Finalize Processing
1149         AlertString();
1150   mFile <<"void "<<mName<<"::bbUserFinalizeProcessing()"<<std::endl;
1151   mFile << "{"<<std::endl;
1152         if ( (mType == vtkImageAlgorithm) || (mType == vtkPolyDataAlgorithm) )
1153         {
1154                 mFile << "   BBTK_VTK_FINALIZE_PROCESSING();\n";
1155         }
1156         mFile << mUserFinalizeProcessing << std::endl;
1157   mFile << "}" << std::endl;
1158
1159
1160   // EO namespace
1161   EndNamespace();
1162
1163   mFile << "\n";
1164   
1165   // EOF
1166   mFile.close();
1167   
1168 }
1169 //==========================================================================
1170  
1171
1172
1173
1174
1175 //==========================================================================
1176 int main(int argc, char **argv)
1177 {
1178   
1179   if (argc<2 || argc>5) 
1180     {
1181       std::cerr << "usage : "<< argv[0] <<" xml_file [package_name] [output_path] [-q]" << std::endl;
1182       return 1;
1183     }
1184
1185   try 
1186     {
1187       std::string package("PACKAGE_NAME");
1188       std::string output_path("");
1189       bool verbose = true;
1190       if (argc>2) package = argv[2];
1191       if (argc>3) output_path = argv[3];
1192       if (argc>4) verbose = false;
1193       
1194       bbfy B(argv[1],package,output_path,verbose);
1195     }
1196   catch (bbfyException e)
1197     {
1198       std::cerr << argv[0] << "  " << argv[1] << std::endl
1199                 << e.mMessage << std::endl;
1200       return 1;
1201     }
1202   return 0;
1203 }
1204 //==========================================================================
1205
1206