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