2 #define _CRT_SECURE_NO_DEPRECATE
12 //==========================================================================
16 bbfyException(const std::string& message) : mMessage(message) {}
20 //==========================================================================
22 const std::string itkImageToImageFilterString = "ITK_ImageToImageFilter";
23 const std::string vtkImageAlgorithmString = "VTK_ImageAlgorithm";
24 const std::string vtkPolyDataAlgorithmString = "VTK_PolyDataAlgorithm";
26 //==========================================================================
30 bbfy(const std::string& filename,
31 const std::string& package = "PACKAGE_NAME",
32 const std::string& output_path = "",
33 bool verbose = false);
35 void CreateBlackBox();
40 void WriteGenericITKFilterHeader();
42 void BeginNamespace();
47 std::string mFilename;
48 std::string mOutputPath;
56 itkImageToImageFilter,
64 std::string mParentBlackBox;
65 std::string mItkParent;
66 std::string mVtkParent;
69 std::string mDescription;
70 std::string mCategory;
72 // bool mIsInNamespace;
73 std::string mNamespace;
74 // int mNbTemplateParam;
75 std::vector<std::string> mTemplateParam;
76 std::string mTemplateDeclaration;
77 std::string mTemplateImplementation;
79 std::vector<std::string> mInclude;
81 std::string mUserConstructor;
82 std::string mUserCopyConstructor;
83 std::string mUserDestructor;
91 std::string generic_type;
95 std::vector<IO> mInput;
96 std::vector<IO> mOutput;
99 std::string mCreateWidget;
104 std::string mCxxName;
107 //==========================================================================
111 //==========================================================================
112 bbfy::bbfy(const std::string& filename,
113 const std::string& package,
114 const std::string& output_path,
119 mFilename = filename;
121 mNamespace = "bb" + mPackage;
123 mOutputPath = output_path;
128 //==========================================================================
130 //==========================================================================
131 void bbfy::CreateBlackBox()
133 // Parse XML input file
135 // Create output files
139 //==========================================================================
143 //==========================================================================
144 void bbfy::ParseXML()
146 XMLResults* res = new XMLResults;
147 XMLNode BB = XMLNode::parseFile(mFilename.c_str(),"blackbox",res);
149 if ( res->error != eXMLErrorNone )
151 std::ostringstream str;
152 str << XMLNode::getError(res->error);
153 str << " [line " << res->nLine << ", col "<<res->nColumn<<"]";
155 throw bbfyException(str.str());
160 if (!BB.isAttributeSet("name"))
162 throw bbfyException("Error : <blackbox> tag : no 'name' attribute found (mandatory)");
164 mName = BB.getAttribute("name");
166 if (mVerbose) std::cout << "* Creating BlackBox '"<<mName<<"'"<<std::endl;
173 if (BB.isAttributeSet("type"))
175 std::string bbtype = BB.getAttribute("type");
176 if (bbtype=="standard")
181 else if (bbtype==itkImageToImageFilterString)
183 mType = itkImageToImageFilter;
184 // Looks for <itkparent> tag
185 if (!BB.nChildNode("itkparent"))
187 throw bbfyException("Error : blackbox type '"+itkImageToImageFilterString+"' but no <itkparent> tag found (mandatory)");
189 bbtk::GetTextOrClear(BB.getChildNode("itkparent"),mItkParent);
192 if (BB.isAttributeSet("generic")) mGeneric=true;
194 else if (bbtype == vtkImageAlgorithmString)
196 mType = vtkImageAlgorithm;
197 // Looks for <vtkparent> tag
198 if (!BB.nChildNode("vtkparent"))
200 throw bbfyException("Error : blackbox type '"
201 +vtkImageAlgorithmString
202 +"' but no <vtkparent> tag found (mandatory)");
204 bbtk::GetTextOrClear(BB.getChildNode("vtkparent"),mVtkParent);
207 else if (bbtype == vtkPolyDataAlgorithmString )
209 mType = vtkPolyDataAlgorithm;
210 // Looks for <vtkparent> tag
211 if (!BB.nChildNode("vtkparent"))
213 throw bbfyException("Error : blackbox type '"
214 +vtkPolyDataAlgorithmString
215 +"' but no <vtkparent> tag found (mandatory)");
217 bbtk::GetTextOrClear(BB.getChildNode("vtkparent"),mVtkParent);
222 std::string mess("Error : blackbox type '");
224 mess += "' unknown. Known types :";
225 mess += "'" + itkImageToImageFilterString + "' ";
226 mess += "'" + vtkImageAlgorithmString + "' ";
227 mess += "'" + vtkPolyDataAlgorithmString + "' ";
228 throw bbfyException(mess);
233 if (BB.isAttributeSet("widget"))
236 mParentBlackBox = "bbtk::WxBlackBox";
237 mInclude.push_back("bbtkWxBlackBox.h");
242 mParentBlackBox = "bbtk::AtomicBlackBox";
243 mInclude.push_back("bbtkAtomicBlackBox.h");
248 for (i=0,j=0; i<BB.nChildNode("author"); i++)
251 bbtk::GetTextOrClear(BB.getChildNode("author",&j),val);
256 for (i=0,j=0; i<BB.nChildNode("description"); i++)
259 bbtk::GetTextOrClear(BB.getChildNode("description",&j),val);
264 for (i=0,j=0; i<BB.nChildNode("category"); i++)
267 bbtk::GetTextOrClear(BB.getChildNode("category",&j),val);
272 if (BB.nChildNode("namespace"))
274 bbtk::GetTextOrClear(BB.getChildNode("namespace"),mNamespace);
277 // UserConstructor body
278 if (BB.nChildNode("userconstructor"))
280 bbtk::GetTextOrClear(BB.getChildNode("userconstructor"),mUserConstructor);
282 // UserCopyConstructor body
283 if (BB.nChildNode("usercopyconstructor"))
285 bbtk::GetTextOrClear(BB.getChildNode("usercopyconstructor"),mUserCopyConstructor);
287 // UserDestructor body
288 if (BB.nChildNode("userdestructor"))
290 bbtk::GetTextOrClear(BB.getChildNode("userdestructor"),mUserDestructor);
293 // Template parameters
294 // mNbTemplateParam = BB.nChildNode("template");
296 if ( BB.nChildNode("template") > 0)
298 mTemplateDeclaration = "<";
299 mTemplateImplementation = "<";
301 for (i=0,j=0; i<BB.nChildNode("template")-1; i++)
303 mTemplateDeclaration += "class ";
305 bbtk::GetTextOrClear(BB.getChildNode("template",&j),val);
306 mTemplateDeclaration += val;
307 mTemplateDeclaration += ",";
308 mTemplateImplementation += val;
309 mTemplateImplementation += ",";
310 mTemplateParam.push_back(val);
312 mTemplateDeclaration += "class ";
314 bbtk::GetTextOrClear(BB.getChildNode("template",&j),val);
315 mTemplateDeclaration += val;
316 mTemplateDeclaration += ">";
317 mTemplateImplementation += val;
318 mTemplateImplementation += ">";
319 mTemplateParam.push_back(val);
323 for (i=0,j=0; i<BB.nChildNode("include"); i++)
326 bbtk::GetTextOrClear(BB.getChildNode("include",&j),val);
327 mInclude.push_back(val);
331 for (i=0,j=0; i<BB.nChildNode("input"); i++)
334 XMLNode n = BB.getChildNode("input",&j);
335 if (!n.isAttributeSet("name"))
337 throw bbfyException("Error : <input> attribute 'name' not found (mandatory)");
339 io.name = n.getAttribute("name");
340 if (!n.isAttributeSet("type"))
342 throw bbfyException("Error : <input name=\""+io.name+"\"> attribute 'type' not found (mandatory)");
344 io.type = n.getAttribute("type");
345 if (!n.isAttributeSet("description"))
347 throw bbfyException("Error : <input name=\""+io.name+"\"> attribute 'description' not found (mandatory)");
349 io.descr = n.getAttribute("description");
351 if (n.isAttributeSet("special"))
353 io.special = n.getAttribute("special");
356 if (n.isAttributeSet("generic_type"))
358 io.generic_type = n.getAttribute("generic_type");
361 mInput.push_back(io);
365 for (i=0,j=0; i<BB.nChildNode("output"); i++)
368 XMLNode n = BB.getChildNode("output",&j);
369 if (!n.isAttributeSet("name"))
371 throw bbfyException("Error : <output> attribute 'name' not found (mandatory)");
373 io.name = n.getAttribute("name");
374 if (!n.isAttributeSet("type"))
376 throw bbfyException("Error : <output name=\""+io.name+"\"> attribute 'type' not found (mandatory)");
378 io.type = n.getAttribute("type");
379 if (!n.isAttributeSet("description"))
381 throw bbfyException("Error : <output name=\""+io.name+"\"> attribute 'description' not found (mandatory)");
383 io.descr = n.getAttribute("description");
385 if (n.isAttributeSet("special"))
387 io.special = n.getAttribute("special");
390 if (n.isAttributeSet("generic_type"))
392 io.generic_type = n.getAttribute("generic_type");
395 mOutput.push_back(io);
400 // process tag given ?
401 if (BB.nChildNode("process"))
403 bbtk::GetTextOrClear(BB.getChildNode("process"),mProcess);
406 // createwidget tag given ?
407 if (BB.nChildNode("createwidget"))
409 bbtk::GetTextOrClear(BB.getChildNode("createwidget"),mCreateWidget);
412 //==========================================================================
415 //==========================================================================
416 void bbfy::BeginNamespace()
418 // if (mIsInNamespace)
420 mFile << "namespace "<<mNamespace <<"\n{\n\n";
423 //==========================================================================
425 //==========================================================================
426 void bbfy::EndNamespace()
428 // if (mIsInNamespace)
430 mFile << "}\n// EO namespace "<<mNamespace<<"\n\n";
433 //==========================================================================
436 //==========================================================================
437 void bbfy::CreateHeader()
444 if (mVerbose) std::cout << " - Creating header '"<<mHName<<"'"<<std::endl;
445 std::string fullname = mOutputPath + mHName;
446 mFile.open(fullname.c_str());
449 std::string mess("Error : could not open file \"");
450 mess += fullname + "\"";
451 throw bbfyException(mess);
457 mFile << "#ifdef _USE_WXWIDGETS_\n";
460 // Prevent multiple inclusions
461 std::string included("__bb");
462 included += mPackage + mName + "_h_INCLUDED__";
463 mFile << "#ifndef " << included <<"\n";
464 mFile << "#define " << included <<"\n";
467 // mFile << "#include \"bbtkAtomicBlackBox.h\"\n";
468 std::vector<std::string>::iterator i;
469 for (i=mInclude.begin(); i!=mInclude.end(); ++i)
471 mFile << "#include \"" << *i <<"\"\n";
473 if (mGeneric) mFile << "#include \"bbitkImage.h\"\n";
481 // If it is a template class
482 if (mTemplateParam.size() > 0)
484 mFile << "template " << mTemplateDeclaration <<"\n";
487 // Class declaration and parents
488 mFile << "class /*BBTK_EXPORT*/ "<<mName<<"\n";
490 mFile << " public "<<mParentBlackBox;
493 if (mBB.nChildNode("inherits"))
496 for (i=0,j=0; i<mBB.nChildNode("inherits")-1; i++)
499 << mBB.getChildNode("inherits",&j).getText()
503 << mBB.getChildNode("Inherits",&j).getText()
508 if (mType == itkImageToImageFilter )
510 mFile << ",\n public " << mItkParent <<"\n";
512 else if ( (mType == vtkImageAlgorithm) ||
513 (mType == vtkPolyDataAlgorithm) )
515 mFile << ",\n public " << mVtkParent <<"\n";
525 mFile << " BBTK_USER_BLACK_BOX_INTERFACE("
527 << mParentBlackBox << ");\n";
529 // typedef on itkfilter
530 if (mType == itkImageToImageFilter)
532 mFile << " typedef " <<mItkParent <<" itkParent;"<<std::endl;
533 mFile << " void bbDelete() { itkParent::UnRegister(); }"<<std::endl;
535 // typedef on itkfilter
536 if ( (mType == vtkImageAlgorithm) ||
537 (mType == vtkPolyDataAlgorithm) )
539 mFile << " typedef " <<mVtkParent <<" vtkParent;"<<std::endl;
540 mFile << " void bbDelete() { vtkParent::Delete(); }"<<std::endl;
543 // Declare user constructor / copy cons /destr
544 mFile << "//=================================================================="<<std::endl;
545 mFile << "/// User callback called in the box contructor"<<std::endl;
547 mFile << "virtual void bbUserConstructor();"<<std::endl;
548 mFile << "/// User callback called in the box copy constructor"<<std::endl;
549 mFile << "virtual void bbUserCopyConstructor();"<<std::endl;
550 mFile << "/// User callback called in the box destructor"<<std::endl;
551 mFile << "virtual void bbUserDestructor();"<<std::endl;
552 mFile << "//=================================================================="<<std::endl;
557 std::vector<IO>::iterator ioi;
558 for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi)
560 if (ioi->special=="")
562 mFile << " BBTK_DECLARE_INPUT("
568 else if (ioi->special=="itk input")
570 mFile << " BBTK_DECLARE_ITK_INPUT("
577 else if (ioi->special=="vtk input")
579 if (mType == vtkImageAlgorithm) {
580 mFile << " BBTK_DECLARE_VTK_IMAGE_ALGORITHM_INPUT("
587 else if (mType == vtkPolyDataAlgorithm) {
588 mFile << " BBTK_DECLARE_POLY_DATA_ALGORITHM_INPUT("
596 else if (ioi->special=="itk parameter")
598 mFile << " BBTK_DECLARE_ITK_PARAM("
605 else if (ioi->special=="vtk parameter")
607 mFile << " BBTK_DECLARE_VTK_PARAM("
616 std::string mess("Error : input '");
618 mess += "', 'special' attribute '";
619 mess += ioi->special;
621 throw bbfyException(mess);
626 for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi)
628 if (ioi->special=="")
630 mFile << " BBTK_DECLARE_OUTPUT("
636 else if (ioi->special=="itk output")
638 mFile << " BBTK_DECLARE_ITK_OUTPUT("
645 else if (ioi->special=="vtk output")
647 mFile << " BBTK_DECLARE_VTK_OUTPUT("
656 std::string mess("Error : output '");
658 mess += "', 'special' attribute '";
659 mess += ioi->special;
661 throw bbfyException(mess);
667 if ((mType == STD)||(mProcess.size()))
669 mFile << " BBTK_PROCESS(Process);\n" ;
670 mFile << " void Process();\n";
672 else if (mType == itkImageToImageFilter)
674 mFile << " BBTK_PROCESS(itkParent::Update);\n" ;
676 else if ((mType == vtkImageAlgorithm) ||
677 (mType == vtkPolyDataAlgorithm) )
680 mFile << " BBTK_PROCESS(vtkParent::Update);\n" ;
686 mFile << " BBTK_CREATE_WIDGET(CreateWidget);\n" ;
687 mFile << " void CreateWidget();\n";
691 // EO black box declaration
696 // BO black box description
697 if (mTemplateParam.size()==0)
699 mFile << "BBTK_BEGIN_DESCRIBE_BLACK_BOX("
701 << mParentBlackBox << ");\n";
702 mFile << "BBTK_NAME(\"" << mName <<"\");\n";
704 else if (mTemplateParam.size()==1)
706 mFile << "BBTK_BEGIN_DESCRIBE_TEMPLATE_BLACK_BOX("
708 //<< mParentBlackBox //<< ","
709 // << mTemplateParam[0]
711 mFile << "BBTK_NAME(\"" << mName
712 << "<\"+bbtk::TypeName<" << mTemplateParam[0]
717 throw bbfyException("template bb with more than 1 templ param not impl");
721 mFile << "BBTK_AUTHOR(\""<<mAuthor<< "\");\n";
724 mFile << "BBTK_DESCRIPTION(\""<<mDescription<< "\");\n";
727 mFile << "BBTK_CATEGORY(\""<<mCategory<< "\");\n";
730 for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi)
732 if (mTemplateParam.size()>0)
734 mFile << "BBTK_TEMPLATE_INPUT(";
738 mFile << "BBTK_INPUT(";
740 mFile << mName << "," << ioi->name << ",\""
741 << ioi->descr << "\"," << ioi->type <<");\n";
745 for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi)
747 if (mTemplateParam.size()>0)
749 mFile << "BBTK_TEMPLATE_OUTPUT(";
753 mFile << "BBTK_OUTPUT(";
755 mFile << mName << "," << ioi->name << ",\""
756 << ioi->descr << "\"," << ioi->type <<");\n";
759 // EO black box description
760 if (mTemplateParam.size()==0)
762 mFile << "BBTK_END_DESCRIBE_BLACK_BOX("
765 else if (mTemplateParam.size()==1)
767 mFile << "BBTK_END_DESCRIBE_TEMPLATE_BLACK_BOX("
769 // << mTemplateParam[0]
774 throw bbfyException("template bb with more than 1 templ param not impl");
778 // Untemplatization of itk filters
781 WriteGenericITKFilterHeader();
788 // Prevent multiple inclusions
789 mFile << "#endif // " << included <<"\n";
793 mFile << "#endif // _USE_WXWIDGETS_\n";
801 //==========================================================================
805 //==========================================================================
806 void bbfy::WriteGenericITKFilterHeader()
808 mFile << "\n//===================================================\n";
809 mFile << "// Generic \"untemplatized\" filter\n";
810 mFile << "//===================================================\n";
812 // Class declaration and parents
813 mFile << "class /*BBTK_EXPORT*/ "<<mName<<"Generic\n";
815 mFile << " public bbtk::AtomicBlackBox\n";
819 mFile << " BBTK_USER_BLACK_BOX_INTERFACE("
820 << mName << "Generic,bbtk::AtomicBlackBox);\n";
823 std::vector<IO>::iterator ioi;
824 for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi)
826 mFile << " BBTK_DECLARE_INPUT("
834 for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi)
836 mFile << " BBTK_DECLARE_OUTPUT("
844 mFile << " BBTK_PROCESS(ProcessSwitch);\n";
845 mFile << " private :\n";
846 mFile << " inline void ProcessSwitch();\n";
847 mFile << " template <class T, unsigned int D> void Process();\n";
848 // EO black box declaration
853 // BO black box description
854 mFile << "BBTK_BEGIN_DESCRIBE_BLACK_BOX("
855 << mName << "Generic,bbtk::AtomicBlackBox);\n";
856 mFile << "BBTK_NAME(\"" << mName <<"\");\n";
859 mFile << "BBTK_AUTHOR(\""<<mAuthor<< "\");\n";
862 mFile << "BBTK_DESCRIPTION(\""<<mDescription<< "\");\n";
865 for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi)
867 mFile << "BBTK_INPUT(";
868 mFile << mName << "Generic," << ioi->name << ",\""
869 << ioi->descr << "\"," << ioi->generic_type <<");\n";
873 for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi)
875 mFile << "BBTK_OUTPUT(";
876 mFile << mName << "Generic," << ioi->name << ",\""
877 << ioi->descr << "\"," << ioi->generic_type <<");\n";
880 // EO black box description
881 mFile << "BBTK_END_DESCRIBE_BLACK_BOX("
882 << mName << "Generic);\n";
885 //=================================================================
886 // ProcessSwitch implementation
887 mFile << "void "<< mName <<"Generic::ProcessSwitch()\n"
889 << "CALL_FOR_ALL_TYPES_AND_DIM(bbGetInputIn()->GetType(),\n"
890 << " bbGetInputIn()->GetDimension(),\n"
893 //=================================================================
896 //=================================================================
897 // Template process implementation
898 mFile << "template <class T, unsigned int D>\n"
899 << "void "<<mName<<"Generic::Process()\n"
901 << " bbtkDebugMessageInc(\"Kernel\",9,\n"
903 << "Generic::Process<\"<<TypeName<T>()<<\",\"<<D<<\">()\"<<std::endl);\n"
905 << " typedef itk::Image<T,D> ImageType;\n"
906 << " typedef "<<mName<<"<ImageType> FilterType;\n"
908 << " FilterType* f = new FilterType(\"Temp\");\n"
910 << " f->bbSetInputIn( this->bbGetInputIn()->GetImage<T,D>() );\n";
912 for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi)
914 if (ioi->name == "In") continue;
915 mFile << " f->bbSetInput"<<ioi->name<<" ( this->bbGetInput"
916 << ioi->name << "() );\n";
919 mFile << " f->bbUpdate();\n"
920 << " this->bbSetOutputOut( new itkImage( f->bbGetOutputOut() ) );\n"
921 << " f->UnRegister();\n"
922 << " bbtkDebugDecTab(\"Kernel\",9);\n"
924 //=================================================================
928 //==========================================================================
931 //==========================================================================
932 void bbfy::CreateCode()
935 mCxxName += mPackage;
938 if (mVerbose) std::cout << " - Creating code '"<<mCxxName<<"'"<<std::endl;
939 std::string fullname = mOutputPath + mCxxName;
940 mFile.open(fullname.c_str());
943 std::string mess("Error : could not open file \"");
946 throw bbfyException(mess);
950 // Header of the class
951 mFile << "#include \"" << mHName << "\"\n";
953 // Include Package header
954 mFile << "#include \"bb"<<mPackage << "Package.h\"\n";
961 if (mTemplateParam.size()>0)
964 mFile << "BBTK_USER_BLACK_BOX_TEMPLATE_IMPLEMENTATION("
966 << mParentBlackBox << ");\n";
971 mFile << "BBTK_USER_BLACK_BOX_IMPLEMENTATION("
972 << mName << "Generic,bbtk::AtomicBlackBox);\n";
974 mFile << "BBTK_ADD_BLACK_BOX_TO_PACKAGE("
976 << mName << "Generic)\n";
981 // Non template class
983 mFile << "BBTK_ADD_BLACK_BOX_TO_PACKAGE("
988 mFile << "BBTK_USER_BLACK_BOX_IMPLEMENTATION("
990 << mParentBlackBox << ");\n";
993 if ((mType == STD)||(mProcess.size()))
995 mFile << "void "<<mName<<"::Process()\n{\n";
996 mFile << mProcess << "\n";
1002 mFile << "void "<<mName<<"::CreateWidget()\n{\n";
1003 mFile << mCreateWidget << "\n";
1008 // User constr / copy constr / destr implementation
1009 mFile <<"void "<<mName<<"::bbUserConstructor()"<<std::endl;
1010 mFile << "{"<<std::endl;
1011 //mFile<<"bbtkDebugMessage(\"Kernel\",9,\""<<mName<<::bbUserConstructor()"<<std::endl);"<<std::endl;
1012 mFile << mUserConstructor << std::endl;
1013 mFile << "}" << std::endl;
1015 mFile <<"void "<<mName<<"::bbUserCopyConstructor()"<<std::endl;
1016 mFile << "{"<<std::endl;
1017 //mFile<<"bbtkDebugMessage(\"Kernel\",9,\""<<mName<<::bbUserCopyConstructor()"<<std::endl);"<<std::endl;
1018 mFile << mUserCopyConstructor << std::endl;
1019 mFile << "}" << std::endl;
1021 mFile <<"void "<<mName<<"::bbUserDestructor()"<<std::endl;
1022 mFile << "{"<<std::endl;
1023 //mFile<<"bbtkDebugMessage(\"Kernel\",9,\""<<mName<<::bbUserDestructor()"<<std::endl);"<<std::endl;
1024 mFile << mUserDestructor << std::endl;
1025 mFile << "}" << std::endl;
1037 //==========================================================================
1043 //==========================================================================
1044 int main(int argc, char **argv)
1047 if (argc<2 || argc>5)
1049 std::cerr << "usage : "<< argv[0] <<" xml_file [package_name] [output_path] [-q]" << std::endl;
1055 std::string package("PACKAGE_NAME");
1056 std::string output_path("");
1057 bool verbose = true;
1058 if (argc>2) package = argv[2];
1059 if (argc>3) output_path = argv[3];
1060 if (argc>4) verbose = false;
1062 bbfy B(argv[1],package,output_path,verbose);
1064 catch (bbfyException e)
1066 std::cerr << argv[0] << " " << argv[1] << std::endl
1067 << e.mMessage << std::endl;
1072 //==========================================================================