Changeset 11056
- Timestamp:
- 02/11/10 12:56:43 (3 years ago)
- Location:
- OpenSceneGraph/trunk/src/osgPlugins/3ds
- Files:
-
- 4 modified
-
ReaderWriter3DS.cpp (modified) (23 diffs)
-
WriterCompareTriangle.cpp (modified) (3 diffs)
-
WriterNodeVisitor.cpp (modified) (15 diffs)
-
WriterNodeVisitor.h (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
OpenSceneGraph/trunk/src/osgPlugins/3ds/ReaderWriter3DS.cpp
r10942 r11056 1 #define ENABLE_3DS_WRITER 1 // Enables the 3DS writer (the define should be removed when the writer will be stable and tested enough)2 1 3 2 #include <osg/Notify> … … 21 20 #include <osg/NodeVisitor> 22 21 23 #ifdef ENABLE_3DS_WRITER 24 #include "WriterNodeVisitor.h" 25 #endif 22 #include "WriterNodeVisitor.h" 26 23 #include "lib3ds/lib3ds.h" 27 24 #include <stdlib.h> … … 172 169 virtual ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* options) const; 173 170 virtual ReadResult readNode(std::istream& fin, const Options* options) const; 174 #if ENABLE_3DS_WRITER 171 virtual ReadResult doReadNode(std::istream& fin, const Options* options, const std::string & fileNamelib3ds) const; ///< Subfunction of readNode()s functions. 172 175 173 virtual WriteResult writeNode(const osg::Node& /*node*/,const std::string& /*fileName*/,const Options* =NULL) const; 176 174 virtual WriteResult writeNode(const osg::Node& /*node*/,std::ostream& /*fout*/,const Options* =NULL) const; 177 #endif 175 virtual WriteResult doWriteNode(const osg::Node& /*node*/,std::ostream& /*fout*/,const Options*, const std::string & fileNamelib3ds) const; 178 176 179 177 protected: 180 178 ReadResult constructFrom3dsFile(Lib3dsFile *f,const std::string& filename, const Options* options) const; 181 179 182 #if ENABLE_3DS_WRITER183 180 bool createFileObject(const osg::Node& node, Lib3dsFile * file3ds,const std::string& fileName, const osgDB::ReaderWriter::Options* options) const; 184 #endif185 181 186 182 class ReaderObject … … 221 217 { 222 218 supportsExtension("3ds","3D Studio model format"); 223 supportsOption("OutputTextureFiles","Write out the texture images to file"); 219 //supportsOption("OutputTextureFiles","Write out the texture images to file"); 220 //supportsOption("flipTexture", "flip texture upside-down"); 221 supportsOption("extended3dsFilePaths", "Keeps long texture filenames (not 8.3) when exporting 3DS, but can lead to compatibility problems."); 222 supportsOption("noMatrixTransforms", "Set the plugin to apply matrices into the mesh vertices (\"old behaviour\") instead of restoring them (\"new behaviour\"). You may use this option to avoid a few rounding errors."); 223 supportsOption("checkForEspilonIdentityMatrices", "If not set, then consider \"almost identity\" matrices to be identity ones (in case of rounding errors)."); 224 supportsOption("restoreMatrixTransformsNoMeshes", "Makes an exception to the behaviour when 'noMatrixTransforms' is not set for mesh instances. When a mesh instance has a transform on it, the reader creates a MatrixTransform above the Geode. If you don't want the hierarchy to be modified, then you can use this option to merge the transform into vertices."); 224 225 setByteOrder(); 225 226 … … 253 254 restoreMatrixTransformsNoMeshes(false) 254 255 { 255 std::istringstream iss(options->getOptionString()); 256 std::string opt; 257 while (iss >> opt) 258 { 259 if (opt == "noMatrixTransforms") 260 noMatrixTransforms = true; 261 if (opt == "checkForEspilonIdentityMatrices") 262 checkForEspilonIdentityMatrices = true; 263 if (opt == "restoreMatrixTransformsNoMeshes") 264 restoreMatrixTransformsNoMeshes = true; 256 if (options) { 257 std::istringstream iss(options->getOptionString()); 258 std::string opt; 259 while (iss >> opt) 260 { 261 if (opt == "noMatrixTransforms") 262 noMatrixTransforms = true; 263 if (opt == "checkForEspilonIdentityMatrices") 264 checkForEspilonIdentityMatrices = true; 265 if (opt == "restoreMatrixTransformsNoMeshes") 266 restoreMatrixTransformsNoMeshes = true; 267 } 265 268 } 266 269 } … … 557 560 } 558 561 559 #if ENABLE_3DS_WRITER560 562 static long fileo_seek_func(void *self, long offset, Lib3dsIoSeek origin) { 561 563 std::ostream *f = reinterpret_cast<std::ostream*>(self); … … 567 569 return f->fail() ? -1 : 0; 568 570 } 569 #endif570 571 571 572 static long filei_tell_func(void *self) { … … 574 575 } 575 576 576 #if ENABLE_3DS_WRITER577 577 static long fileo_tell_func(void *self) { 578 578 std::ostream *f = reinterpret_cast<std::ostream*>(self); 579 579 return f->tellp(); 580 580 } 581 #endif582 581 583 582 … … 588 587 } 589 588 590 #if ENABLE_3DS_WRITER591 589 static size_t fileo_write_func(void *self, const void *buffer, size_t size) { 592 590 std::ostream *f = reinterpret_cast<std::ostream*>(self); … … 594 592 return f->fail() ? 0 : size; 595 593 } 596 #endif597 594 598 595 static void fileio_log_func(void *self, Lib3dsLogLevel level, int indent, const char *msg) 599 596 { 600 597 osg::NotifySeverity l = osg::INFO; 601 if (level == LIB3DS_LOG_ERROR) l = osg::FATAL; 602 else if (level == LIB3DS_LOG_WARN) l = osg::WARN; 598 // Intentionally NOT mapping 3DS levels with OSG levels 599 if (level == LIB3DS_LOG_ERROR) l = osg::WARN; 600 else if (level == LIB3DS_LOG_WARN) l = osg::NOTICE; 603 601 else if (level == LIB3DS_LOG_INFO) l = osg::INFO; 604 602 else if (level == LIB3DS_LOG_DEBUG) l = osg::DEBUG_INFO; … … 609 607 osgDB::ReaderWriter::ReadResult ReaderWriter3DS::readNode(std::istream& fin, const osgDB::ReaderWriter::Options* options) const 610 608 { 611 osgDB::ReaderWriter::ReadResult result = ReadResult::FILE_NOT_HANDLED; 612 613 std::string optFileName = ""; 609 std::string optFileName; 614 610 if (options) 615 611 { … … 617 613 if (optFileName.empty()) optFileName = options->getPluginStringData("filename"); 618 614 } 615 return doReadNode(fin, options, optFileName); 616 } 617 618 osgDB::ReaderWriter::ReadResult ReaderWriter3DS::doReadNode(std::istream& fin, const osgDB::ReaderWriter::Options* options, const std::string & fileNamelib3ds) const 619 { 620 osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; 621 local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileNamelib3ds)); 622 623 osgDB::ReaderWriter::ReadResult result = ReadResult::FILE_NOT_HANDLED; 619 624 620 625 // Prepare io structure to tell how to read the stream … … 630 635 if (lib3ds_file_read(file3ds, &io) != 0) 631 636 { 632 result = constructFrom3dsFile(file3ds, optFileName,options);637 result = constructFrom3dsFile(file3ds,fileNamelib3ds,options); 633 638 lib3ds_file_free(file3ds); 634 639 } … … 639 644 osgDB::ReaderWriter::ReadResult ReaderWriter3DS::readNode(const std::string& file, const osgDB::ReaderWriter::Options* options) const 640 645 { 641 osgDB::ReaderWriter::ReadResult result = ReadResult::FILE_NOT_HANDLED;642 643 646 std::string ext = osgDB::getLowerCaseFileExtension(file); 644 647 if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; … … 647 650 if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; 648 651 649 Lib3dsFile *f = lib3ds_file_open(fileName.c_str() /*,options*/); 652 // Do not use the lib3ds_file_open() as: 653 // 1. It relies on FILE* instead of iostreams (less safe) 654 // 2. It doesn't allow us to set a custom log output 655 std::ifstream fin(file.c_str(), std::ios_base::in | std::ios_base::binary); 656 if (!fin.good()) return ReadResult::ERROR_IN_READING_FILE; 657 return doReadNode(fin, options, fileName); 658 /* 659 osgDB::ReaderWriter::ReadResult result = ReadResult::FILE_NOT_HANDLED; 660 Lib3dsFile *f = lib3ds_file_open(fileName.c_str()); // ,options 650 661 651 662 if (f) … … 659 670 660 671 return result; 672 */ 661 673 } 662 674 … … 1059 1071 1060 1072 1061 1062 #if ENABLE_3DS_WRITER1063 1073 osgDB::ReaderWriter::WriteResult ReaderWriter3DS::writeNode(const osg::Node& node,const std::string& fileName,const Options* options) const { 1064 1074 std::string ext = osgDB::getLowerCaseFileExtension(fileName); 1065 1075 if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED; 1066 1076 1067 //osg::notify(osg::WARN) << "!!WARNING!! 3DS write support is incomplete" << std::endl; 1068 1077 osgDB::makeDirectoryForFile(fileName.c_str()); 1078 std::ofstream fout(fileName.c_str(), std::ios_base::out | std::ios_base::binary); 1079 if (!fout.good()) return WriteResult::ERROR_IN_WRITING_FILE; 1080 return doWriteNode(node, fout, options, fileName); 1081 /* 1069 1082 bool ok = true; 1070 1083 Lib3dsFile * file3ds = lib3ds_file_new(); … … 1075 1088 local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName)); 1076 1089 1077 if (!createFileObject(node, file3ds, fileName, local_opt .get())) ok = false;1090 if (!createFileObject(node, file3ds, fileName, local_opt)) ok = false; 1078 1091 if (ok && !lib3ds_file_save(file3ds, fileName.c_str())) ok = false; 1079 1092 } catch (...) { … … 1084 1097 1085 1098 return ok ? WriteResult(WriteResult::FILE_SAVED) : WriteResult(WriteResult::ERROR_IN_WRITING_FILE); 1086 //return ok ? WriteResult(WriteResult::FILE_SAVED) : WriteResult(WriteResult::FILE_NOT_HANDLED); 1099 */ 1087 1100 } 1088 1101 … … 1090 1103 osgDB::ReaderWriter::WriteResult ReaderWriter3DS::writeNode(const osg::Node& node,std::ostream& fout,const Options* options) const { 1091 1104 //osg::notify(osg::WARN) << "!!WARNING!! 3DS write support is incomplete" << std::endl; 1092 std::string optFileName = ""; 1093 if (options) 1094 { 1105 std::string optFileName; 1106 if (options) { 1095 1107 optFileName = options->getPluginStringData("STREAM_FILENAME"); 1096 1108 } 1109 1110 return doWriteNode(node, fout, options, optFileName); 1111 } 1112 1113 osgDB::ReaderWriter::WriteResult ReaderWriter3DS::doWriteNode(const osg::Node& node,std::ostream& fout, const Options* options, const std::string & fileNamelib3ds) const { 1114 osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; 1115 local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileNamelib3ds)); 1097 1116 1098 1117 Lib3dsIo io; … … 1105 1124 1106 1125 Lib3dsFile * file3ds = lib3ds_file_new(); 1126 if (!file3ds) return WriteResult(WriteResult::ERROR_IN_WRITING_FILE); 1127 1107 1128 bool ok = true; 1108 1129 try { 1109 osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; 1110 local_opt->getDatabasePathList().push_front(osgDB::getFilePath(optFileName)); 1111 1112 if (!createFileObject(node, file3ds, optFileName, local_opt.get())) ok = false; 1130 if (!createFileObject(node, file3ds, fileNamelib3ds, local_opt.get())) ok = false; 1113 1131 if (ok && !lib3ds_file_write(file3ds, &io)) ok = false; 1114 1132 … … 1123 1141 } 1124 1142 1125 const std::string getParent(const std::string & pathBad)1126 {1127 const std::string & path = osgDB::convertFileNameToNativeStyle(pathBad);1128 1129 std::string parent = "";1130 std::string tmp = "";1131 for(std::string::const_iterator itPath = path.begin();; ++itPath)1132 {1133 if (!parent.empty())1134 parent += '\\';1135 parent += tmp;1136 tmp.clear();1137 for(;itPath != path.end() && *itPath != '\\'; ++itPath)1138 tmp += *itPath;1139 if (itPath == path.end())1140 break;1141 }1142 return parent;1143 }1144 1145 1143 bool ReaderWriter3DS::createFileObject(const osg::Node& node, Lib3dsFile * file3ds,const std::string& fileName, const osgDB::ReaderWriter::Options* options) const { 1146 WriterNodeVisitor w(file3ds, fileName, options, getParent(node.getName()));1147 const_cast<osg::Node &>(node).accept(w); // TODO Remove that ugly const_cast<>. Any idea?1144 WriterNodeVisitor w(file3ds, fileName, options, osgDB::getFilePath(node.getName())); 1145 const_cast<osg::Node &>(node).accept(w); // Ugly const_cast<> for visitor... 1148 1146 if (!w.suceedLastApply()) 1149 1147 return false; … … 1151 1149 return true; //w.good(); 1152 1150 } 1153 #endif // ENABLE_3DS_WRITER 1151 -
OpenSceneGraph/trunk/src/osgPlugins/3ds/WriterCompareTriangle.cpp
r10853 r11056 33 33 { 34 34 static const unsigned int min = 1; 35 static const unsigned int max = 5; // Number of blocks used to divide the scene (arbitrary but seems ok)36 nbVerticesX = osg::clampBetween<unsigned int>(nbVerticesX, min, max);37 nbVerticesY = osg::clampBetween<unsigned int>(nbVerticesY, min, max);38 nbVerticesZ = osg::clampBetween<unsigned int>(nbVerticesZ, min, max);35 static const unsigned int max = 5; // Number of blocks used to divide the scene (arbitrary but seems ok) 36 nbVerticesX = osg::clampBetween<unsigned int>(nbVerticesX, min, max); 37 nbVerticesY = osg::clampBetween<unsigned int>(nbVerticesY, min, max); 38 nbVerticesZ = osg::clampBetween<unsigned int>(nbVerticesZ, min, max); 39 39 } 40 40 … … 43 43 osg::BoundingBox::vec_type length = sceneBox._max - sceneBox._min; 44 44 45 static const float k = 1.3f; // Arbitrary constant multiplier for density computation ("simulates" non-uniform point distributions)46 // Computes "density" of points, and thus the number of blocks to divide the mesh into45 static const float k = 1.3f; // Arbitrary constant multiplier for density computation ("simulates" non-uniform point distributions) 46 // Computes "density" of points, and thus the number of blocks to divide the mesh into 47 47 unsigned int nbVerticesX = static_cast<unsigned int>( (nbVertices * k) / (length.z() * length.y()) ); 48 48 unsigned int nbVerticesY = static_cast<unsigned int>( (nbVertices * k) / (length.z() * length.x()) ); … … 132 132 133 133 int WriterCompareTriangle::inWhichBox(const osg::BoundingBox::vec_type & point) const { 134 return inWhichBox(point.x(), point.y(), point.z());134 return inWhichBox(point.x(), point.y(), point.z()); 135 135 } -
OpenSceneGraph/trunk/src/osgPlugins/3ds/WriterNodeVisitor.cpp
r10938 r11056 92 92 93 93 /// Tests if the given string is a path supported by 3DS format (8.3, 63 chars max). 94 bool is3DSpath(const std::string & s ) {94 bool is3DSpath(const std::string & s, bool extendedFilePaths) { 95 95 unsigned int len = s.length(); 96 96 if (len >= 64 || len == 0) return false; 97 if (extendedFilePaths) return true; // Extended paths are simply those that fits the 64 bytes buffer! 97 98 98 99 unsigned int tokenBegin = 0; … … 146 147 triangle.t3 = i3; 147 148 triangle.material = _material; 148 _listTriangles.push_back(std:: make_pair(triangle, _drawable_n));149 _listTriangles.push_back(std::pair<Triangle, unsigned int>(triangle, _drawable_n)); 149 150 } 150 151 virtual void begin(GLenum mode) … … 335 336 //break; 336 337 default: 337 osg::notify(osg::WARN) << " WriterNodeVisitor :: can't handle mode " << mode << std::endl;338 osg::notify(osg::WARN) << "3DS WriterNodeVisitor: can't handle mode " << mode << std::endl; 338 339 break; 339 340 } … … 400 401 401 402 402 std::string 403 getPathRelative(const std::string & srcBad, 404 const std::string & dstBad) 405 { 406 if(srcBad.empty()) 407 return osgDB::getSimpleFileName(dstBad); 408 const std::string & src = osgDB::convertFileNameToNativeStyle(srcBad); 409 const std::string & dst = osgDB::convertFileNameToNativeStyle(dstBad); 410 std::string::const_iterator itDst = dst.begin(); 411 std::string::const_iterator itSrc = src.begin(); 412 413 std::string result = ""; 414 415 while(itDst != dst.end()) 416 { 417 if (itSrc != src.end() && *itDst == *itSrc) 418 ++itSrc; 419 else if (!result.empty() || *itDst != '\\') 420 result += *itDst; 421 ++itDst; 422 } 423 if (itSrc != src.end()) 424 result = osgDB::getSimpleFileName(dst); 425 return result; 403 // If 'to' is in a subdirectory of 'from' then this function returns the 404 // subpath. Otherwise it just returns the file name. 405 // (Same as in FBX plugin) 406 std::string getPathRelative(const std::string& from/*directory*/, 407 const std::string& to/*file path*/) 408 { 409 410 std::string::size_type slash = to.find_last_of('/'); 411 std::string::size_type backslash = to.find_last_of('\\'); 412 if (slash == std::string::npos) 413 { 414 if (backslash == std::string::npos) return to; 415 slash = backslash; 416 } 417 else if (backslash != std::string::npos && backslash > slash) 418 { 419 slash = backslash; 420 } 421 422 if (from.empty() || from.length() > to.length()) 423 return osgDB::getSimpleFileName(to); 424 425 std::string::const_iterator itTo = to.begin(); 426 for (std::string::const_iterator itFrom = from.begin(); 427 itFrom != from.end(); ++itFrom, ++itTo) 428 { 429 char a = tolower(*itFrom), b = tolower(*itTo); 430 if (a == '\\') a = '/'; 431 if (b == '\\') b = '/'; 432 if (a != b || itTo == to.begin() + slash + 1) 433 { 434 return osgDB::getSimpleFileName(to); 435 } 436 } 437 438 while (itTo != to.end() && (*itTo == '\\' || *itTo == '/')) 439 { 440 ++itTo; 441 } 442 443 return std::string(itTo, to.end()); 426 444 } 427 445 428 446 /// Converts an extension to a 3-letters long one equivalent. 429 std::string convertExt(const std::string & path) 430 { 447 std::string convertExt(const std::string & path, bool extendedFilePaths) 448 { 449 if (extendedFilePaths) return path; // Extensions are not truncated for extended filenames 450 431 451 std::string ext = osgDB::getFileExtensionIncludingDot(path); 432 452 if (ext == ".tiff") ext = ".tif"; … … 435 455 return osgDB::getNameLessExtension(path) + ext; 436 456 } 457 458 459 WriterNodeVisitor::WriterNodeVisitor(Lib3dsFile * file3ds, const std::string & fileName, 460 const osgDB::ReaderWriter::Options* options, 461 const std::string & srcDirectory) : 462 osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), 463 _suceedLastApply(true), 464 _srcDirectory(srcDirectory), 465 file3ds(file3ds), 466 _currentStateSet(new osg::StateSet()), 467 _lastMaterialIndex(0), 468 _lastMeshIndex(0), 469 _cur3dsNode(NULL), 470 options(options), 471 _imageCount(0), 472 _extendedFilePaths(false) 473 { 474 if (!fileName.empty()) 475 _directory = options->getDatabasePathList().empty() ? osgDB::getFilePath(fileName) : options->getDatabasePathList().front(); 476 477 if (options) { 478 std::istringstream iss(options->getOptionString()); 479 std::string opt; 480 while (iss >> opt) 481 { 482 if (opt == "extended3dsFilePaths" || opt == "extended3DSFilePaths") 483 _extendedFilePaths = true; 484 } 485 } 486 } 487 437 488 438 489 void WriterNodeVisitor::writeMaterials() … … 471 522 path = getPathRelative(_srcDirectory, mat.image->getFileName()); 472 523 } 473 path = convertExt(path );474 475 if(!is3DSpath(path )) {524 path = convertExt(path, _extendedFilePaths); 525 526 if(!is3DSpath(path, _extendedFilePaths)) { 476 527 path = getUniqueName(path, "", true); 477 528 //path = osgDB::getSimpleFileName(path); … … 483 534 484 535 //if (mat.image->valid()) osgDB::writeImageFile(*(mat.image), path); 485 osgDB::writeImageFile(*(mat.image), path); 536 if(_imageSet.find(mat.image.get()) == _imageSet.end()) 537 { 538 _imageSet.insert(mat.image.get()); 539 osgDB::writeImageFile(*(mat.image), path); 540 } 486 541 if (mat.texture_transparency) tex.flags |= LIB3DS_TEXTURE_ALPHA_SOURCE; 487 542 if (mat.texture_no_tile) tex.flags |= LIB3DS_TEXTURE_NO_TILE; … … 498 553 499 554 std::string WriterNodeVisitor::getUniqueName(const std::string& _defaultValue, const std::string & _defaultPrefix, bool nameIsPath) { 500 if (_defaultPrefix.length()>=4) throw "Default prefix is too long"; // Arbitrarily defined to 3 chars. You can modify this, but you may have to change the code so that finding a number is okay, even when changing the default prefix length. 555 static const unsigned int MAX_PREFIX_LEGNTH = 4; 556 if (_defaultPrefix.length()>MAX_PREFIX_LEGNTH) throw "Default prefix is too long"; // Arbitrarily defined to 4 chars. 501 557 502 558 // Tests if default name is valid and unique 503 559 bool defaultIs83 = is83(_defaultValue); 504 bool defaultIsValid = nameIsPath ? is3DSpath(_defaultValue ) : defaultIs83;560 bool defaultIsValid = nameIsPath ? is3DSpath(_defaultValue, _extendedFilePaths) : defaultIs83; 505 561 if (defaultIsValid && _nameMap.find(_defaultValue) == _nameMap.end()) { 506 562 _nameMap.insert(_defaultValue); … … 509 565 510 566 // Handling of paths is not well done yet. Defaulting to something very simple. 511 // We should actually ensure each component is 8 chars long, and final filename is 8.3, and total is <64 chars .567 // We should actually ensure each component is 8 chars long, and final filename is 8.3, and total is <64 chars, or simply ensure total length for extended 3DS paths. 512 568 std::string defaultValue(nameIsPath ? osgDB::getSimpleFileName(_defaultValue) : _defaultValue); 513 569 std::string ext(nameIsPath ? osgDB::getFileExtensionIncludingDot(_defaultValue).substr(0, std::min<unsigned int>(_defaultValue.size(), 4)) : ""); // 4 chars = dot + 3 chars 570 if (ext == ".") ext = ""; 514 571 515 572 std::string defaultPrefix(_defaultPrefix.empty() ? "_" : _defaultPrefix); … … 517 574 unsigned int max_val = 0; 518 575 std::string truncDefaultValue = ""; 519 for (unsigned int i = 0; i < std::min<unsigned int>(defaultValue.size(), 4); ++i)576 for (unsigned int i = 0; i < std::min<unsigned int>(defaultValue.size(), MAX_PREFIX_LEGNTH); ++i) 520 577 { 521 578 if (defaultValue[i] == '.') … … 526 583 } 527 584 if (truncDefaultValue.empty()) 528 truncDefaultValue = defaultValue.substr(0, std::min<unsigned int>(defaultValue.size(), 4)); 585 truncDefaultValue = defaultValue.substr(0, std::min<unsigned int>(defaultValue.size(), MAX_PREFIX_LEGNTH)); 586 assert(truncDefaultValue.size() <= MAX_PREFIX_LEGNTH); 529 587 std::map<std::string, unsigned int>::iterator pairPrefix; 588 589 // TODO - Handle the case of extended 3DS paths and allow more than 8 chars 530 590 defaultIs83 = is83(truncDefaultValue); 531 591 if (defaultIs83) 532 592 { 533 max_val = static_cast<unsigned int>(pow(10., 8. - truncDefaultValue.length() - 1)) -1; // defaultPrefix.length()-1 because we add an underscore ("_")593 max_val = static_cast<unsigned int>(pow(10., 8. - truncDefaultValue.length())) -1; 534 594 pairPrefix = _mapPrefix.find(truncDefaultValue); 535 595 } 536 596 537 if (defaultIs83 && ( _mapPrefix.end() == pairPrefix|| pairPrefix->second <= max_val))597 if (defaultIs83 && (pairPrefix == _mapPrefix.end() || pairPrefix->second <= max_val)) 538 598 { 539 599 defaultPrefix = truncDefaultValue; … … 541 601 else 542 602 { 543 max_val = static_cast<unsigned int>(pow(10., 8. - defaultPrefix.length() - 1)) - 1; // defaultPrefix.length()-1 because we add an underscore ("_")603 max_val = static_cast<unsigned int>(pow(10., 8. - defaultPrefix.length())) -1; 544 604 pairPrefix = _mapPrefix.find(defaultPrefix); 545 605 } 546 606 547 607 unsigned int searchStart = 0; 548 if (pairPrefix != _mapPrefix.end()) 608 if (pairPrefix != _mapPrefix.end()) { 549 609 searchStart = pairPrefix->second; 610 } 550 611 551 612 for(unsigned int i = searchStart; i <= max_val; ++i) { 552 613 std::stringstream ss; 553 ss << defaultPrefix << "_" <<i;614 ss << defaultPrefix << i; 554 615 const std::string & res = ss.str(); 555 616 if (_nameMap.find(res) == _nameMap.end()) { 556 if (pairPrefix != _mapPrefix.end()) 557 { 617 if (pairPrefix != _mapPrefix.end()) { 558 618 pairPrefix->second = i + 1; 559 } 560 else 561 { 562 _mapPrefix.insert(std::make_pair(defaultPrefix, i + 1)); 619 } else { 620 _mapPrefix.insert(std::pair<std::string, unsigned int>(defaultPrefix, i + 1)); 563 621 } 564 622 _nameMap.insert(res); … … 566 624 } 567 625 } 568 if (defaultPrefix == "_") _lastGeneratedNumberedName = max_val; 626 627 // Failed finding a name 628 // Try with a shorter prefix if possible 629 if (defaultPrefix.length()>1) return getUniqueName(_defaultValue, defaultPrefix.substr(0, defaultPrefix.length()-1), nameIsPath); 630 // Try with default prefix if not arleady done 631 if (defaultPrefix != std::string("_")) return getUniqueName(_defaultValue, "_", nameIsPath); 569 632 throw "No more names available! Is default prefix too long?"; 570 633 } … … 603 666 unsigned int drawable_n) 604 667 { 605 MapIndices::iterator itIndex = index_vert.find(std:: make_pair(index, drawable_n));668 MapIndices::iterator itIndex = index_vert.find(std::pair<unsigned int, unsigned int>(index, drawable_n)); 606 669 if (itIndex == index_vert.end()) { 607 670 unsigned int indexMesh = index_vert.size(); 608 index_vert.insert(std::make_pair(std:: make_pair(index, drawable_n), indexMesh));671 index_vert.insert(std::make_pair(std::pair<unsigned int, unsigned int>(index, drawable_n), indexMesh)); 609 672 return indexMesh; 610 673 } … … 693 756 ((nbVertices) >= MAX_VERTICES-2)) 694 757 { 695 osg::notify(osg:: ALWAYS) << "Sorting elements..." << std::endl;758 osg::notify(osg::INFO) << "Sorting elements..." << std::endl; 696 759 WriterCompareTriangle cmp(geo, nbVertices); 697 760 std::sort(listTriangles.begin(), listTriangles.end(), cmp); -
OpenSceneGraph/trunk/src/osgPlugins/3ds/WriterNodeVisitor.h
r10945 r11056 42 42 #include "lib3ds/lib3ds.h" 43 43 #include "WriterCompareTriangle.h" 44 #include <set> 44 45 45 46 void copyOsgMatrixToLib3dsMatrix(Lib3dsMatrix lib3ds_matrix, const osg::Matrix& osg_matrix); … … 50 51 class WriterNodeVisitor: public osg::NodeVisitor 51 52 { 52 53 53 public: 54 54 static const unsigned int MAX_VERTICES = 65000; … … 57 57 WriterNodeVisitor(Lib3dsFile * file3ds, const std::string & fileName, 58 58 const osgDB::ReaderWriter::Options* options, 59 const std::string & srcDirectory) : 60 osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), 61 _suceedLastApply(true), 62 _srcDirectory(srcDirectory), 63 file3ds(file3ds), 64 _currentStateSet(new osg::StateSet()), 65 _lastGeneratedNumberedName(0), 66 _lastMaterialIndex(0), 67 _lastMeshIndex(0), 68 _cur3dsNode(NULL), 69 options(options), 70 _imageCount(0) 71 { 72 //supportsOption("flipTexture", "flip texture upside-down"); 73 if (!fileName.empty()) 74 _directory = options->getDatabasePathList().empty() ? osgDB::getFilePath(fileName) : options->getDatabasePathList().front(); 75 } 59 const std::string & srcDirectory); 76 60 77 61 bool suceedLastApply() const; … … 216 200 StateSetStack _stateSetStack; 217 201 osg::ref_ptr<osg::StateSet> _currentStateSet; 218 std::map<std::string, unsigned int> _mapPrefix; 202 std::map<std::string, unsigned int> _mapPrefix; ///< List of next number to use in unique name generation, for each prefix 219 203 std::set<std::string> _nameMap; 220 204 MaterialMap _materialMap; 221 unsigned int _lastGeneratedNumberedName;222 205 unsigned int _lastMaterialIndex; 223 206 unsigned int _lastMeshIndex; … … 225 208 const osgDB::ReaderWriter::Options* options; 226 209 unsigned int _imageCount; 210 bool _extendedFilePaths; 211 std::set<osg::Image *> _imageSet; 227 212 }; 228 213
