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