vrshoot

annotate libs/assimp/OFFLoader.cpp @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
rev   line source
nuclear@0 1 /*
nuclear@0 2 ---------------------------------------------------------------------------
nuclear@0 3 Open Asset Import Library (assimp)
nuclear@0 4 ---------------------------------------------------------------------------
nuclear@0 5
nuclear@0 6 Copyright (c) 2006-2012, assimp team
nuclear@0 7
nuclear@0 8 All rights reserved.
nuclear@0 9
nuclear@0 10 Redistribution and use of this software in source and binary forms,
nuclear@0 11 with or without modification, are permitted provided that the following
nuclear@0 12 conditions are met:
nuclear@0 13
nuclear@0 14 * Redistributions of source code must retain the above
nuclear@0 15 copyright notice, this list of conditions and the
nuclear@0 16 following disclaimer.
nuclear@0 17
nuclear@0 18 * Redistributions in binary form must reproduce the above
nuclear@0 19 copyright notice, this list of conditions and the
nuclear@0 20 following disclaimer in the documentation and/or other
nuclear@0 21 materials provided with the distribution.
nuclear@0 22
nuclear@0 23 * Neither the name of the assimp team, nor the names of its
nuclear@0 24 contributors may be used to endorse or promote products
nuclear@0 25 derived from this software without specific prior
nuclear@0 26 written permission of the assimp team.
nuclear@0 27
nuclear@0 28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
nuclear@0 29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
nuclear@0 30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
nuclear@0 31 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
nuclear@0 32 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
nuclear@0 33 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
nuclear@0 34 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
nuclear@0 35 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
nuclear@0 36 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
nuclear@0 37 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
nuclear@0 38 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
nuclear@0 39 ---------------------------------------------------------------------------
nuclear@0 40 */
nuclear@0 41
nuclear@0 42 /** @file OFFLoader.cpp
nuclear@0 43 * @brief Implementation of the OFF importer class
nuclear@0 44 */
nuclear@0 45
nuclear@0 46 #include "AssimpPCH.h"
nuclear@0 47 #ifndef ASSIMP_BUILD_NO_OFF_IMPORTER
nuclear@0 48
nuclear@0 49 // internal headers
nuclear@0 50 #include "OFFLoader.h"
nuclear@0 51 #include "ParsingUtils.h"
nuclear@0 52 #include "fast_atof.h"
nuclear@0 53
nuclear@0 54
nuclear@0 55 using namespace Assimp;
nuclear@0 56
nuclear@0 57 static const aiImporterDesc desc = {
nuclear@0 58 "OFF Importer",
nuclear@0 59 "",
nuclear@0 60 "",
nuclear@0 61 "",
nuclear@0 62 aiImporterFlags_SupportBinaryFlavour,
nuclear@0 63 0,
nuclear@0 64 0,
nuclear@0 65 0,
nuclear@0 66 0,
nuclear@0 67 "off"
nuclear@0 68 };
nuclear@0 69
nuclear@0 70 // ------------------------------------------------------------------------------------------------
nuclear@0 71 // Constructor to be privately used by Importer
nuclear@0 72 OFFImporter::OFFImporter()
nuclear@0 73 {}
nuclear@0 74
nuclear@0 75 // ------------------------------------------------------------------------------------------------
nuclear@0 76 // Destructor, private as well
nuclear@0 77 OFFImporter::~OFFImporter()
nuclear@0 78 {}
nuclear@0 79
nuclear@0 80 // ------------------------------------------------------------------------------------------------
nuclear@0 81 // Returns whether the class can handle the format of the given file.
nuclear@0 82 bool OFFImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
nuclear@0 83 {
nuclear@0 84 const std::string extension = GetExtension(pFile);
nuclear@0 85
nuclear@0 86 if (extension == "off")
nuclear@0 87 return true;
nuclear@0 88 else if (!extension.length() || checkSig)
nuclear@0 89 {
nuclear@0 90 if (!pIOHandler)return true;
nuclear@0 91 const char* tokens[] = {"off"};
nuclear@0 92 return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
nuclear@0 93 }
nuclear@0 94 return false;
nuclear@0 95 }
nuclear@0 96
nuclear@0 97 // ------------------------------------------------------------------------------------------------
nuclear@0 98 const aiImporterDesc* OFFImporter::GetInfo () const
nuclear@0 99 {
nuclear@0 100 return &desc;
nuclear@0 101 }
nuclear@0 102
nuclear@0 103 // ------------------------------------------------------------------------------------------------
nuclear@0 104 // Imports the given file into the given scene structure.
nuclear@0 105 void OFFImporter::InternReadFile( const std::string& pFile,
nuclear@0 106 aiScene* pScene, IOSystem* pIOHandler)
nuclear@0 107 {
nuclear@0 108 boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
nuclear@0 109
nuclear@0 110 // Check whether we can read from the file
nuclear@0 111 if( file.get() == NULL) {
nuclear@0 112 throw DeadlyImportError( "Failed to open OFF file " + pFile + ".");
nuclear@0 113 }
nuclear@0 114
nuclear@0 115 // allocate storage and copy the contents of the file to a memory buffer
nuclear@0 116 std::vector<char> mBuffer2;
nuclear@0 117 TextFileToBuffer(file.get(),mBuffer2);
nuclear@0 118 const char* buffer = &mBuffer2[0];
nuclear@0 119
nuclear@0 120 char line[4096];
nuclear@0 121 GetNextLine(buffer,line);
nuclear@0 122 if ('O' == line[0]) {
nuclear@0 123 GetNextLine(buffer,line); // skip the 'OFF' line
nuclear@0 124 }
nuclear@0 125
nuclear@0 126 const char* sz = line; SkipSpaces(&sz);
nuclear@0 127 const unsigned int numVertices = strtoul10(sz,&sz);SkipSpaces(&sz);
nuclear@0 128 const unsigned int numFaces = strtoul10(sz,&sz);
nuclear@0 129
nuclear@0 130 pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes = 1 ];
nuclear@0 131 aiMesh* mesh = pScene->mMeshes[0] = new aiMesh();
nuclear@0 132 aiFace* faces = mesh->mFaces = new aiFace [mesh->mNumFaces = numFaces];
nuclear@0 133
nuclear@0 134 std::vector<aiVector3D> tempPositions(numVertices);
nuclear@0 135
nuclear@0 136 // now read all vertex lines
nuclear@0 137 for (unsigned int i = 0; i< numVertices;++i)
nuclear@0 138 {
nuclear@0 139 if(!GetNextLine(buffer,line))
nuclear@0 140 {
nuclear@0 141 DefaultLogger::get()->error("OFF: The number of verts in the header is incorrect");
nuclear@0 142 break;
nuclear@0 143 }
nuclear@0 144 aiVector3D& v = tempPositions[i];
nuclear@0 145
nuclear@0 146 sz = line; SkipSpaces(&sz);
nuclear@0 147 sz = fast_atoreal_move<float>(sz,(float&)v.x); SkipSpaces(&sz);
nuclear@0 148 sz = fast_atoreal_move<float>(sz,(float&)v.y); SkipSpaces(&sz);
nuclear@0 149 fast_atoreal_move<float>(sz,(float&)v.z);
nuclear@0 150 }
nuclear@0 151
nuclear@0 152
nuclear@0 153 // First find out how many vertices we'll need
nuclear@0 154 const char* old = buffer;
nuclear@0 155 for (unsigned int i = 0; i< mesh->mNumFaces;++i)
nuclear@0 156 {
nuclear@0 157 if(!GetNextLine(buffer,line))
nuclear@0 158 {
nuclear@0 159 DefaultLogger::get()->error("OFF: The number of faces in the header is incorrect");
nuclear@0 160 break;
nuclear@0 161 }
nuclear@0 162 sz = line;SkipSpaces(&sz);
nuclear@0 163 if(!(faces->mNumIndices = strtoul10(sz,&sz)) || faces->mNumIndices > 9)
nuclear@0 164 {
nuclear@0 165 DefaultLogger::get()->error("OFF: Faces with zero indices aren't allowed");
nuclear@0 166 --mesh->mNumFaces;
nuclear@0 167 continue;
nuclear@0 168 }
nuclear@0 169 mesh->mNumVertices += faces->mNumIndices;
nuclear@0 170 ++faces;
nuclear@0 171 }
nuclear@0 172
nuclear@0 173 if (!mesh->mNumVertices)
nuclear@0 174 throw DeadlyImportError("OFF: There are no valid faces");
nuclear@0 175
nuclear@0 176 // allocate storage for the output vertices
nuclear@0 177 aiVector3D* verts = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
nuclear@0 178
nuclear@0 179 // second: now parse all face indices
nuclear@0 180 buffer = old;faces = mesh->mFaces;
nuclear@0 181 for (unsigned int i = 0, p = 0; i< mesh->mNumFaces;)
nuclear@0 182 {
nuclear@0 183 if(!GetNextLine(buffer,line))break;
nuclear@0 184
nuclear@0 185 unsigned int idx;
nuclear@0 186 sz = line;SkipSpaces(&sz);
nuclear@0 187 if(!(idx = strtoul10(sz,&sz)) || idx > 9)
nuclear@0 188 continue;
nuclear@0 189
nuclear@0 190 faces->mIndices = new unsigned int [faces->mNumIndices];
nuclear@0 191 for (unsigned int m = 0; m < faces->mNumIndices;++m)
nuclear@0 192 {
nuclear@0 193 SkipSpaces(&sz);
nuclear@0 194 if ((idx = strtoul10(sz,&sz)) >= numVertices)
nuclear@0 195 {
nuclear@0 196 DefaultLogger::get()->error("OFF: Vertex index is out of range");
nuclear@0 197 idx = numVertices-1;
nuclear@0 198 }
nuclear@0 199 faces->mIndices[m] = p++;
nuclear@0 200 *verts++ = tempPositions[idx];
nuclear@0 201 }
nuclear@0 202 ++i;
nuclear@0 203 ++faces;
nuclear@0 204 }
nuclear@0 205
nuclear@0 206 // generate the output node graph
nuclear@0 207 pScene->mRootNode = new aiNode();
nuclear@0 208 pScene->mRootNode->mName.Set("<OFFRoot>");
nuclear@0 209 pScene->mRootNode->mMeshes = new unsigned int [pScene->mRootNode->mNumMeshes = 1];
nuclear@0 210 pScene->mRootNode->mMeshes[0] = 0;
nuclear@0 211
nuclear@0 212 // generate a default material
nuclear@0 213 pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials = 1];
nuclear@0 214 aiMaterial* pcMat = new aiMaterial();
nuclear@0 215
nuclear@0 216 aiColor4D clr(0.6f,0.6f,0.6f,1.0f);
nuclear@0 217 pcMat->AddProperty(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
nuclear@0 218 pScene->mMaterials[0] = pcMat;
nuclear@0 219
nuclear@0 220 const int twosided =1;
nuclear@0 221 pcMat->AddProperty(&twosided,1,AI_MATKEY_TWOSIDED);
nuclear@0 222 }
nuclear@0 223
nuclear@0 224 #endif // !! ASSIMP_BUILD_NO_OFF_IMPORTER