2 #define _CRT_SECURE_NO_DEPRECATE
12 //==========================================================================
16 bbfyException(const std::string& message) : mMessage(message) {}
20 //==========================================================================
22 //==========================================================================
26 bbfy(const std::string& filename, const std::string& output_path = "",
27 bool verbose = false);
29 void CreateBlackBox();
34 void WriteGenericITKFilterHeader();
36 void BeginNamespace();
41 std::string mFilename;
42 std::string mOutputPath;
50 itkImageToImageFilter,
56 std::string mParentBlackBox;
57 std::string mItkParent;
58 std::string mVtkParent;
61 std::string mDescription;
64 std::string mNamespace;
65 // int mNbTemplateParam;
66 std::vector<std::string> mTemplateParam;
67 std::string mTemplateDeclaration;
68 std::string mTemplateImplementation;
70 std::vector<std::string> mInclude;
72 std::string mUserConstructor;
73 std::string mUserCopyConstructor;
74 std::string mUserDestructor;
82 std::string generic_type;
86 std::vector<IO> mInput;
87 std::vector<IO> mOutput;
97 //==========================================================================
101 //==========================================================================
102 bbfy::bbfy(const std::string& filename,
103 const std::string& output_path,
106 mFilename = filename;
107 mOutputPath = output_path;
112 //==========================================================================
114 //==========================================================================
115 void bbfy::CreateBlackBox()
117 // Parse XML input file
119 // Create output files
123 //==========================================================================
126 //==========================================================================
127 void GetTextOrClear(const XMLNode& node, std::string& var)
131 var = node.getText();
133 else if (node.nClear()>0)
135 var = node.getClear().lpszValue;
139 std::string mess("Error : element <");
140 mess += node.getName();
141 mess += "> : no text nor <PRE></PRE> clear tag found";
142 throw bbfyException(mess);
145 //==========================================================================
148 //==========================================================================
149 void bbfy::ParseXML()
151 XMLResults* res = new XMLResults;
152 XMLNode BB = XMLNode::parseFile(mFilename.c_str(),"blackbox",res);
154 if ( res->error != eXMLErrorNone )
156 std::ostringstream str;
157 str << XMLNode::getError(res->error);
158 str << " [line " << res->nLine << ", col "<<res->nColumn<<"]";
160 throw bbfyException(str.str());
165 if (!BB.isAttributeSet("name"))
167 throw bbfyException("Error : no 'name' attribute found (mandatory)");
169 mName = BB.getAttribute("name");
171 if (mVerbose) std::cout << "* Creating BlackBox '"<<mName<<"'"<<std::endl;
176 if (BB.isAttributeSet("type"))
178 std::string bbtype = BB.getAttribute("type");
179 if (bbtype=="standard")
184 else if (bbtype=="itkImageToImageFilter")
186 mType = itkImageToImageFilter;
187 // Looks for <itkparent> tag
188 if (!BB.nChildNode("itkparent"))
190 throw bbfyException("Error : blackbox type 'itkImageToImageFilter' but no <itkparent> tag found (mandatory)");
192 GetTextOrClear(BB.getChildNode("itkparent"),mItkParent);
195 if (BB.isAttributeSet("generic")) mGeneric=true;
197 else if ((bbtype=="vtkImageAlgorithm") || (bbtype=="vtkPolyDataAlgorithm"))
199 mType = vtkImageAlgorithm;
200 // Looks for <vtkparent> tag
201 if (!BB.nChildNode("vtkparent"))
203 throw bbfyException("Error : blackbox type 'vtkImageAlgorithm' but no <vtkparent> tag found (mandatory)");
205 GetTextOrClear(BB.getChildNode("vtkparent"),mVtkParent);
210 std::string mess("Error : blackbox type '");
212 mess += "' unknown (types are 'standard','itkfilter')";
213 throw bbfyException(mess);
218 if (!BB.nChildNode("parentblackbox"))
220 throw bbfyException("Error : no <parentblackbox> tag found (mandatory)");
222 GetTextOrClear(BB.getChildNode("parentblackbox"),mParentBlackBox);
225 if (!BB.nChildNode("package"))
227 throw bbfyException("Error : no <package> tag found (mandatory)");
229 GetTextOrClear(BB.getChildNode("package"),mPackage);
233 for (i=0,j=0; i<BB.nChildNode("author"); i++)
236 GetTextOrClear(BB.getChildNode("author",&j),val);
241 for (i=0,j=0; i<BB.nChildNode("description"); i++)
244 GetTextOrClear(BB.getChildNode("description",&j),val);
249 mIsInNamespace = false;
250 if (BB.nChildNode("namespace"))
252 mIsInNamespace = true;
253 GetTextOrClear(BB.getChildNode("namespace"),mNamespace);
256 // UserConstructor body
257 if (BB.nChildNode("constructor"))
259 GetTextOrClear(BB.getChildNode("constructor"),mUserConstructor);
261 // UserCopyConstructor body
262 if (BB.nChildNode("copyconstructor"))
264 GetTextOrClear(BB.getChildNode("copyconstructor"),mUserCopyConstructor);
266 // UserDestructor body
267 if (BB.nChildNode("destructor"))
269 GetTextOrClear(BB.getChildNode("destructor"),mUserDestructor);
272 // Template parameters
273 // mNbTemplateParam = BB.nChildNode("template");
275 if ( BB.nChildNode("template") > 0)
277 mTemplateDeclaration = "<";
278 mTemplateImplementation = "<";
280 for (i=0,j=0; i<BB.nChildNode("template")-1; i++)
282 mTemplateDeclaration += "class ";
284 GetTextOrClear(BB.getChildNode("template",&j),val);
285 mTemplateDeclaration += val;
286 mTemplateDeclaration += ",";
287 mTemplateImplementation += val;
288 mTemplateImplementation += ",";
289 mTemplateParam.push_back(val);
291 mTemplateDeclaration += "class ";
293 GetTextOrClear(BB.getChildNode("template",&j),val);
294 mTemplateDeclaration += val;
295 mTemplateDeclaration += ">";
296 mTemplateImplementation += val;
297 mTemplateImplementation += ">";
298 mTemplateParam.push_back(val);
302 for (i=0,j=0; i<BB.nChildNode("include"); i++)
305 GetTextOrClear(BB.getChildNode("include",&j),val);
306 mInclude.push_back(val);
310 for (i=0,j=0; i<BB.nChildNode("input"); i++)
312 XMLNode n = BB.getChildNode("input",&j);
313 if (!n.isAttributeSet("name"))
315 throw bbfyException("Error : <input> attribute 'name' not found (mandatory)");
317 if (!n.isAttributeSet("type"))
319 throw bbfyException("Error : <input> attribute 'type' not found (mandatory)");
323 io.name = n.getAttribute("name");
324 io.type = n.getAttribute("type");
325 GetTextOrClear(n,io.help);
327 if (n.isAttributeSet("special"))
329 io.special = n.getAttribute("special");
332 if (n.isAttributeSet("generic_type"))
334 io.generic_type = n.getAttribute("generic_type");
337 mInput.push_back(io);
341 for (i=0,j=0; i<BB.nChildNode("output"); i++)
343 XMLNode n = BB.getChildNode("output",&j);
344 if (!n.isAttributeSet("name"))
346 throw bbfyException("Error : <output> attribute 'name' not found (mandatory)");
348 if (!n.isAttributeSet("type"))
350 throw bbfyException("Error : <output> attribute 'type' not found (mandatory)");
354 io.name = n.getAttribute("name");
355 io.type = n.getAttribute("type");
356 GetTextOrClear(n,io.help);
358 if (n.isAttributeSet("special"))
360 io.special = n.getAttribute("special");
363 if (n.isAttributeSet("generic_type"))
365 io.generic_type = n.getAttribute("generic_type");
368 mOutput.push_back(io);
373 // Process tag given ?
374 if (BB.nChildNode("process"))
376 GetTextOrClear(BB.getChildNode("process"),mProcess);
379 //==========================================================================
382 //==========================================================================
383 void bbfy::BeginNamespace()
387 mFile << "namespace "<<mNamespace <<"\n{\n\n";
390 //==========================================================================
392 //==========================================================================
393 void bbfy::EndNamespace()
397 mFile << "}\n// EO namespace "<<mNamespace<<"\n\n";
400 //==========================================================================
403 //==========================================================================
404 void bbfy::CreateHeader()
411 if (mVerbose) std::cout << " - Creating header '"<<mHName<<"'"<<std::endl;
412 std::string fullname = mOutputPath + mHName;
413 mFile.open(fullname.c_str());
416 std::string mess("Error : could not open file \"");
417 mess += fullname + "\"";
418 throw bbfyException(mess);
423 mFile << "#include \"bbtkUserBlackBox.h\"\n";
424 std::vector<std::string>::iterator i;
425 for (i=mInclude.begin(); i!=mInclude.end(); ++i)
427 mFile << "#include \"" << *i <<"\"\n";
429 if (mGeneric) mFile << "#include \"bbitkImage.h\"\n";
437 // If it is a template class
438 if (mTemplateParam.size() > 0)
440 mFile << "template " << mTemplateDeclaration <<"\n";
443 // Class declaration and parents
444 mFile << "class /*BBTK_EXPORT*/ "<<mName<<"\n";
446 mFile << " public "<<mParentBlackBox;
449 if (mBB.nChildNode("inherits"))
452 for (i=0,j=0; i<mBB.nChildNode("inherits")-1; i++)
455 << mBB.getChildNode("inherits",&j).getText()
459 << mBB.getChildNode("Inherits",&j).getText()
464 if (mType == itkImageToImageFilter )
466 mFile << ",\n public " << mItkParent <<"\n";
468 else if ( (mType == vtkImageAlgorithm) ||
469 (mType == vtkPolyDataAlgorithm) )
471 mFile << ",\n public " << mVtkParent <<"\n";
481 mFile << " BBTK_USER_BLACK_BOX_INTERFACE("
483 << mParentBlackBox << ");\n";
485 // typedef on itkfilter
486 if (mType == itkImageToImageFilter)
488 mFile << " typedef " <<mItkParent <<" itkParent;"<<std::endl;
489 mFile << " void bbDelete() { itkParent::UnRegister(); }"<<std::endl;
491 // typedef on itkfilter
492 if ( (mType == vtkImageAlgorithm) ||
493 (mType == vtkPolyDataAlgorithm) )
495 mFile << " typedef " <<mVtkParent <<" vtkParent;"<<std::endl;
496 mFile << " void bbDelete() { vtkParent::Delete(); }"<<std::endl;
499 // Declare user constructor / copy cons /destr
500 mFile << "//=================================================================="<<std::endl;
501 mFile << "/// User callback called in the box contructor"<<std::endl;
503 mFile << "virtual void bbUserConstructor();"<<std::endl;
504 mFile << "/// User callback called in the box copy constructor"<<std::endl;
505 mFile << "virtual void bbUserCopyConstructor();"<<std::endl;
506 mFile << "/// User callback called in the box destructor"<<std::endl;
507 mFile << "virtual void bbUserDestructor();"<<std::endl;
508 mFile << "//=================================================================="<<std::endl;
513 std::vector<IO>::iterator ioi;
514 for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi)
516 if (ioi->special=="")
518 mFile << " BBTK_DECLARE_INPUT("
524 else if (ioi->special=="itk input")
526 mFile << " BBTK_DECLARE_ITK_INPUT("
533 else if (ioi->special=="vtk input")
535 if (mType == vtkImageAlgorithm) {
536 mFile << " BBTK_DECLARE_VTK_IMAGE_ALGORITHM_INPUT("
543 else if (mType == vtkPolyDataAlgorithm) {
544 mFile << " BBTK_DECLARE_POLY_DATA_ALGORITHM_INPUT("
552 else if (ioi->special=="itk parameter")
554 mFile << " BBTK_DECLARE_ITK_PARAM("
561 else if (ioi->special=="vtk parameter")
563 mFile << " BBTK_DECLARE_VTK_PARAM("
572 std::string mess("Error : input '");
574 mess += "', 'special' attribute '";
575 mess += ioi->special;
577 throw bbfyException(mess);
582 for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi)
584 if (ioi->special=="")
586 mFile << " BBTK_DECLARE_OUTPUT("
592 else if (ioi->special=="itk output")
594 mFile << " BBTK_DECLARE_ITK_OUTPUT("
601 else if (ioi->special=="vtk output")
603 mFile << " BBTK_DECLARE_VTK_OUTPUT("
612 std::string mess("Error : output '");
614 mess += "', 'special' attribute '";
615 mess += ioi->special;
617 throw bbfyException(mess);
623 if ((mType == STD)||(mProcess.size()))
625 mFile << " BBTK_PROCESS(DoProcess);\n" ;
626 mFile << " void DoProcess();\n";
628 else if (mType == itkImageToImageFilter)
630 mFile << " BBTK_PROCESS(itkParent::Update);\n" ;
632 else if ((mType == vtkImageAlgorithm) ||
633 (mType == vtkPolyDataAlgorithm) )
636 mFile << " BBTK_PROCESS(vtkParent::Update);\n" ;
639 // EO black box declaration
644 // BO black box description
645 if (mTemplateParam.size()==0)
647 mFile << "BBTK_BEGIN_DESCRIBE_BLACK_BOX("
649 << mParentBlackBox << ");\n";
650 mFile << "BBTK_NAME(\"" << mName <<"\");\n";
652 else if (mTemplateParam.size()==1)
654 mFile << "BBTK_BEGIN_DESCRIBE_TEMPLATE_BLACK_BOX("
656 //<< mParentBlackBox //<< ","
657 // << mTemplateParam[0]
659 mFile << "BBTK_NAME(\"" << mName
660 << "<\"+bbtk::TypeName<" << mTemplateParam[0]
665 throw bbfyException("template bb with more than 1 templ param not impl");
669 mFile << "BBTK_AUTHOR(\""<<mAuthor<< "\");\n";
672 mFile << "BBTK_DESCRIPTION(\""<<mDescription<< "\");\n";
675 for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi)
677 if (mTemplateParam.size()>0)
679 mFile << "BBTK_TEMPLATE_INPUT(";
683 mFile << "BBTK_INPUT(";
685 mFile << mName << "," << ioi->name << ",\""
686 << ioi->help << "\"," << ioi->type <<");\n";
690 for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi)
692 if (mTemplateParam.size()>0)
694 mFile << "BBTK_TEMPLATE_OUTPUT(";
698 mFile << "BBTK_OUTPUT(";
700 mFile << mName << "," << ioi->name << ",\""
701 << ioi->help << "\"," << ioi->type <<");\n";
704 // EO black box description
705 if (mTemplateParam.size()==0)
707 mFile << "BBTK_END_DESCRIBE_BLACK_BOX("
710 else if (mTemplateParam.size()==1)
712 mFile << "BBTK_END_DESCRIBE_TEMPLATE_BLACK_BOX("
714 // << mTemplateParam[0]
719 throw bbfyException("template bb with more than 1 templ param not impl");
723 // Untemplatization of itk filters
726 WriteGenericITKFilterHeader();
738 //==========================================================================
742 //==========================================================================
743 void bbfy::WriteGenericITKFilterHeader()
745 mFile << "\n//===================================================\n";
746 mFile << "// Generic \"untemplatized\" filter\n";
747 mFile << "//===================================================\n";
749 // Class declaration and parents
750 mFile << "class /*BBTK_EXPORT*/ "<<mName<<"Generic\n";
752 mFile << " public bbtk::UserBlackBox\n";
756 mFile << " BBTK_USER_BLACK_BOX_INTERFACE("
757 << mName << "Generic,bbtk::UserBlackBox);\n";
760 std::vector<IO>::iterator ioi;
761 for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi)
763 mFile << " BBTK_DECLARE_INPUT("
771 for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi)
773 mFile << " BBTK_DECLARE_OUTPUT("
781 mFile << " BBTK_PROCESS(ProcessSwitch);\n";
782 mFile << " private :\n";
783 mFile << " inline void ProcessSwitch();\n";
784 mFile << " template <class T, unsigned int D> void Process();\n";
785 // EO black box declaration
790 // BO black box description
791 mFile << "BBTK_BEGIN_DESCRIBE_BLACK_BOX("
792 << mName << "Generic,bbtk::UserBlackBox);\n";
793 mFile << "BBTK_NAME(\"" << mName <<"\");\n";
796 mFile << "BBTK_AUTHOR(\""<<mAuthor<< "\");\n";
799 mFile << "BBTK_DESCRIPTION(\""<<mDescription<< "\");\n";
802 for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi)
804 mFile << "BBTK_INPUT(";
805 mFile << mName << "Generic," << ioi->name << ",\""
806 << ioi->help << "\"," << ioi->generic_type <<");\n";
810 for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi)
812 mFile << "BBTK_OUTPUT(";
813 mFile << mName << "Generic," << ioi->name << ",\""
814 << ioi->help << "\"," << ioi->generic_type <<");\n";
817 // EO black box description
818 mFile << "BBTK_END_DESCRIBE_BLACK_BOX("
819 << mName << "Generic);\n";
822 //=================================================================
823 // ProcessSwitch implementation
824 mFile << "void "<< mName <<"Generic::ProcessSwitch()\n"
826 << "CALL_FOR_ALL_TYPES_AND_DIM(bbGetInputIn()->GetType(),\n"
827 << " bbGetInputIn()->GetDimension(),\n"
830 //=================================================================
833 //=================================================================
834 // Template process implementation
835 mFile << "template <class T, unsigned int D>\n"
836 << "void "<<mName<<"Generic::Process()\n"
838 << " bbtkDebugMessageInc(\"Core\",9,\n"
840 << "Generic::Process<\"<<TypeName<T>()<<\",\"<<D<<\">()\"<<std::endl);\n"
842 << " typedef itk::Image<T,D> ImageType;\n"
843 << " typedef "<<mName<<"<ImageType> FilterType;\n"
845 << " FilterType* f = new FilterType(\"Temp\");\n"
847 << " f->bbSetInputIn( this->bbGetInputIn()->GetImage<T,D>() );\n";
849 for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi)
851 if (ioi->name == "In") continue;
852 mFile << " f->bbSetInput"<<ioi->name<<" ( this->bbGetInput"
853 << ioi->name << "() );\n";
856 mFile << " f->bbUpdate();\n"
857 << " this->bbSetOutputOut( new itkImage( f->bbGetOutputOut() ) );\n"
858 << " f->UnRegister();\n"
859 << " bbtkDebugDecTab(\"Core\",9);\n"
861 //=================================================================
865 //==========================================================================
868 //==========================================================================
869 void bbfy::CreateCode()
872 mCxxName += mPackage;
875 if (mVerbose) std::cout << " - Creating code '"<<mCxxName<<"'"<<std::endl;
876 std::string fullname = mOutputPath + mCxxName;
877 mFile.open(fullname.c_str());
880 std::string mess("Error : could not open file \"");
883 throw bbfyException(mess);
887 // Header of the class
888 mFile << "#include \"" << mHName << "\"\n";
890 // Include Package header
891 mFile << "#include \"bb"<<mPackage << "Package.h\"\n";
898 if (mTemplateParam.size()>0)
901 mFile << "BBTK_USER_BLACK_BOX_TEMPLATE_IMPLEMENTATION("
903 << mParentBlackBox << ");\n";
908 mFile << "BBTK_USER_BLACK_BOX_IMPLEMENTATION("
909 << mName << "Generic,bbtk::UserBlackBox);\n";
911 mFile << "BBTK_ADD_BLACK_BOX_TO_PACKAGE("
913 << mName << "Generic)\n";
918 // Non template class
920 mFile << "BBTK_ADD_BLACK_BOX_TO_PACKAGE("
925 mFile << "BBTK_USER_BLACK_BOX_IMPLEMENTATION("
927 << mParentBlackBox << ");\n";
930 if ((mType == STD)||(mProcess.size()))
932 mFile << "void "<<mName<<"::DoProcess()\n{\n";
933 mFile << mProcess << "\n";
938 // User constr / copy constr / destr implementation
939 mFile <<"void "<<mName<<"::bbUserConstructor()"<<std::endl;
940 mFile << "{"<<std::endl;
941 //mFile<<"bbtkDebugMessage(\"Core\",9,\""<<mName<<::bbUserConstructor()"<<std::endl);"<<std::endl;
942 mFile << mUserConstructor << std::endl;
943 mFile << "}" << std::endl;
945 mFile <<"void "<<mName<<"::bbUserCopyConstructor()"<<std::endl;
946 mFile << "{"<<std::endl;
947 //mFile<<"bbtkDebugMessage(\"Core\",9,\""<<mName<<::bbUserCopyConstructor()"<<std::endl);"<<std::endl;
948 mFile << mUserCopyConstructor << std::endl;
949 mFile << "}" << std::endl;
951 mFile <<"void "<<mName<<"::bbUserDestructor()"<<std::endl;
952 mFile << "{"<<std::endl;
953 //mFile<<"bbtkDebugMessage(\"Core\",9,\""<<mName<<::bbUserDestructor()"<<std::endl);"<<std::endl;
954 mFile << mUserDestructor << std::endl;
955 mFile << "}" << std::endl;
967 //==========================================================================
973 //==========================================================================
974 int main(int argc, char **argv)
977 if (argc<2 || argc>4)
979 std::cerr << "usage : "<< argv[0] <<" xml_file [output_path] [-q]" << std::endl;
985 std::string output_path("");
987 if (argc>2) output_path = argv[2];
988 if (argc>3) verbose = false;
990 bbfy B(argv[1],output_path,verbose);
992 catch (bbfyException e)
994 std::cerr << e.mMessage << std::endl;
999 //==========================================================================