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