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