#ifdef WIN32 #define _CRT_SECURE_NO_DEPRECATE #endif #include #include "bbtkXML.h" #include #include #include #include //========================================================================== class bbfyException { public: bbfyException(const std::string& message) : mMessage(message) {} std::string mMessage; }; //========================================================================== const std::string itkImageToImageFilterString = "ITK_ImageToImageFilter"; const std::string vtkImageAlgorithmString = "VTK_ImageAlgorithm"; const std::string vtkPolyDataAlgorithmString = "VTK_PolyDataAlgorithm"; //========================================================================== class bbfy { public: bbfy(const std::string& filename, const std::string& package = "PACKAGE_NAME", const std::string& output_path = "", bool verbose = false); void CreateBlackBox(); void ParseXML(); void CreateHeader(); void CreateCode(); void WriteGenericITKFilterHeader(); void BeginNamespace(); void EndNamespace(); private: // std::string mFilename; std::string mOutputPath; bool mVerbose; // std::string mName; typedef enum { STD, itkImageToImageFilter, vtkImageAlgorithm, vtkPolyDataAlgorithm, } BoxType; BoxType mType; bool mIsWidget; std::string mParentBlackBox; std::string mItkParent; std::string mVtkParent; bool mGeneric; std::string mAuthor; std::string mDescription; std::string mCategory; std::string mPackage; // bool mIsInNamespace; std::string mNamespace; // int mNbTemplateParam; std::vector mTemplateParam; std::string mTemplateDeclaration; std::string mTemplateImplementation; std::vector mInclude; std::vector mTypedef; std::string mUserConstructor; std::string mUserCopyConstructor; std::string mUserDestructor; typedef struct { std::string name; std::string type; std::string nature; std::string descr; std::string special; std::string generic_type; } IO; std::vector mInput; std::vector mOutput; std::string mProcess; std::string mCreateWidget; // std::ofstream mFile; std::string mHName; std::string mCxxName; }; //========================================================================== //========================================================================== bbfy::bbfy(const std::string& filename, const std::string& package, const std::string& output_path, bool verbose) { mIsWidget = false; mFilename = filename; mPackage = package; mNamespace = "bb" + mPackage; mOutputPath = output_path; mVerbose = verbose; CreateBlackBox(); } //========================================================================== //========================================================================== void bbfy::CreateBlackBox() { // Parse XML input file ParseXML(); // Create output files CreateHeader(); CreateCode(); } //========================================================================== //========================================================================== void bbfy::ParseXML() { XMLResults* res = new XMLResults; XMLNode BB = XMLNode::parseFile(mFilename.c_str(),"blackbox",res); if ( res->error != eXMLErrorNone ) { std::ostringstream str; str << XMLNode::getError(res->error); str << " [line " << res->nLine << ", col "<nColumn<<"]"; delete res; throw bbfyException(str.str()); } delete res; // Name if (!BB.isAttributeSet("name")) { throw bbfyException("Error : tag : no 'name' attribute found (mandatory)"); } mName = BB.getAttribute("name"); if (mVerbose) std::cout << "* Creating BlackBox '"< tag if (!BB.nChildNode("itkparent")) { throw bbfyException("Error : blackbox type '"+itkImageToImageFilterString+"' but no tag found (mandatory)"); } bbtk::GetTextOrClear(BB.getChildNode("itkparent"),mItkParent); // mGeneric = false; if (BB.isAttributeSet("generic")) mGeneric=true; } else if (bbtype == vtkImageAlgorithmString) { mType = vtkImageAlgorithm; // Looks for tag if (!BB.nChildNode("vtkparent")) { throw bbfyException("Error : blackbox type '" +vtkImageAlgorithmString +"' but no tag found (mandatory)"); } bbtk::GetTextOrClear(BB.getChildNode("vtkparent"),mVtkParent); // } else if (bbtype == vtkPolyDataAlgorithmString ) { mType = vtkPolyDataAlgorithm; // Looks for tag if (!BB.nChildNode("vtkparent")) { throw bbfyException("Error : blackbox type '" +vtkPolyDataAlgorithmString +"' but no tag found (mandatory)"); } bbtk::GetTextOrClear(BB.getChildNode("vtkparent"),mVtkParent); // } else { std::string mess("Error : blackbox type '"); mess += bbtype; mess += "' unknown. Known types :"; mess += "'" + itkImageToImageFilterString + "' "; mess += "'" + vtkImageAlgorithmString + "' "; mess += "'" + vtkPolyDataAlgorithmString + "' "; throw bbfyException(mess); } } // Is a widget box ? if (BB.isAttributeSet("widget")) { mIsWidget = true; mParentBlackBox = "bbtk::WxBlackBox"; mInclude.push_back("bbtkWxBlackBox.h"); } else { mIsWidget = false; mParentBlackBox = "bbtk::AtomicBlackBox"; mInclude.push_back("bbtkAtomicBlackBox.h"); } // Author int i,j; for (i=0,j=0; i 0) { mTemplateDeclaration = "<"; mTemplateImplementation = "<"; for (i=0,j=0; i attribute 'name' not found (mandatory)"); } io.name = n.getAttribute("name"); if (!n.isAttributeSet("type")) { throw bbfyException("Error : attribute 'type' not found (mandatory)"); } io.type = n.getAttribute("type"); if (!n.isAttributeSet("description")) { throw bbfyException("Error : attribute 'description' not found (mandatory)"); } io.descr = n.getAttribute("description"); if (n.isAttributeSet("special")) { io.special = n.getAttribute("special"); } if (n.isAttributeSet("nature")) { io.nature = n.getAttribute("nature"); } if (n.isAttributeSet("generic_type")) { io.generic_type = n.getAttribute("generic_type"); } mInput.push_back(io); } // Outputs for (i=0,j=0; i attribute 'name' not found (mandatory)"); } io.name = n.getAttribute("name"); if (!n.isAttributeSet("type")) { throw bbfyException("Error : attribute 'type' not found (mandatory)"); } io.type = n.getAttribute("type"); if (!n.isAttributeSet("description")) { throw bbfyException("Error : attribute 'description' not found (mandatory)"); } io.descr = n.getAttribute("description"); if (n.isAttributeSet("special")) { io.special = n.getAttribute("special"); } if (n.isAttributeSet("nature")) { io.nature = n.getAttribute("nature"); } if (n.isAttributeSet("generic_type")) { io.generic_type = n.getAttribute("generic_type"); } mOutput.push_back(io); } // Process // process tag given ? if (BB.nChildNode("process")) { bbtk::GetTextOrClear(BB.getChildNode("process"),mProcess); } // CreateWidget // createwidget tag given ? if (BB.nChildNode("createwidget")) { bbtk::GetTextOrClear(BB.getChildNode("createwidget"),mCreateWidget); } } //========================================================================== //========================================================================== void bbfy::BeginNamespace() { // if (mIsInNamespace) // { mFile << "namespace "<::iterator i; for (i=mInclude.begin(); i!=mInclude.end(); ++i) { mFile << "#include \"" << *i <<"\"\n"; } if (mGeneric) mFile << "#include \"bbitkImage.h\"\n"; mFile << "\n"; // Namespace BeginNamespace(); // Interface // If it is a template class if (mTemplateParam.size() > 0) { mFile << "template " << mTemplateDeclaration <<"\n"; } // Class declaration and parents mFile << "class /*BBTK_EXPORT*/ "<::iterator ioi; for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi) { if (ioi->special=="") { mFile << " BBTK_DECLARE_INPUT(" << ioi->name << "," << ioi->type << ");\n"; } else if (ioi->special=="itk input") { mFile << " BBTK_DECLARE_ITK_INPUT(" << "itkParent," << ioi->name << "," << ioi->type << ");\n"; } else if (ioi->special=="vtk input") { if (mType == vtkImageAlgorithm) { mFile << " BBTK_DECLARE_VTK_IMAGE_ALGORITHM_INPUT(" << "vtkParent," << ioi->name << "," << ioi->type << ");\n"; } else if (mType == vtkPolyDataAlgorithm) { mFile << " BBTK_DECLARE_POLY_DATA_ALGORITHM_INPUT(" << "vtkParent," << ioi->name << "," << ioi->type << ");\n"; } } else if (ioi->special=="itk parameter") { mFile << " BBTK_DECLARE_ITK_PARAM(" << "itkParent," << ioi->name << "," << ioi->type << ");\n"; } else if (ioi->special=="vtk parameter") { mFile << " BBTK_DECLARE_VTK_PARAM(" << "vtkParent," << ioi->name << "," << ioi->type << ");\n"; } else { std::string mess("Error : input '"); mess += ioi->name; mess += "', 'special' attribute '"; mess += ioi->special; mess += "' unknown"; throw bbfyException(mess); } } // Outputs for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi) { if (ioi->special=="") { mFile << " BBTK_DECLARE_OUTPUT(" << ioi->name << "," << ioi->type << ");\n"; } else if (ioi->special=="itk output") { mFile << " BBTK_DECLARE_ITK_OUTPUT(" << "itkParent," << ioi->name << "," << ioi->type << ");\n"; } else if (ioi->special=="vtk output") { mFile << " BBTK_DECLARE_VTK_OUTPUT(" << "vtkParent," << ioi->name << "," << ioi->type << ");\n"; } else { std::string mess("Error : output '"); mess += ioi->name; mess += "', 'special' attribute '"; mess += ioi->special; mess += "' unknown"; throw bbfyException(mess); } } // Process if ((mType == STD)||(mProcess.size())) { mFile << " BBTK_PROCESS(Process);\n" ; mFile << " void Process();\n"; } else if (mType == itkImageToImageFilter) { mFile << " BBTK_PROCESS(itkParent::Update);\n" ; } else if ((mType == vtkImageAlgorithm) || (mType == vtkPolyDataAlgorithm) ) { mFile << " BBTK_PROCESS(vtkParent::Update);\n" ; } // CreateWidget if (mIsWidget) { mFile << " BBTK_CREATE_WIDGET(CreateWidget);\n" ; mFile << " void CreateWidget();\n"; } // EO black box declaration mFile << "};\n\n"; // BO black box description if (mTemplateParam.size()==0) { mFile << "BBTK_BEGIN_DESCRIBE_BLACK_BOX(" << mName << "," << mParentBlackBox << ");\n"; mFile << "BBTK_NAME(\"" << mName <<"\");\n"; } else if (mTemplateParam.size()==1) { mFile << "BBTK_BEGIN_DESCRIBE_TEMPLATE_BLACK_BOX(" << mName //<< "," //<< mParentBlackBox //<< "," // << mTemplateParam[0] << ");\n"; mFile << "BBTK_NAME(\"" << mName << "<\"+bbtk::TypeName<" << mTemplateParam[0] <<">()+\">\");\n"; } else { throw bbfyException("template bb with more than 1 templ param not impl"); } // Author mFile << "BBTK_AUTHOR(\""<0) { mFile << "BBTK_TEMPLATE_INPUT("; } else { mFile << "BBTK_INPUT("; } mFile << mName << "," << ioi->name << ",\"" << ioi->descr << "\"," << ioi->type << ",\"" << ioi->nature<<"\");\n"; } // Outputs for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi) { if (mTemplateParam.size()>0) { mFile << "BBTK_TEMPLATE_OUTPUT("; } else { mFile << "BBTK_OUTPUT("; } mFile << mName << "," << ioi->name << ",\"" << ioi->descr << "\"," << ioi->type << ",\"" << ioi->nature<<"\");\n"; } // EO black box description if (mTemplateParam.size()==0) { mFile << "BBTK_END_DESCRIBE_BLACK_BOX(" << mName << ");\n"; } else if (mTemplateParam.size()==1) { mFile << "BBTK_END_DESCRIBE_TEMPLATE_BLACK_BOX(" << mName //<< "," // << mTemplateParam[0] << ");\n"; } else { throw bbfyException("template bb with more than 1 templ param not impl"); } // Untemplatization of itk filters if ( mGeneric ) { WriteGenericITKFilterHeader(); } // EO namespace EndNamespace(); // Prevent multiple inclusions mFile << "#endif // " << included <<"\n"; // If is widget if (mIsWidget) { mFile << "#endif // _USE_WXWIDGETS_\n"; } // EOF mFile << "\n"; mFile.close(); } //========================================================================== //========================================================================== void bbfy::WriteGenericITKFilterHeader() { mFile << "\n//===================================================\n"; mFile << "// Generic \"untemplatized\" filter\n"; mFile << "//===================================================\n"; // Class declaration and parents mFile << "class /*BBTK_EXPORT*/ "<::iterator ioi; for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi) { mFile << " BBTK_DECLARE_INPUT(" << ioi->name << "," << ioi->generic_type << ");\n"; } // Outputs for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi) { mFile << " BBTK_DECLARE_OUTPUT(" << ioi->name << "," << ioi->generic_type << ");\n"; } // Process mFile << " BBTK_PROCESS(ProcessSwitch);\n"; mFile << " private :\n"; mFile << " inline void ProcessSwitch();\n"; mFile << " template void Process();\n"; // EO black box declaration mFile << "};\n\n"; // BO black box description mFile << "BBTK_BEGIN_DESCRIBE_BLACK_BOX(" << mName << "Generic,bbtk::AtomicBlackBox);\n"; mFile << "BBTK_NAME(\"" << mName <<"\");\n"; // Author mFile << "BBTK_AUTHOR(\""<name << ",\"" << ioi->descr << "\"," << ioi->generic_type <<");\n"; } // Outputs for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi) { mFile << "BBTK_OUTPUT("; mFile << mName << "Generic," << ioi->name << ",\"" << ioi->descr << "\"," << ioi->generic_type <<");\n"; } // EO black box description mFile << "BBTK_END_DESCRIBE_BLACK_BOX(" << mName << "Generic);\n"; //================================================================= // ProcessSwitch implementation mFile << "void "<< mName <<"Generic::ProcessSwitch()\n" << "{\n" << "CALL_FOR_ALL_TYPES_AND_DIM(bbGetInputIn()->GetType(),\n" << " bbGetInputIn()->GetDimension(),\n" << " Process);\n" << "}\n"; //================================================================= //================================================================= // Template process implementation mFile << "template \n" << "void "<()<<\",\"<()\"< ImageType;\n" << " typedef "< FilterType;\n" << " FilterType* f = new FilterType(\"Temp\");\n" << " f->bbSetInputIn( this->bbGetInputIn()->GetImage() );\n"; for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi) { if (ioi->name == "In") continue; mFile << " f->bbSetInput"<name<<" ( this->bbGetInput" << ioi->name << "() );\n"; } mFile << " f->bbUpdate();\n" << " this->bbSetOutputOut( new itkImage( f->bbGetOutputOut() ) );\n" << " f->UnRegister();\n" << " bbtkDebugDecTab(\"Kernel\",9);\n" << "}\n\n"; //================================================================= } //========================================================================== //========================================================================== void bbfy::CreateCode() { mCxxName = "bb"; mCxxName += mPackage; mCxxName += mName; mCxxName += ".cxx"; if (mVerbose) std::cout << " - Creating code '"<0) { // Implementation mFile << "BBTK_BLACK_BOX_TEMPLATE_IMPLEMENTATION(" << mName << "," << mParentBlackBox << ");\n"; if (mGeneric) { // Implementation mFile << "BBTK_BLACK_BOX_IMPLEMENTATION(" << mName << "Generic,bbtk::AtomicBlackBox);\n"; // Package mFile << "BBTK_ADD_BLACK_BOX_TO_PACKAGE(" << mPackage << "," << mName << "Generic)\n"; } } else { // Non template class // Package mFile << "BBTK_ADD_BLACK_BOX_TO_PACKAGE(" << mPackage << "," << mName << ")\n"; // Implementation mFile << "BBTK_BLACK_BOX_IMPLEMENTATION(" << mName << "," << mParentBlackBox << ");\n"; } // Process if ((mType == STD)||(mProcess.size())) { mFile << "void "<5) { std::cerr << "usage : "<< argv[0] <<" xml_file [package_name] [output_path] [-q]" << std::endl; return 1; } try { std::string package("PACKAGE_NAME"); std::string output_path(""); bool verbose = true; if (argc>2) package = argv[2]; if (argc>3) output_path = argv[3]; if (argc>4) verbose = false; bbfy B(argv[1],package,output_path,verbose); } catch (bbfyException e) { std::cerr << argv[0] << " " << argv[1] << std::endl << e.mMessage << std::endl; return 1; } return 0; } //==========================================================================