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