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