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