]> Creatis software - bbtk.git/blob - kernel/appli/bbfy/bbfy.cpp
d528eb916e4e5ae60a104655e136064b33f67a44
[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   else if ( (mType == vtkImageAlgorithm) ||
572             (mType == vtkPolyDataAlgorithm) )
573     {
574       mFile << "   public " << mVtkParent <<",\n";
575     }
576
577   mFile << "   public "<<mParentBlackBox << "\n";
578
579   mFile << "{\n";
580
581   // Interface
582
583   // ITK 
584   if (mType == itkImageToImageFilter)
585     {
586       mFile << "  BBTK_ITK_BLACK_BOX_INTERFACE("
587             << mName << ","
588             << mParentBlackBox << ","
589             << mItkParent 
590             << ");\n";
591     }
592   // VTK
593   else if ( (mType == vtkImageAlgorithm) ||
594        (mType == vtkPolyDataAlgorithm) )
595     {
596       mFile << "  BBTK_VTK_BLACK_BOX_INTERFACE("
597             << mName << ","
598             << mParentBlackBox << ","
599             << mVtkParent 
600             << ");\n";
601     }
602   // Default
603   else 
604     {
605       mFile << "  BBTK_BLACK_BOX_INTERFACE("
606             << mName << ","
607             << mParentBlackBox << ");\n";
608     }
609
610   for (i=mTypedef.begin(); i!=mTypedef.end(); ++i) 
611     {
612       mFile << *i <<"\n";
613     }
614
615   // Declare user constructor / copy cons /destr 
616   /*
617   mFile << "//=================================================================="<<std::endl;
618   mFile << "/// User callback called in the box contructor"<<std::endl;
619
620   mFile << "virtual void bbUserConstructor();"<<std::endl;
621   mFile << "/// User callback called in the box copy constructor"<<std::endl;
622   mFile << "virtual void bbUserCopyConstructor(bbtk::BlackBox::Pointer);"<<std::endl;
623   mFile << "/// User callback called in the box destructor"<<std::endl;
624   mFile << "virtual void bbUserDestructor();"<<std::endl;
625   mFile << "//=================================================================="<<std::endl; 
626
627   */
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   // Outputs
694   for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi) 
695     {
696       if (ioi->special=="") 
697         {
698           mFile << "  BBTK_DECLARE_OUTPUT(" 
699                 << ioi->name
700                 << ","
701                 << ioi->type
702                 << ");\n";
703         }
704       else if (ioi->special=="itk output")
705         {
706           mFile << "  BBTK_DECLARE_ITK_OUTPUT(" 
707                 << ioi->name
708                 << ","
709                 << ioi->type
710                 << ");\n";
711         }  
712       else if (ioi->special=="vtk output")
713         {
714           mFile << "  BBTK_DECLARE_VTK_OUTPUT(" 
715                 << ioi->name
716                 << ","
717                 << ioi->type
718                 << ");\n";
719         }  
720       else 
721         {
722           std::string mess("Error : output '");
723           mess += ioi->name;
724           mess += "', 'special' attribute '";
725           mess += ioi->special;
726           mess += "' unknown";
727           throw bbfyException(mess);
728         }
729     }
730   
731   // Process
732   if ((mType == STD)||(mProcess.size()))
733     {
734       mFile << "  BBTK_PROCESS(Process);\n" ;
735       mFile << "  void Process();\n";
736     }
737   else if (mType == itkImageToImageFilter)
738     {   
739       mFile << "  BBTK_ITK_PROCESS();\n" ;
740     }
741   else if ((mType == vtkImageAlgorithm) ||
742            (mType == vtkPolyDataAlgorithm) )
743
744     {   
745       mFile << "  BBTK_VTK_PROCESS();\n" ;
746     }
747
748   // CreateWidget
749   if (mIsWidget) 
750     {
751        mFile << "  BBTK_CREATE_WIDGET(CreateWidget);\n" ;
752        mFile << "  void CreateWidget(wxWindow*);\n";
753     }
754
755
756   // EO black box declaration
757   mFile << "};\n\n";
758
759   // BO black box description
760   if (mTemplateParam.size()==0)
761     {
762       mFile << "BBTK_BEGIN_DESCRIBE_BLACK_BOX("
763             << mName << ","
764             << mParentBlackBox << ");\n";
765       mFile << "BBTK_NAME(\"" << mName <<"\");\n";
766     }
767   else if (mTemplateParam.size()==1)
768     {
769       mFile << "BBTK_BEGIN_DESCRIBE_TEMPLATE_BLACK_BOX("
770             << mName //<< ","
771         //<< mParentBlackBox //<< ","
772         //   << mTemplateParam[0] 
773             << ");\n";
774       mFile << "BBTK_NAME(\"" << mName 
775             << "<\"+bbtk::TypeName<" << mTemplateParam[0]
776             <<">()+\">\");\n";
777     }
778  else 
779     {
780       throw bbfyException("template bb with more than 1 templ param not impl");
781     } 
782   
783   // Author
784   mFile << "BBTK_AUTHOR(\""<<mAuthor<< "\");\n";
785
786   // Description
787   mFile << "BBTK_DESCRIPTION(\""<<mDescription<< "\");\n"; 
788   
789   // Category
790   mFile << "BBTK_CATEGORY(\""<<mCategory<< "\");\n"; 
791
792   for (i=mTypedef.begin(); i!=mTypedef.end(); ++i) 
793     {
794       mFile << *i <<"\n";
795     }
796   
797   // Inputs
798   for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi) 
799     {
800       if (mTemplateParam.size()>0)
801         {
802           mFile << "BBTK_TEMPLATE_INPUT(";
803         } 
804       else 
805         {
806           mFile << "BBTK_INPUT(";
807         } 
808       mFile << mName << "," << ioi->name << ",\""
809             << ioi->descr << "\"," <<  ioi->type << ",\"" 
810             << ioi->nature<<"\");\n";
811     }
812   
813   // Outputs
814   for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi) 
815     {
816       if (mTemplateParam.size()>0)
817         {
818           mFile << "BBTK_TEMPLATE_OUTPUT(";
819         } 
820       else 
821         {
822           mFile << "BBTK_OUTPUT(";
823         } 
824       mFile << mName << "," << ioi->name << ",\""
825             << ioi->descr << "\"," <<  ioi->type << ",\"" 
826             << ioi->nature<<"\");\n";
827     }
828   
829   // EO black box description
830   if (mTemplateParam.size()==0)
831     {
832       mFile << "BBTK_END_DESCRIBE_BLACK_BOX("
833             << mName << ");\n";
834     }
835   else if (mTemplateParam.size()==1)
836     {
837       mFile << "BBTK_END_DESCRIBE_TEMPLATE_BLACK_BOX("
838             << mName //<< ","
839         // << mTemplateParam[0] 
840             << ");\n";
841     }
842   else 
843     {
844       throw bbfyException("template bb with more than 1 templ param not impl");
845      
846     } 
847   
848   // Untemplatization of itk filters
849   if ( mGeneric )
850     {
851       WriteGenericITKFilterHeader();
852     }
853
854
855   // EO namespace
856   EndNamespace();
857   
858   // Prevent multiple inclusions
859   mFile << "#endif // " << included <<"\n";
860   // If is widget 
861   if (mIsWidget)
862     {
863       mFile << "#endif // _USE_WXWIDGETS_\n";
864     }
865
866   // EOF
867   mFile << "\n";
868
869   mFile.close();
870 }
871 //==========================================================================
872
873
874
875 //==========================================================================
876 void bbfy::WriteGenericITKFilterHeader()
877 {
878   mFile << "\n//===================================================\n";
879   mFile << "// Generic \"untemplatized\" filter\n";
880   mFile << "//===================================================\n";
881
882   // Class declaration and parents
883   mFile << "class /*BBTK_EXPORT*/ "<<mName<<"Generic\n";
884   mFile << " : \n";
885   mFile << "   public bbtk::AtomicBlackBox\n";
886   mFile << "{\n";
887
888   // Interface
889   mFile << "  BBTK_BLACK_BOX_INTERFACE("
890         << mName << "Generic,bbtk::AtomicBlackBox);\n";
891
892   // Inputs
893   std::vector<IO>::iterator ioi;
894   for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi) 
895     {
896       mFile << "  BBTK_DECLARE_INPUT(" 
897             << ioi->name
898             << ","
899             << ioi->generic_type
900             << ");\n";
901     }
902   
903   // Outputs
904   for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi) 
905     {
906       mFile << "  BBTK_DECLARE_OUTPUT(" 
907             << ioi->name
908             << ","
909             << ioi->generic_type
910             << ");\n";
911     }
912     
913   // Process
914   mFile << "  BBTK_PROCESS(ProcessSwitch);\n";
915   mFile << "  private :\n";
916   mFile << "    inline void ProcessSwitch();\n";
917   mFile << "    template <class T, unsigned int D> void Process();\n";
918   // EO black box declaration
919   mFile << "};\n\n";
920
921
922
923   // BO black box description
924   mFile << "BBTK_BEGIN_DESCRIBE_BLACK_BOX("
925         << mName << "Generic,bbtk::AtomicBlackBox);\n";
926   mFile << "BBTK_NAME(\"" << mName <<"\");\n";
927
928   // Author
929   mFile << "BBTK_AUTHOR(\""<<mAuthor<< "\");\n";
930
931   // Description
932   mFile << "BBTK_DESCRIPTION(\""<<mDescription<< "\");\n"; 
933   
934   // Inputs
935   for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi) 
936     {
937       mFile << "BBTK_INPUT(";
938       mFile << mName << "Generic," << ioi->name << ",\""
939             << ioi->descr << "\"," <<  ioi->generic_type <<");\n";
940     }
941   
942   // Outputs
943   for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi) 
944     {
945       mFile << "BBTK_OUTPUT(";
946       mFile << mName << "Generic," << ioi->name << ",\""
947             << ioi->descr << "\"," <<  ioi->generic_type <<");\n";
948     }
949   
950   // EO black box description
951   mFile << "BBTK_END_DESCRIBE_BLACK_BOX("
952         << mName << "Generic);\n";
953
954
955   //=================================================================
956   // ProcessSwitch implementation
957   mFile << "void "<< mName <<"Generic::ProcessSwitch()\n"
958         << "{\n"
959         << "CALL_FOR_ALL_TYPES_AND_DIM(bbGetInputIn()->GetType(),\n"
960         << "                           bbGetInputIn()->GetDimension(),\n"
961         << "                           Process);\n"
962         << "}\n";
963   //=================================================================
964
965
966   //=================================================================
967   // Template process implementation
968   mFile << "template <class T, unsigned int D>\n"
969         << "void "<<mName<<"Generic::Process()\n"
970         << "{\n"
971         << "  bbtkDebugMessageInc(\"Kernel\",9,\n"
972         << "      \""<<mName 
973         << "Generic::Process<\"<<TypeName<T>()<<\",\"<<D<<\">()\"<<std::endl);\n"
974     
975         << "  typedef itk::Image<T,D> ImageType;\n"
976         << "  typedef "<<mName<<"<ImageType> FilterType;\n"
977     
978         << "  FilterType* f = new FilterType(\"Temp\");\n"
979     
980         << "  f->bbSetInputIn( this->bbGetInputIn()->GetImage<T,D>() );\n";
981   
982   for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi) 
983     {
984       if (ioi->name == "In") continue;
985       mFile << "  f->bbSetInput"<<ioi->name<<" ( this->bbGetInput" 
986             << ioi->name << "() );\n";
987     }
988   
989   mFile << "  f->bbUpdate();\n"
990         << "  this->bbSetOutputOut( new itkImage( f->bbGetOutputOut() ) );\n"
991         << "  f->UnRegister();\n"
992         << "  bbtkDebugDecTab(\"Kernel\",9);\n"
993         << "}\n\n";
994   //=================================================================
995
996
997 }
998 //==========================================================================
999
1000
1001 //==========================================================================
1002 void bbfy::CreateCode()
1003 {
1004   mCxxName = "bb";
1005   mCxxName += mPackage;
1006   mCxxName += mName;
1007   mCxxName += ".cxx";
1008   if (mVerbose) std::cout << " - Creating code   '"<<mCxxName<<"'"<<std::endl;
1009   std::string fullname = mOutputPath + mCxxName;
1010   mFile.open(fullname.c_str());
1011   if (!mFile.good()) 
1012     {
1013       std::string mess("Error : could not open file \"");
1014       mess += fullname;
1015       mess += "\"";
1016       throw bbfyException(mess);
1017     }
1018   
1019   // Includes
1020   // Header of the class
1021   mFile << "#include \"" << mHName << "\"\n";
1022
1023   // Include Package header
1024   mFile << "#include \"bb"<<mPackage << "Package.h\"\n";
1025
1026   // BO namespace
1027   BeginNamespace();
1028  
1029   
1030   // Template class ?
1031   if (mTemplateParam.size()>0) 
1032     {
1033       // Implementation
1034       mFile << "BBTK_BLACK_BOX_TEMPLATE_IMPLEMENTATION("
1035             << mName << ","  
1036             << mParentBlackBox << ");\n";
1037      
1038       if (mGeneric) 
1039         {       
1040           // Implementation
1041           mFile << "BBTK_BLACK_BOX_IMPLEMENTATION("
1042                 << mName << "Generic,bbtk::AtomicBlackBox);\n";
1043           // Package
1044           mFile << "BBTK_ADD_BLACK_BOX_TO_PACKAGE("
1045                 << mPackage << ","
1046                 << mName << "Generic)\n";
1047         }
1048     }
1049   else 
1050     {
1051       // Non template class
1052       // Package
1053       mFile << "BBTK_ADD_BLACK_BOX_TO_PACKAGE("
1054             << mPackage << ","
1055             << mName << ")\n";
1056
1057       // Implementation
1058       mFile << "BBTK_BLACK_BOX_IMPLEMENTATION("
1059             << mName << ","  
1060             << mParentBlackBox << ");\n"; 
1061     }
1062   // Process
1063   if ((mType == STD)||(mProcess.size()))
1064     {
1065       mFile << "void "<<mName<<"::Process()\n{\n";
1066       mFile << mProcess << "\n";
1067       mFile << "}\n";
1068     }
1069   // CreateWidget
1070   if (mIsWidget)
1071     {
1072       mFile << "void "<<mName<<"::CreateWidget(wxWindow* parent)\n{\n";
1073       mFile << mCreateWidget << "\n";
1074       mFile << "}\n";
1075     }
1076
1077   // User constr / copy constr / destr implementation
1078   mFile <<"void "<<mName<<"::bbUserSetDefaultValues()"<<std::endl;
1079   mFile << "{"<<std::endl;  
1080   mFile << mUserSetDefaultValues << std::endl;
1081   mFile << "}" << std::endl;
1082
1083   mFile <<"void "<<mName<<"::bbUserInitializeProcessing()"
1084         <<std::endl;
1085   mFile << "{"<<std::endl;
1086   mFile << mUserInitializeProcessing << std::endl;
1087   mFile << "}" << std::endl;
1088
1089   mFile <<"void "<<mName<<"::bbUserFinalizeProcessing()"<<std::endl;
1090   mFile << "{"<<std::endl;
1091   mFile << mUserFinalizeProcessing << std::endl;
1092   mFile << "}" << std::endl;
1093
1094
1095   // EO namespace
1096   EndNamespace();
1097
1098   mFile << "\n";
1099   
1100   // EOF
1101   mFile.close();
1102   
1103 }
1104 //==========================================================================
1105  
1106
1107
1108
1109
1110 //==========================================================================
1111 int main(int argc, char **argv)
1112 {
1113   
1114   if (argc<2 || argc>5) 
1115     {
1116       std::cerr << "usage : "<< argv[0] <<" xml_file [package_name] [output_path] [-q]" << std::endl;
1117       return 1;
1118     }
1119
1120   try 
1121     {
1122       std::string package("PACKAGE_NAME");
1123       std::string output_path("");
1124       bool verbose = true;
1125       if (argc>2) package = argv[2];
1126       if (argc>3) output_path = argv[3];
1127       if (argc>4) verbose = false;
1128       
1129       bbfy B(argv[1],package,output_path,verbose);
1130     }
1131   catch (bbfyException e)
1132     {
1133       std::cerr << argv[0] << "  " << argv[1] << std::endl
1134                 << e.mMessage << std::endl;
1135       return 1;
1136     }
1137   return 0;
1138 }
1139 //==========================================================================
1140
1141