Selaa lähdekoodia

Fix : https://github.com/assimp/assimp/issues/557

Kim Kulling 10 vuotta sitten
vanhempi
commit
bc8aa18eb2
2 muutettua tiedostoa jossa 266 lisäystä ja 260 poistoa
  1. 13 7
      code/ObjFileMtlImporter.cpp
  2. 253 253
      tools/assimp_cmd/ImageExtractor.cpp

+ 13 - 7
code/ObjFileMtlImporter.cpp

@@ -162,11 +162,17 @@ void ObjFileMtlImporter::load()
             }
             }
             break;
             break;
 
 
-        case 'd':   // Alpha value
+        case 'd':   
             {
             {
-                ++m_DataIt;
-                getFloatValue( m_pModel->m_pCurrentMaterial->alpha );
-                m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
+                if( *(m_DataIt+1) == 'i' && *( m_DataIt + 2 ) == 's' && *( m_DataIt + 3 ) == 'p' ) {
+                    // A displacement map
+                    getTexture();
+                } else {
+                    // Alpha value
+                    ++m_DataIt;
+                    getFloatValue( m_pModel->m_pCurrentMaterial->alpha );
+                    m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
+                }
             }
             }
             break;
             break;
 
 
@@ -343,9 +349,9 @@ void ObjFileMtlImporter::getTexture() {
     getTextureOption(clamp);
     getTextureOption(clamp);
     m_pModel->m_pCurrentMaterial->clamp[clampIndex] = clamp;
     m_pModel->m_pCurrentMaterial->clamp[clampIndex] = clamp;
 
 
-    std::string strTexture;
-    m_DataIt = getName<DataArrayIt>( m_DataIt, m_DataItEnd, strTexture );
-    out->Set( strTexture );
+    std::string texture;
+    m_DataIt = getName<DataArrayIt>( m_DataIt, m_DataItEnd, texture );
+    out->Set( texture );
 }
 }
 
 
 /* /////////////////////////////////////////////////////////////////////////////
 /* /////////////////////////////////////////////////////////////////////////////

+ 253 - 253
tools/assimp_cmd/ImageExtractor.cpp

@@ -65,30 +65,30 @@ const char* AICMD_MSG_DUMP_HELP_E =
 // Data structure for the first header of a BMP
 // Data structure for the first header of a BMP
 struct BITMAPFILEHEADER 
 struct BITMAPFILEHEADER 
 {
 {
-	uint16_t  bfType ;
-	uint32_t  bfSize;
-	uint16_t  bfReserved1 ;
-	uint16_t  bfReserved2; 
-	uint32_t  bfOffBits; 
+    uint16_t  bfType ;
+    uint32_t  bfSize;
+    uint16_t  bfReserved1 ;
+    uint16_t  bfReserved2; 
+    uint32_t  bfOffBits; 
 } PACK_STRUCT;
 } PACK_STRUCT;
 
 
 // -----------------------------------------------------------------------------------
 // -----------------------------------------------------------------------------------
 // Data structure for the second header of a BMP
 // Data structure for the second header of a BMP
 struct BITMAPINFOHEADER
 struct BITMAPINFOHEADER
 {
 {
-	int32_t        biSize;
-	int32_t        biWidth;
-	int32_t        biHeight;
-	int16_t        biPlanes;
-	int16_t        biBitCount;
-	uint32_t       biCompression;
-	int32_t        biSizeImage;
-	int32_t        biXPelsPerMeter;
-	int32_t        biYPelsPerMeter;
-	int32_t        biClrUsed;
-	int32_t        biClrImportant;
-
-	// pixel data follows header
+    int32_t        biSize;
+    int32_t        biWidth;
+    int32_t        biHeight;
+    int16_t        biPlanes;
+    int16_t        biBitCount;
+    uint32_t       biCompression;
+    int32_t        biSizeImage;
+    int32_t        biXPelsPerMeter;
+    int32_t        biYPelsPerMeter;
+    int32_t        biClrUsed;
+    int32_t        biClrImportant;
+
+    // pixel data follows header
 } PACK_STRUCT;
 } PACK_STRUCT;
 
 
 // -----------------------------------------------------------------------------------
 // -----------------------------------------------------------------------------------
@@ -99,7 +99,7 @@ struct TGA_HEADER
     uint8_t  colourmaptype;      // type of colour map 0=none, 1=has palette
     uint8_t  colourmaptype;      // type of colour map 0=none, 1=has palette
     uint8_t  imagetype;          // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed
     uint8_t  imagetype;          // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed
 
 
-	uint16_t colourmapstart;     // first colour map entry in palette
+    uint16_t colourmapstart;     // first colour map entry in palette
     uint16_t colourmaplength;    // number of colours in palette
     uint16_t colourmaplength;    // number of colours in palette
     uint8_t  colourmapbits;      // number of bits per palette entry 15,16,24,32
     uint8_t  colourmapbits;      // number of bits per palette entry 15,16,24,32
 
 
@@ -120,258 +120,258 @@ struct TGA_HEADER
 // Save a texture as bitmap
 // Save a texture as bitmap
 int SaveAsBMP (FILE* file, const aiTexel* data, unsigned int width, unsigned int height, bool SaveAlpha = false)
 int SaveAsBMP (FILE* file, const aiTexel* data, unsigned int width, unsigned int height, bool SaveAlpha = false)
 {
 {
-	if (!file || !data) {
-		return 1;
-	}
-
-	const unsigned int numc = (SaveAlpha ? 4 : 3);
-	unsigned char* buffer = new unsigned char[width*height*numc];
-
-	for (unsigned int y = 0; y < height; ++y) {
-		for (unsigned int x = 0; x < width; ++x) {
-
-			unsigned char* s = &buffer[(y*width+x) * numc];
-			const aiTexel* t = &data  [ y*width+x];
-			s[0] = t->b;
-			s[1] = t->g;
-			s[2] = t->r;
-			if (4 == numc)
-				s[3] = t->a;
-		}
-	}
-
-	BITMAPFILEHEADER header;
-	header.bfType      = 'B' | (int('M') << 8u);
-	header.bfOffBits   = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
-	header.bfSize      = header.bfOffBits+width*height*numc;
-	header.bfReserved1 = header.bfReserved2 = 0;
-
-	fwrite(&header,sizeof(BITMAPFILEHEADER),1,file);
-
-	BITMAPINFOHEADER info;
-	info.biSize     = 40;
-	info.biWidth    = width;
-	info.biHeight   = height;
-	info.biPlanes   = 1;
-	info.biBitCount = numc<<3;
-	info.biCompression = 0;
-	info.biSizeImage   = width*height*numc;
-	info.biXPelsPerMeter = 1; // dummy
-	info.biYPelsPerMeter = 1; // dummy
-	info.biClrUsed = 0;
-	info.biClrImportant = 0;
-
-	fwrite(&info,sizeof(BITMAPINFOHEADER),1,file);
-
-	unsigned char* temp = buffer+info.biSizeImage;
-	const unsigned int row = width*numc;
-
-	for (int y = 0; temp -= row,y < info.biHeight;++y)	{
-		fwrite(temp,row,1,file);
-	}
-
-	// delete the buffer
-	delete[] buffer;
-	return 0;
+    if (!file || !data) {
+        return 1;
+    }
+
+    const unsigned int numc = (SaveAlpha ? 4 : 3);
+    unsigned char* buffer = new unsigned char[width*height*numc];
+
+    for (unsigned int y = 0; y < height; ++y) {
+        for (unsigned int x = 0; x < width; ++x) {
+
+            unsigned char* s = &buffer[(y*width+x) * numc];
+            const aiTexel* t = &data  [ y*width+x];
+            s[0] = t->b;
+            s[1] = t->g;
+            s[2] = t->r;
+            if (4 == numc)
+                s[3] = t->a;
+        }
+    }
+
+    BITMAPFILEHEADER header;
+    header.bfType      = 'B' | (int('M') << 8u);
+    header.bfOffBits   = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
+    header.bfSize      = header.bfOffBits+width*height*numc;
+    header.bfReserved1 = header.bfReserved2 = 0;
+
+    fwrite(&header,sizeof(BITMAPFILEHEADER),1,file);
+
+    BITMAPINFOHEADER info;
+    info.biSize     = 40;
+    info.biWidth    = width;
+    info.biHeight   = height;
+    info.biPlanes   = 1;
+    info.biBitCount = numc<<3;
+    info.biCompression = 0;
+    info.biSizeImage   = width*height*numc;
+    info.biXPelsPerMeter = 1; // dummy
+    info.biYPelsPerMeter = 1; // dummy
+    info.biClrUsed = 0;
+    info.biClrImportant = 0;
+
+    fwrite(&info,sizeof(BITMAPINFOHEADER),1,file);
+
+    unsigned char* temp = buffer+info.biSizeImage;
+    const unsigned int row = width*numc;
+
+    for (int y = 0; temp -= row,y < info.biHeight;++y)	{
+        fwrite(temp,row,1,file);
+    }
+
+    // delete the buffer
+    delete[] buffer;
+    return 0;
 }
 }
 
 
 // -----------------------------------------------------------------------------------
 // -----------------------------------------------------------------------------------
 // Save a texture as tga
 // Save a texture as tga
 int SaveAsTGA (FILE* file, const aiTexel* data, unsigned int width, unsigned int height)
 int SaveAsTGA (FILE* file, const aiTexel* data, unsigned int width, unsigned int height)
 {
 {
-	if (!file || !data) {
-		return 1;
-	}
-
-	TGA_HEADER head;
-	memset(&head, 0, sizeof(head));
-	head.bits   = 32;
-	head.height = (uint16_t)height;
-	head.width  = (uint16_t)width;
-	head.descriptor |= (1u<<5);
-
-	head.imagetype = 2; // actually it's RGBA
-	fwrite(&head,sizeof(TGA_HEADER),1,file);
-
-	for (unsigned int y = 0; y < height; ++y) {
-		for (unsigned int x = 0; x < width; ++x) {
-			fwrite(data + y*width+x,4,1,file);
-		}
-	}
-
-	return 0;
+    if (!file || !data) {
+        return 1;
+    }
+
+    TGA_HEADER head;
+    memset(&head, 0, sizeof(head));
+    head.bits   = 32;
+    head.height = (uint16_t)height;
+    head.width  = (uint16_t)width;
+    head.descriptor |= (1u<<5);
+
+    head.imagetype = 2; // actually it's RGBA
+    fwrite(&head,sizeof(TGA_HEADER),1,file);
+
+    for (unsigned int y = 0; y < height; ++y) {
+        for (unsigned int x = 0; x < width; ++x) {
+            fwrite(data + y*width+x,4,1,file);
+        }
+    }
+
+    return 0;
 }
 }
 
 
 // -----------------------------------------------------------------------------------
 // -----------------------------------------------------------------------------------
 // Do the texture import for a given aiTexture
 // Do the texture import for a given aiTexture
 int DoExport(const aiTexture* tx, FILE* p, const std::string& extension,
 int DoExport(const aiTexture* tx, FILE* p, const std::string& extension,
-	unsigned int flags) 
+    unsigned int flags) 
 {
 {
-	// export the image to the appropriate decoder
-	if (extension == "bmp") {
-		SaveAsBMP(p,tx->pcData,tx->mWidth,tx->mHeight,
-			(0 != (flags & AI_EXTRACT_WRITE_BMP_ALPHA)));
-	}
-	else if (extension == "tga") {
-		SaveAsTGA(p,tx->pcData,tx->mWidth,tx->mHeight);
-	}
-	else {
-		printf("assimp extract: No available texture encoder found for %s\n", extension.c_str());
-		return 1;
-	}
-	return 0;
+    // export the image to the appropriate decoder
+    if (extension == "bmp") {
+        SaveAsBMP(p,tx->pcData,tx->mWidth,tx->mHeight,
+            (0 != (flags & AI_EXTRACT_WRITE_BMP_ALPHA)));
+    }
+    else if (extension == "tga") {
+        SaveAsTGA(p,tx->pcData,tx->mWidth,tx->mHeight);
+    }
+    else {
+        printf("assimp extract: No available texture encoder found for %s\n", extension.c_str());
+        return 1;
+    }
+    return 0;
 }
 }
 
 
 // -----------------------------------------------------------------------------------
 // -----------------------------------------------------------------------------------
 // Implementation of the assimp extract utility
 // Implementation of the assimp extract utility
 int Assimp_Extract (const char* const* params, unsigned int num)
 int Assimp_Extract (const char* const* params, unsigned int num)
 {
 {
-	const char* const invalid = "assimp extract: Invalid number of arguments. See \'assimp extract --help\'\n"; 
-	if (num < 1) {
-		printf(invalid);
-		return 1;
-	}
-
-	// --help
-	if (!strcmp( params[0], "-h") || !strcmp( params[0], "--help") || !strcmp( params[0], "-?") ) {
-		printf("%s",AICMD_MSG_DUMP_HELP_E);
-		return 0;
-	}
-
-	// asssimp extract in out [options]
-	if (num < 1) {
-		printf(invalid);
-		return 1;
-	}
-
-	std::string in  = std::string(params[0]);
-	std::string out = (num > 1 ? std::string(params[1]) : "-");
-
-	// get import flags
-	ImportData import;
-	ProcessStandardArguments(import,params+1,num-1);
-
-	bool nosuffix = false;
-	unsigned int texIdx  = 0xffffffff, flags = 0;
-
-	// process other flags
-	std::string extension = "bmp";
-	for (unsigned int i = (out[0] == '-' ? 1 : 2); i < num;++i)		{
-		if (!params[i]) {
-			continue;
-		}
-
-		if (!strncmp( params[i], "-f",2)) {
-			extension = std::string(params[i]+2);
-		}
-		else if ( !strncmp( params[i], "--format=",9)) {
-			extension = std::string(params[i]+9);
-		}
-		else if ( !strcmp( params[i], "--nosuffix") || !strcmp(params[i],"-s")) {
-			nosuffix = true;
-		}
-		else if ( !strncmp( params[i], "--texture=",10)) {
-			texIdx = Assimp::strtoul10(params[i]+10);
-		}
-		else if ( !strncmp( params[i], "-t",2)) {
-			texIdx = Assimp::strtoul10(params[i]+2);
-		}
-		else if ( !strcmp( params[i], "-ba") ||  !strcmp( params[i], "--bmp-with-alpha")) {
-			flags |= AI_EXTRACT_WRITE_BMP_ALPHA;
-		}
+    const char* const invalid = "assimp extract: Invalid number of arguments. See \'assimp extract --help\'\n"; 
+    if (num < 1) {
+        printf(invalid);
+        return 1;
+    }
+
+    // --help
+    if (!strcmp( params[0], "-h") || !strcmp( params[0], "--help") || !strcmp( params[0], "-?") ) {
+        printf("%s",AICMD_MSG_DUMP_HELP_E);
+        return 0;
+    }
+
+    // asssimp extract in out [options]
+    if (num < 1) {
+        printf(invalid);
+        return 1;
+    }
+
+    std::string in  = std::string(params[0]);
+    std::string out = (num > 1 ? std::string(params[1]) : "-");
+
+    // get import flags
+    ImportData import;
+    ProcessStandardArguments(import,params+1,num-1);
+
+    bool nosuffix = false;
+    unsigned int texIdx  = 0xffffffff, flags = 0;
+
+    // process other flags
+    std::string extension = "bmp";
+    for (unsigned int i = (out[0] == '-' ? 1 : 2); i < num;++i)		{
+        if (!params[i]) {
+            continue;
+        }
+
+        if (!strncmp( params[i], "-f",2)) {
+            extension = std::string(params[i]+2);
+        }
+        else if ( !strncmp( params[i], "--format=",9)) {
+            extension = std::string(params[i]+9);
+        }
+        else if ( !strcmp( params[i], "--nosuffix") || !strcmp(params[i],"-s")) {
+            nosuffix = true;
+        }
+        else if ( !strncmp( params[i], "--texture=",10)) {
+            texIdx = Assimp::strtoul10(params[i]+10);
+        }
+        else if ( !strncmp( params[i], "-t",2)) {
+            texIdx = Assimp::strtoul10(params[i]+2);
+        }
+        else if ( !strcmp( params[i], "-ba") ||  !strcmp( params[i], "--bmp-with-alpha")) {
+            flags |= AI_EXTRACT_WRITE_BMP_ALPHA;
+        }
 #if 0
 #if 0
-		else {
-			printf("Unknown parameter: %s\n",params[i]);
-			return 10;
-		}
+        else {
+            printf("Unknown parameter: %s\n",params[i]);
+            return 10;
+        }
 #endif
 #endif
-	}
-
-	std::transform(extension.begin(),extension.end(),extension.begin(),::tolower);
-	
-	if (out[0] == '-') {
-		// take file name from input file
-		std::string::size_type s = in.find_last_of('.');
-		if (s == std::string::npos)
-			s = in.length();
-
-		out = in.substr(0,s);
-	}
-
-	// take file extension from file name, if given
-	std::string::size_type s = out.find_last_of('.');
-	if (s != std::string::npos) {
-		extension = out.substr(s+1,in.length()-(s+1));
-		out = out.substr(0,s);
-	}
-
-	// import the main model
-	const aiScene* scene = ImportModel(import,in);
-	if (!scene) {
-		printf("assimp extract: Unable to load input file %s\n",in.c_str());
-		return 5;
-	}
-
-	// get the texture(s) to be exported
-	if (texIdx != 0xffffffff) {
-
-		// check whether the requested texture is existing
-		if (texIdx >= scene->mNumTextures) {
-			::printf("assimp extract: Texture %i requested, but there are just %i textures\n",
-				texIdx, scene->mNumTextures);
-			return 6;
-		}
-	}
-	else {
-		::printf("assimp extract: Exporting %i textures\n",scene->mNumTextures);
-	}
-
-	// now write all output textures
-	for (unsigned int i = 0; i < scene->mNumTextures;++i)	{
-		if (texIdx != 0xffffffff && texIdx != i) {
-			continue;
-		}
-
-		const aiTexture* tex = scene->mTextures[i];
-		std::string out_cpy = out, out_ext = extension;
-
-		// append suffix if necessary - always if all textures are exported
-		if (!nosuffix || (texIdx == 0xffffffff)) {
-			out_cpy.append  ("_img");
-			char tmp[10];
-			Assimp::ASSIMP_itoa10(tmp,i);
-
-			out_cpy.append(std::string(tmp));
-		}
-
-		// if the texture is a compressed one, we'll export
-		// it to its native file format
-		if (!tex->mHeight) {
-			printf("assimp extract: Texture %i is compressed (%s). Writing native file format.\n",
-				i,tex->achFormatHint);
-
-			// modify file extension
-			out_ext = std::string(tex->achFormatHint);
-		}
-		out_cpy.append("."+out_ext);
-
-		// open output file
-		FILE* p = ::fopen(out_cpy.c_str(),"wb");
-		if (!p)  {
-			printf("assimp extract: Unable to open output file %s\n",out_cpy.c_str());
-			return 7;
-		}
-		int m;
-
-		if (!tex->mHeight) {
-			m = (1 != fwrite(tex->pcData,tex->mWidth,1,p));
-		}
-		else m = DoExport(tex,p,extension,flags);
-		::fclose(p);
-
-		printf("assimp extract: Wrote texture %i to %s\n",i, out_cpy.c_str());
-		if (texIdx != 0xffffffff)
-			return m;
-	}
-	return 0;
+    }
+
+    std::transform(extension.begin(),extension.end(),extension.begin(),::tolower);
+    
+    if (out[0] == '-') {
+        // take file name from input file
+        std::string::size_type s = in.find_last_of('.');
+        if (s == std::string::npos)
+            s = in.length();
+
+        out = in.substr(0,s);
+    }
+
+    // take file extension from file name, if given
+    std::string::size_type s = out.find_last_of('.');
+    if (s != std::string::npos) {
+        extension = out.substr(s+1,in.length()-(s+1));
+        out = out.substr(0,s);
+    }
+
+    // import the main model
+    const aiScene* scene = ImportModel(import,in);
+    if (!scene) {
+        printf("assimp extract: Unable to load input file %s\n",in.c_str());
+        return 5;
+    }
+
+    // get the texture(s) to be exported
+    if (texIdx != 0xffffffff) {
+
+        // check whether the requested texture is existing
+        if (texIdx >= scene->mNumTextures) {
+            ::printf("assimp extract: Texture %i requested, but there are just %i textures\n",
+                texIdx, scene->mNumTextures);
+            return 6;
+        }
+    }
+    else {
+        ::printf("assimp extract: Exporting %i textures\n",scene->mNumTextures);
+    }
+
+    // now write all output textures
+    for (unsigned int i = 0; i < scene->mNumTextures;++i)	{
+        if (texIdx != 0xffffffff && texIdx != i) {
+            continue;
+        }
+
+        const aiTexture* tex = scene->mTextures[i];
+        std::string out_cpy = out, out_ext = extension;
+
+        // append suffix if necessary - always if all textures are exported
+        if (!nosuffix || (texIdx == 0xffffffff)) {
+            out_cpy.append  ("_img");
+            char tmp[10];
+            Assimp::ASSIMP_itoa10(tmp,i);
+
+            out_cpy.append(std::string(tmp));
+        }
+
+        // if the texture is a compressed one, we'll export
+        // it to its native file format
+        if (!tex->mHeight) {
+            printf("assimp extract: Texture %i is compressed (%s). Writing native file format.\n",
+                i,tex->achFormatHint);
+
+            // modify file extension
+            out_ext = std::string(tex->achFormatHint);
+        }
+        out_cpy.append("."+out_ext);
+
+        // open output file
+        FILE* p = ::fopen(out_cpy.c_str(),"wb");
+        if (!p)  {
+            printf("assimp extract: Unable to open output file %s\n",out_cpy.c_str());
+            return 7;
+        }
+        int m;
+
+        if (!tex->mHeight) {
+            m = (1 != fwrite(tex->pcData,tex->mWidth,1,p));
+        }
+        else m = DoExport(tex,p,extension,flags);
+        ::fclose(p);
+
+        printf("assimp extract: Wrote texture %i to %s\n",i, out_cpy.c_str());
+        if (texIdx != 0xffffffff)
+            return m;
+    }
+    return 0;
 }
 }