2 #define _CRT_SECURE_NO_DEPRECATE
12 //==========================================================================
16 bbfyException(const std::string& message) : mMessage(message) {}
20 //==========================================================================
22 //==========================================================================
26 bbfy(const std::string& filename,
27 const std::string& package = "PACKAGE_NAME",
28 const std::string& output_path = "",
29 bool verbose = false);
31 void CreateBlackBox();
36 void WriteGenericITKFilterHeader();
38 void BeginNamespace();
43 std::string mFilename;
44 std::string mOutputPath;
52 itkImageToImageFilter,
59 std::string mParentBlackBox;
60 std::string mItkParent;
61 std::string mVtkParent;
64 std::string mDescription;
65 std::string mCategory;
67 // bool mIsInNamespace;
68 std::string mNamespace;
69 // int mNbTemplateParam;
70 std::vector<std::string> mTemplateParam;
71 std::string mTemplateDeclaration;
72 std::string mTemplateImplementation;
74 std::vector<std::string> mInclude;
76 std::string mUserConstructor;
77 std::string mUserCopyConstructor;
78 std::string mUserDestructor;
86 std::string generic_type;
90 std::vector<IO> mInput;
91 std::vector<IO> mOutput;
94 std::string mCreateWidget;
102 //==========================================================================
106 //==========================================================================
107 bbfy::bbfy(const std::string& filename,
108 const std::string& package,
109 const std::string& output_path,
112 mFilename = filename;
114 mNamespace = "bb" + mPackage;
116 mOutputPath = output_path;
121 //==========================================================================
123 //==========================================================================
124 void bbfy::CreateBlackBox()
126 // Parse XML input file
128 // Create output files
132 //==========================================================================
135 //==========================================================================
136 void GetTextOrClear(const XMLNode& node, std::string& var)
140 var = node.getText();
142 else if (node.nClear()>0)
144 var = node.getClear().lpszValue;
148 std::string mess("Error : element <");
149 mess += node.getName();
150 mess += "> : no text nor <PRE></PRE> clear tag found";
151 throw bbfyException(mess);
154 //==========================================================================
157 //==========================================================================
158 void bbfy::ParseXML()
160 XMLResults* res = new XMLResults;
161 XMLNode BB = XMLNode::parseFile(mFilename.c_str(),"blackbox",res);
163 if ( res->error != eXMLErrorNone )
165 std::ostringstream str;
166 str << XMLNode::getError(res->error);
167 str << " [line " << res->nLine << ", col "<<res->nColumn<<"]";
169 throw bbfyException(str.str());
174 if (!BB.isAttributeSet("name"))
176 throw bbfyException("Error : no 'name' attribute found (mandatory)");
178 mName = BB.getAttribute("name");
180 if (mVerbose) std::cout << "* Creating BlackBox '"<<mName<<"'"<<std::endl;
187 if (BB.isAttributeSet("type"))
189 std::string bbtype = BB.getAttribute("type");
190 if (bbtype=="standard")
195 else if (bbtype=="itkImageToImageFilter")
197 mType = itkImageToImageFilter;
198 // Looks for <itkparent> tag
199 if (!BB.nChildNode("itkparent"))
201 throw bbfyException("Error : blackbox type 'itkImageToImageFilter' but no <itkparent> tag found (mandatory)");
203 GetTextOrClear(BB.getChildNode("itkparent"),mItkParent);
206 if (BB.isAttributeSet("generic")) mGeneric=true;
208 else if ((bbtype=="vtkImageAlgorithm") || (bbtype=="vtkPolyDataAlgorithm"))
210 mType = vtkImageAlgorithm;
211 // Looks for <vtkparent> tag
212 if (!BB.nChildNode("vtkparent"))
214 throw bbfyException("Error : blackbox type 'vtkImageAlgorithm' but no <vtkparent> tag found (mandatory)");
216 GetTextOrClear(BB.getChildNode("vtkparent"),mVtkParent);
221 std::string mess("Error : blackbox type '");
223 mess += "' unknown (types are 'standard','itkfilter')";
224 throw bbfyException(mess);
229 if (BB.isAttributeSet("widget"))
232 mParentBlackBox = "bbtk::WxBlackBox";
233 mInclude.push_back("bbtkWxBlackBox.h");
238 mParentBlackBox = "bbtk::AtomicBlackBox";
239 mInclude.push_back("bbtkAtomicBlackBox.h");
244 if (!BB.nChildNode("parentblackbox"))
246 throw bbfyException("Error : no <parentblackbox> tag found (mandatory)");
248 GetTextOrClear(BB.getChildNode("parentblackbox"),mParentBlackBox);
251 if (!BB.nChildNode("package"))
253 throw bbfyException("Error : no <package> tag found (mandatory)");
255 GetTextOrClear(BB.getChildNode("package"),mPackage);
260 for (i=0,j=0; i<BB.nChildNode("author"); i++)
263 GetTextOrClear(BB.getChildNode("author",&j),val);
268 for (i=0,j=0; i<BB.nChildNode("description"); i++)
271 GetTextOrClear(BB.getChildNode("description",&j),val);
276 for (i=0,j=0; i<BB.nChildNode("category"); i++)
279 GetTextOrClear(BB.getChildNode("category",&j),val);
285 mIsInNamespace = false;
286 if (BB.nChildNode("namespace"))
288 mIsInNamespace = true;
289 GetTextOrClear(BB.getChildNode("namespace"),mNamespace);
293 // UserConstructor body
294 if (BB.nChildNode("constructor"))
296 GetTextOrClear(BB.getChildNode("constructor"),mUserConstructor);
298 // UserCopyConstructor body
299 if (BB.nChildNode("copyconstructor"))
301 GetTextOrClear(BB.getChildNode("copyconstructor"),mUserCopyConstructor);
303 // UserDestructor body
304 if (BB.nChildNode("destructor"))
306 GetTextOrClear(BB.getChildNode("destructor"),mUserDestructor);
309 // Template parameters
310 // mNbTemplateParam = BB.nChildNode("template");
312 if ( BB.nChildNode("template") > 0)
314 mTemplateDeclaration = "<";
315 mTemplateImplementation = "<";
317 for (i=0,j=0; i<BB.nChildNode("template")-1; i++)
319 mTemplateDeclaration += "class ";
321 GetTextOrClear(BB.getChildNode("template",&j),val);
322 mTemplateDeclaration += val;
323 mTemplateDeclaration += ",";
324 mTemplateImplementation += val;
325 mTemplateImplementation += ",";
326 mTemplateParam.push_back(val);
328 mTemplateDeclaration += "class ";
330 GetTextOrClear(BB.getChildNode("template",&j),val);
331 mTemplateDeclaration += val;
332 mTemplateDeclaration += ">";
333 mTemplateImplementation += val;
334 mTemplateImplementation += ">";
335 mTemplateParam.push_back(val);
339 for (i=0,j=0; i<BB.nChildNode("include"); i++)
342 GetTextOrClear(BB.getChildNode("include",&j),val);
343 mInclude.push_back(val);
347 for (i=0,j=0; i<BB.nChildNode("input"); i++)
349 XMLNode n = BB.getChildNode("input",&j);
350 if (!n.isAttributeSet("name"))
352 throw bbfyException("Error : <input> attribute 'name' not found (mandatory)");
354 if (!n.isAttributeSet("type"))
356 throw bbfyException("Error : <input> attribute 'type' not found (mandatory)");
360 io.name = n.getAttribute("name");
361 io.type = n.getAttribute("type");
362 GetTextOrClear(n,io.help);
364 if (n.isAttributeSet("special"))
366 io.special = n.getAttribute("special");
369 if (n.isAttributeSet("generic_type"))
371 io.generic_type = n.getAttribute("generic_type");
374 mInput.push_back(io);
378 for (i=0,j=0; i<BB.nChildNode("output"); i++)
380 XMLNode n = BB.getChildNode("output",&j);
381 if (!n.isAttributeSet("name"))
383 throw bbfyException("Error : <output> attribute 'name' not found (mandatory)");
385 if (!n.isAttributeSet("type"))
387 throw bbfyException("Error : <output> attribute 'type' not found (mandatory)");
391 io.name = n.getAttribute("name");
392 io.type = n.getAttribute("type");
393 GetTextOrClear(n,io.help);
395 if (n.isAttributeSet("special"))
397 io.special = n.getAttribute("special");
400 if (n.isAttributeSet("generic_type"))
402 io.generic_type = n.getAttribute("generic_type");
405 mOutput.push_back(io);
410 // process tag given ?
411 if (BB.nChildNode("process"))
413 GetTextOrClear(BB.getChildNode("process"),mProcess);
416 // createwidget tag given ?
417 if (BB.nChildNode("createwidget"))
419 GetTextOrClear(BB.getChildNode("createwidget"),mCreateWidget);
422 //==========================================================================
425 //==========================================================================
426 void bbfy::BeginNamespace()
428 // if (mIsInNamespace)
430 mFile << "namespace "<<mNamespace <<"\n{\n\n";
433 //==========================================================================
435 //==========================================================================
436 void bbfy::EndNamespace()
438 // if (mIsInNamespace)
440 mFile << "}\n// EO namespace "<<mNamespace<<"\n\n";
443 //==========================================================================
446 //==========================================================================
447 void bbfy::CreateHeader()
454 if (mVerbose) std::cout << " - Creating header '"<<mHName<<"'"<<std::endl;
455 std::string fullname = mOutputPath + mHName;
456 mFile.open(fullname.c_str());
459 std::string mess("Error : could not open file \"");
460 mess += fullname + "\"";
461 throw bbfyException(mess);
465 mFile << "#ifdef _USE_WXWIDGETS_\n";
467 // Prevent multiple inclusions
468 std::string included("__bb");
469 included += mPackage + mName + "_h_INCLUDED__";
470 mFile << "#ifndef " << included <<"\n";
471 mFile << "#define " << included <<"\n";
474 // mFile << "#include \"bbtkAtomicBlackBox.h\"\n";
475 std::vector<std::string>::iterator i;
476 for (i=mInclude.begin(); i!=mInclude.end(); ++i)
478 mFile << "#include \"" << *i <<"\"\n";
480 if (mGeneric) mFile << "#include \"bbitkImage.h\"\n";
488 // If it is a template class
489 if (mTemplateParam.size() > 0)
491 mFile << "template " << mTemplateDeclaration <<"\n";
494 // Class declaration and parents
495 mFile << "class /*BBTK_EXPORT*/ "<<mName<<"\n";
497 mFile << " public "<<mParentBlackBox;
500 if (mBB.nChildNode("inherits"))
503 for (i=0,j=0; i<mBB.nChildNode("inherits")-1; i++)
506 << mBB.getChildNode("inherits",&j).getText()
510 << mBB.getChildNode("Inherits",&j).getText()
515 if (mType == itkImageToImageFilter )
517 mFile << ",\n public " << mItkParent <<"\n";
519 else if ( (mType == vtkImageAlgorithm) ||
520 (mType == vtkPolyDataAlgorithm) )
522 mFile << ",\n public " << mVtkParent <<"\n";
532 mFile << " BBTK_USER_BLACK_BOX_INTERFACE("
534 << mParentBlackBox << ");\n";
536 // typedef on itkfilter
537 if (mType == itkImageToImageFilter)
539 mFile << " typedef " <<mItkParent <<" itkParent;"<<std::endl;
540 mFile << " void bbDelete() { itkParent::UnRegister(); }"<<std::endl;
542 // typedef on itkfilter
543 if ( (mType == vtkImageAlgorithm) ||
544 (mType == vtkPolyDataAlgorithm) )
546 mFile << " typedef " <<mVtkParent <<" vtkParent;"<<std::endl;
547 mFile << " void bbDelete() { vtkParent::Delete(); }"<<std::endl;
550 // Declare user constructor / copy cons /destr
551 mFile << "//=================================================================="<<std::endl;
552 mFile << "/// User callback called in the box contructor"<<std::endl;
554 mFile << "virtual void bbUserConstructor();"<<std::endl;
555 mFile << "/// User callback called in the box copy constructor"<<std::endl;
556 mFile << "virtual void bbUserCopyConstructor();"<<std::endl;
557 mFile << "/// User callback called in the box destructor"<<std::endl;
558 mFile << "virtual void bbUserDestructor();"<<std::endl;
559 mFile << "//=================================================================="<<std::endl;
564 std::vector<IO>::iterator ioi;
565 for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi)
567 if (ioi->special=="")
569 mFile << " BBTK_DECLARE_INPUT("
575 else if (ioi->special=="itk input")
577 mFile << " BBTK_DECLARE_ITK_INPUT("
584 else if (ioi->special=="vtk input")
586 if (mType == vtkImageAlgorithm) {
587 mFile << " BBTK_DECLARE_VTK_IMAGE_ALGORITHM_INPUT("
594 else if (mType == vtkPolyDataAlgorithm) {
595 mFile << " BBTK_DECLARE_POLY_DATA_ALGORITHM_INPUT("
603 else if (ioi->special=="itk parameter")
605 mFile << " BBTK_DECLARE_ITK_PARAM("
612 else if (ioi->special=="vtk parameter")
614 mFile << " BBTK_DECLARE_VTK_PARAM("
623 std::string mess("Error : input '");
625 mess += "', 'special' attribute '";
626 mess += ioi->special;
628 throw bbfyException(mess);
633 for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi)
635 if (ioi->special=="")
637 mFile << " BBTK_DECLARE_OUTPUT("
643 else if (ioi->special=="itk output")
645 mFile << " BBTK_DECLARE_ITK_OUTPUT("
652 else if (ioi->special=="vtk output")
654 mFile << " BBTK_DECLARE_VTK_OUTPUT("
663 std::string mess("Error : output '");
665 mess += "', 'special' attribute '";
666 mess += ioi->special;
668 throw bbfyException(mess);
674 if ((mType == STD)||(mProcess.size()))
676 mFile << " BBTK_PROCESS(DoProcess);\n" ;
677 mFile << " void DoProcess();\n";
679 else if (mType == itkImageToImageFilter)
681 mFile << " BBTK_PROCESS(itkParent::Update);\n" ;
683 else if ((mType == vtkImageAlgorithm) ||
684 (mType == vtkPolyDataAlgorithm) )
687 mFile << " BBTK_PROCESS(vtkParent::Update);\n" ;
693 mFile << " BBTK_CREATE_WIDGET(DoCreateWidget);\n" ;
694 mFile << " void DoCreateWidget();\n";
698 // EO black box declaration
703 // BO black box description
704 if (mTemplateParam.size()==0)
706 mFile << "BBTK_BEGIN_DESCRIBE_BLACK_BOX("
708 << mParentBlackBox << ");\n";
709 mFile << "BBTK_NAME(\"" << mName <<"\");\n";
711 else if (mTemplateParam.size()==1)
713 mFile << "BBTK_BEGIN_DESCRIBE_TEMPLATE_BLACK_BOX("
715 //<< mParentBlackBox //<< ","
716 // << mTemplateParam[0]
718 mFile << "BBTK_NAME(\"" << mName
719 << "<\"+bbtk::TypeName<" << mTemplateParam[0]
724 throw bbfyException("template bb with more than 1 templ param not impl");
728 mFile << "BBTK_AUTHOR(\""<<mAuthor<< "\");\n";
731 mFile << "BBTK_DESCRIPTION(\""<<mDescription<< "\");\n";
734 mFile << "BBTK_CATEGORY(\""<<mCategory<< "\");\n";
737 for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi)
739 if (mTemplateParam.size()>0)
741 mFile << "BBTK_TEMPLATE_INPUT(";
745 mFile << "BBTK_INPUT(";
747 mFile << mName << "," << ioi->name << ",\""
748 << ioi->help << "\"," << ioi->type <<");\n";
752 for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi)
754 if (mTemplateParam.size()>0)
756 mFile << "BBTK_TEMPLATE_OUTPUT(";
760 mFile << "BBTK_OUTPUT(";
762 mFile << mName << "," << ioi->name << ",\""
763 << ioi->help << "\"," << ioi->type <<");\n";
766 // EO black box description
767 if (mTemplateParam.size()==0)
769 mFile << "BBTK_END_DESCRIBE_BLACK_BOX("
772 else if (mTemplateParam.size()==1)
774 mFile << "BBTK_END_DESCRIBE_TEMPLATE_BLACK_BOX("
776 // << mTemplateParam[0]
781 throw bbfyException("template bb with more than 1 templ param not impl");
785 // Untemplatization of itk filters
788 WriteGenericITKFilterHeader();
795 // Prevent multiple inclusions
796 mFile << "#endif // " << included <<"\n";
798 mFile << "#endif // _USE_WXWIDGETS_\n";
805 //==========================================================================
809 //==========================================================================
810 void bbfy::WriteGenericITKFilterHeader()
812 mFile << "\n//===================================================\n";
813 mFile << "// Generic \"untemplatized\" filter\n";
814 mFile << "//===================================================\n";
816 // Class declaration and parents
817 mFile << "class /*BBTK_EXPORT*/ "<<mName<<"Generic\n";
819 mFile << " public bbtk::AtomicBlackBox\n";
823 mFile << " BBTK_USER_BLACK_BOX_INTERFACE("
824 << mName << "Generic,bbtk::AtomicBlackBox);\n";
827 std::vector<IO>::iterator ioi;
828 for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi)
830 mFile << " BBTK_DECLARE_INPUT("
838 for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi)
840 mFile << " BBTK_DECLARE_OUTPUT("
848 mFile << " BBTK_PROCESS(ProcessSwitch);\n";
849 mFile << " private :\n";
850 mFile << " inline void ProcessSwitch();\n";
851 mFile << " template <class T, unsigned int D> void Process();\n";
852 // EO black box declaration
857 // BO black box description
858 mFile << "BBTK_BEGIN_DESCRIBE_BLACK_BOX("
859 << mName << "Generic,bbtk::AtomicBlackBox);\n";
860 mFile << "BBTK_NAME(\"" << mName <<"\");\n";
863 mFile << "BBTK_AUTHOR(\""<<mAuthor<< "\");\n";
866 mFile << "BBTK_DESCRIPTION(\""<<mDescription<< "\");\n";
869 for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi)
871 mFile << "BBTK_INPUT(";
872 mFile << mName << "Generic," << ioi->name << ",\""
873 << ioi->help << "\"," << ioi->generic_type <<");\n";
877 for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi)
879 mFile << "BBTK_OUTPUT(";
880 mFile << mName << "Generic," << ioi->name << ",\""
881 << ioi->help << "\"," << ioi->generic_type <<");\n";
884 // EO black box description
885 mFile << "BBTK_END_DESCRIBE_BLACK_BOX("
886 << mName << "Generic);\n";
889 //=================================================================
890 // ProcessSwitch implementation
891 mFile << "void "<< mName <<"Generic::ProcessSwitch()\n"
893 << "CALL_FOR_ALL_TYPES_AND_DIM(bbGetInputIn()->GetType(),\n"
894 << " bbGetInputIn()->GetDimension(),\n"
897 //=================================================================
900 //=================================================================
901 // Template process implementation
902 mFile << "template <class T, unsigned int D>\n"
903 << "void "<<mName<<"Generic::Process()\n"
905 << " bbtkDebugMessageInc(\"Kernel\",9,\n"
907 << "Generic::Process<\"<<TypeName<T>()<<\",\"<<D<<\">()\"<<std::endl);\n"
909 << " typedef itk::Image<T,D> ImageType;\n"
910 << " typedef "<<mName<<"<ImageType> FilterType;\n"
912 << " FilterType* f = new FilterType(\"Temp\");\n"
914 << " f->bbSetInputIn( this->bbGetInputIn()->GetImage<T,D>() );\n";
916 for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi)
918 if (ioi->name == "In") continue;
919 mFile << " f->bbSetInput"<<ioi->name<<" ( this->bbGetInput"
920 << ioi->name << "() );\n";
923 mFile << " f->bbUpdate();\n"
924 << " this->bbSetOutputOut( new itkImage( f->bbGetOutputOut() ) );\n"
925 << " f->UnRegister();\n"
926 << " bbtkDebugDecTab(\"Kernel\",9);\n"
928 //=================================================================
932 //==========================================================================
935 //==========================================================================
936 void bbfy::CreateCode()
939 mCxxName += mPackage;
942 if (mVerbose) std::cout << " - Creating code '"<<mCxxName<<"'"<<std::endl;
943 std::string fullname = mOutputPath + mCxxName;
944 mFile.open(fullname.c_str());
947 std::string mess("Error : could not open file \"");
950 throw bbfyException(mess);
954 // Header of the class
955 mFile << "#include \"" << mHName << "\"\n";
957 // Include Package header
958 mFile << "#include \"bb"<<mPackage << "Package.h\"\n";
965 if (mTemplateParam.size()>0)
968 mFile << "BBTK_USER_BLACK_BOX_TEMPLATE_IMPLEMENTATION("
970 << mParentBlackBox << ");\n";
975 mFile << "BBTK_USER_BLACK_BOX_IMPLEMENTATION("
976 << mName << "Generic,bbtk::AtomicBlackBox);\n";
978 mFile << "BBTK_ADD_BLACK_BOX_TO_PACKAGE("
980 << mName << "Generic)\n";
985 // Non template class
987 mFile << "BBTK_ADD_BLACK_BOX_TO_PACKAGE("
992 mFile << "BBTK_USER_BLACK_BOX_IMPLEMENTATION("
994 << mParentBlackBox << ");\n";
997 if ((mType == STD)||(mProcess.size()))
999 mFile << "void "<<mName<<"::DoProcess()\n{\n";
1000 mFile << mProcess << "\n";
1006 mFile << "void "<<mName<<"::DoCreateWidget()\n{\n";
1007 mFile << mCreateWidget << "\n";
1012 // User constr / copy constr / destr implementation
1013 mFile <<"void "<<mName<<"::bbUserConstructor()"<<std::endl;
1014 mFile << "{"<<std::endl;
1015 //mFile<<"bbtkDebugMessage(\"Kernel\",9,\""<<mName<<::bbUserConstructor()"<<std::endl);"<<std::endl;
1016 mFile << mUserConstructor << std::endl;
1017 mFile << "}" << std::endl;
1019 mFile <<"void "<<mName<<"::bbUserCopyConstructor()"<<std::endl;
1020 mFile << "{"<<std::endl;
1021 //mFile<<"bbtkDebugMessage(\"Kernel\",9,\""<<mName<<::bbUserCopyConstructor()"<<std::endl);"<<std::endl;
1022 mFile << mUserCopyConstructor << std::endl;
1023 mFile << "}" << std::endl;
1025 mFile <<"void "<<mName<<"::bbUserDestructor()"<<std::endl;
1026 mFile << "{"<<std::endl;
1027 //mFile<<"bbtkDebugMessage(\"Kernel\",9,\""<<mName<<::bbUserDestructor()"<<std::endl);"<<std::endl;
1028 mFile << mUserDestructor << std::endl;
1029 mFile << "}" << std::endl;
1041 //==========================================================================
1047 //==========================================================================
1048 int main(int argc, char **argv)
1051 if (argc<2 || argc>5)
1053 std::cerr << "usage : "<< argv[0] <<" xml_file [package_name] [output_path] [-q]" << std::endl;
1059 std::string package("PACKAGE_NAME");
1060 std::string output_path("");
1061 bool verbose = true;
1062 if (argc>2) package = argv[2];
1063 if (argc>3) output_path = argv[3];
1064 if (argc>4) verbose = false;
1066 bbfy B(argv[1],package,output_path,verbose);
1068 catch (bbfyException e)
1070 std::cerr << e.mMessage << std::endl;
1075 //==========================================================================