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