osgDB::ReaderWriter::WriteResult ReaderWriterDAE::writeNode( const osg::Node& node, const std::string& fname, const osgDB::ReaderWriter::Options* options ) const { SERIALIZER(); bool bOwnDAE = false; DAE* pDAE = NULL; std::string ext( osgDB::getLowerCaseFileExtension(fname) ); if( ! acceptsExtension(ext) ) return WriteResult::FILE_NOT_HANDLED; // Process options osgDAE::daeWriter::Options pluginOptions; std::string srcDirectory( osgDB::getFilePath(node.getName().empty() ? fname : node.getName()) ); // Base dir when relativising images paths if( options ) { pDAE = (DAE*)options->getPluginData("DAE"); const std::string & baseDir = options->getPluginStringData("baseImageDir"); // Rename "srcModelPath" (and call getFilePath() on it)? if (!baseDir.empty()) srcDirectory = baseDir; const std::string & relativiseImagesPathNbUpDirs = options->getPluginStringData("DAE-relativiseImagesPathNbUpDirs"); if (!relativiseImagesPathNbUpDirs.empty()) { std::istringstream iss(relativiseImagesPathNbUpDirs); iss >> pluginOptions.relativiseImagesPathNbUpDirs; } // Sukender's note: I don't know why DAE seems to accept comma-sparated options instead of space-separated options as other ReaderWriters. However, to avoid breaking compatibility, here's a workaround: std::string optString( options->getOptionString() ); for(std::string::iterator it=optString.begin(); it!=optString.end(); ++it) { if (*it == ' ') *it = ','; } std::istringstream iss( optString ); std::string opt; //while (iss >> opt) while( std::getline( iss, opt, ',' ) ) { if( opt == "polygon") pluginOptions.usePolygons = true; else if (opt == "GoogleMode") pluginOptions.googleMode = true; else if (opt == "NoExtras") pluginOptions.writeExtras = false; else if (opt == "daeEarthTex") pluginOptions.earthTex = true; else if (opt == "daeZUpAxis") {} // Nothing (old option) else if (opt == "daeLinkOriginalTexturesNoForce") { pluginOptions.linkOrignialTextures = true; pluginOptions.forceTexture = false; } else if (opt == "daeLinkOriginalTexturesForce") { pluginOptions.linkOrignialTextures = true; pluginOptions.forceTexture = true; } else if (opt == "daeNamesUseCodepage") pluginOptions.namesUseCodepage = true; else if (!opt.empty()) { OSG_NOTICE << std::endl << "COLLADA dae plugin: unrecognized option \"" << opt << std::endl; } } }
/*------------------------------------------------------------------------ | NAME optParseOptions | | FUNCTION Parse commandline options. | | SYNOPSIS #include "shhopt.h" | void optParseOptions(int *argc, char *argv[], | optStruct opt[], int allowNegNum); | | INPUT argc Pointer to number of options. | argv Array of option-/argument-strings. | opt Array of possible options. | allowNegNum | a negative number is not to be taken as | an option. | | OUTPUT argc new argument count. | argv array with arguments removed. | | RETURNS Nothing. Aborts in case of error. | | DESCRIPTION This function checks each option in the argv-array | against strings in the opt-array, and `executes' any | matching action. Any arguments to the options are | extracted and stored in the variables or passed to | functions pointed to by entries in opt. | | Options and arguments used are removed from the argv- | array, and argc is decreased accordingly. | | Any error leads to program abortion. */ void optParseOptions(int *argc, char *argv[], optStruct opt[], int allowNegNum) { int ai, /* argv index. */ optarg, /* argv index of option argument, or -1 if none. */ mi, /* Match index in opt. */ done; char *arg, /* Pointer to argument to an option. */ *o, /* pointer to an option character */ *p; /* * Loop through all arguments. */ for (ai = 0; ai < *argc; ) { /* * "--" indicates that the rest of the argv-array does not * contain options. */ if (strcmp(argv[ai], "--") == 0) { argvRemove(argc, argv, ai); break; } if (allowNegNum && argv[ai][0] == '-' && isdigit(argv[ai][1])) { ++ai; continue; } else if (strncmp(argv[ai], "--", 2) == 0) { /* long option */ /* find matching option */ if ((mi = optMatch(opt, argv[ai] + 2, 1)) < 0) optFatal("unrecognized option `%s'\n", argv[ai]); /* possibly locate the argument to this option. */ arg = NULL; if ((p = strchr(argv[ai], '=')) != NULL) arg = p + 1; /* does this option take an argument? */ optarg = -1; if (optNeedsArgument(&opt[mi])) { /* option needs an argument. find it. */ if (!arg) { if ((optarg = ai + 1) == *argc) optFatal("option `%s' requires an argument\n", optString(&opt[mi], 1)); arg = argv[optarg]; } } else { if (arg) optFatal("option `%s' doesn't allow an argument\n", optString(&opt[mi], 1)); } /* perform the action of this option. */ optExecute(&opt[mi], arg, 1); /* remove option and any argument from the argv-array. */ if (optarg >= 0) argvRemove(argc, argv, ai); argvRemove(argc, argv, ai); } else if (*argv[ai] == '-') { /* A dash by itself is not considered an option. */ if (argv[ai][1] == '\0') { ++ai; continue; } /* Short option(s) following */ o = argv[ai] + 1; done = 0; optarg = -1; while (*o && !done) { /* find matching option */ if ((mi = optMatch(opt, o, 0)) < 0) optFatal("unrecognized option `-%c'\n", *o); /* does this option take an argument? */ optarg = -1; arg = NULL; if (optNeedsArgument(&opt[mi])) { /* option needs an argument. find it. */ arg = o + 1; if (!*arg) { if ((optarg = ai + 1) == *argc) optFatal("option `%s' requires an argument\n", optString(&opt[mi], 0)); arg = argv[optarg]; } done = 1; } /* perform the action of this option. */ optExecute(&opt[mi], arg, 0); ++o; } /* remove option and any argument from the argv-array. */ if (optarg >= 0) argvRemove(argc, argv, ai); argvRemove(argc, argv, ai); } else { /* a non-option argument */ ++ai; } } }
/*------------------------------------------------------------------------ | NAME optExecute | | FUNCTION Perform the action of an option. | | INPUT opt array of possible options. | arg argument to option, if it applies. | lng was the option given as a long option? | | RETURNS Nothing. Aborts in case of error. */ static void optExecute(optStruct *opt, char *arg, int lng) { switch (opt->type) { case OPT_FLAG: if (opt->flags & OPT_CALLFUNC) ((void (*)(void)) opt->arg)(); else *((int *) opt->arg) = 1; break; case OPT_STRING: if (opt->flags & OPT_CALLFUNC) ((void (*)(char *)) opt->arg)(arg); else *((char **) opt->arg) = arg; break; case OPT_INT: case OPT_LONG: { long tmp; char *e; tmp = strtol(arg, &e, 10); if (*e) optFatal("invalid number `%s'\n", arg); if (errno == ERANGE || (opt->type == OPT_INT && (tmp > INT_MAX || tmp < INT_MIN))) optFatal("number `%s' to `%s' out of range\n", arg, optString(opt, lng)); if (opt->type == OPT_INT) { if (opt->flags & OPT_CALLFUNC) ((void (*)(int)) opt->arg)((int) tmp); else *((int *) opt->arg) = (int) tmp; } else /* OPT_LONG */ { if (opt->flags & OPT_CALLFUNC) ((void (*)(long)) opt->arg)(tmp); else *((long *) opt->arg) = tmp; } break; } case OPT_UINT: case OPT_ULONG: { unsigned long tmp; char *e; tmp = strtoul(arg, &e, 10); if (*e) optFatal("invalid number `%s'\n", arg); if (errno == ERANGE || (opt->type == OPT_UINT && tmp > UINT_MAX)) optFatal("number `%s' to `%s' out of range\n", arg, optString(opt, lng)); if (opt->type == OPT_UINT) { if (opt->flags & OPT_CALLFUNC) ((void (*)(unsigned)) opt->arg)((unsigned) tmp); else *((unsigned *) opt->arg) = (unsigned) tmp; } else /* OPT_ULONG */ { if (opt->flags & OPT_CALLFUNC) ((void (*)(unsigned long)) opt->arg)(tmp); else *((unsigned long *) opt->arg) = tmp; } break; } default: break; } }