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 Implementation of the STL importer class */
|
nuclear@0
|
43
|
nuclear@0
|
44 #include "AssimpPCH.h"
|
nuclear@0
|
45 #ifndef ASSIMP_BUILD_NO_STL_IMPORTER
|
nuclear@0
|
46
|
nuclear@0
|
47 // internal headers
|
nuclear@0
|
48 #include "STLLoader.h"
|
nuclear@0
|
49 #include "ParsingUtils.h"
|
nuclear@0
|
50 #include "fast_atof.h"
|
nuclear@0
|
51
|
nuclear@0
|
52 using namespace Assimp;
|
nuclear@0
|
53
|
nuclear@0
|
54 static const aiImporterDesc desc = {
|
nuclear@0
|
55 "Stereolithography (STL) Importer",
|
nuclear@0
|
56 "",
|
nuclear@0
|
57 "",
|
nuclear@0
|
58 "",
|
nuclear@0
|
59 aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour,
|
nuclear@0
|
60 0,
|
nuclear@0
|
61 0,
|
nuclear@0
|
62 0,
|
nuclear@0
|
63 0,
|
nuclear@0
|
64 "stl"
|
nuclear@0
|
65 };
|
nuclear@0
|
66
|
nuclear@0
|
67 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
68 // Constructor to be privately used by Importer
|
nuclear@0
|
69 STLImporter::STLImporter()
|
nuclear@0
|
70 {}
|
nuclear@0
|
71
|
nuclear@0
|
72 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
73 // Destructor, private as well
|
nuclear@0
|
74 STLImporter::~STLImporter()
|
nuclear@0
|
75 {}
|
nuclear@0
|
76
|
nuclear@0
|
77 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
78 // Returns whether the class can handle the format of the given file.
|
nuclear@0
|
79 bool STLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
|
nuclear@0
|
80 {
|
nuclear@0
|
81 const std::string extension = GetExtension(pFile);
|
nuclear@0
|
82
|
nuclear@0
|
83 if (extension == "stl")
|
nuclear@0
|
84 return true;
|
nuclear@0
|
85 else if (!extension.length() || checkSig) {
|
nuclear@0
|
86 if (!pIOHandler)
|
nuclear@0
|
87 return true;
|
nuclear@0
|
88 const char* tokens[] = {"STL","solid"};
|
nuclear@0
|
89 return SearchFileHeaderForToken(pIOHandler,pFile,tokens,2);
|
nuclear@0
|
90 }
|
nuclear@0
|
91 return false;
|
nuclear@0
|
92 }
|
nuclear@0
|
93
|
nuclear@0
|
94 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
95 const aiImporterDesc* STLImporter::GetInfo () const
|
nuclear@0
|
96 {
|
nuclear@0
|
97 return &desc;
|
nuclear@0
|
98 }
|
nuclear@0
|
99
|
nuclear@0
|
100 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
101 // Imports the given file into the given scene structure.
|
nuclear@0
|
102 void STLImporter::InternReadFile( const std::string& pFile,
|
nuclear@0
|
103 aiScene* pScene, IOSystem* pIOHandler)
|
nuclear@0
|
104 {
|
nuclear@0
|
105 boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
|
nuclear@0
|
106
|
nuclear@0
|
107 // Check whether we can read from the file
|
nuclear@0
|
108 if( file.get() == NULL) {
|
nuclear@0
|
109 throw DeadlyImportError( "Failed to open STL file " + pFile + ".");
|
nuclear@0
|
110 }
|
nuclear@0
|
111
|
nuclear@0
|
112 fileSize = (unsigned int)file->FileSize();
|
nuclear@0
|
113
|
nuclear@0
|
114 // allocate storage and copy the contents of the file to a memory buffer
|
nuclear@0
|
115 // (terminate it with zero)
|
nuclear@0
|
116 std::vector<char> mBuffer2;
|
nuclear@0
|
117 TextFileToBuffer(file.get(),mBuffer2);
|
nuclear@0
|
118
|
nuclear@0
|
119 this->pScene = pScene;
|
nuclear@0
|
120 this->mBuffer = &mBuffer2[0];
|
nuclear@0
|
121
|
nuclear@0
|
122 // the default vertex color is white
|
nuclear@0
|
123 clrColorDefault.r = clrColorDefault.g = clrColorDefault.b = clrColorDefault.a = 1.0f;
|
nuclear@0
|
124
|
nuclear@0
|
125 // allocate one mesh
|
nuclear@0
|
126 pScene->mNumMeshes = 1;
|
nuclear@0
|
127 pScene->mMeshes = new aiMesh*[1];
|
nuclear@0
|
128 aiMesh* pMesh = pScene->mMeshes[0] = new aiMesh();
|
nuclear@0
|
129 pMesh->mMaterialIndex = 0;
|
nuclear@0
|
130
|
nuclear@0
|
131 // allocate a single node
|
nuclear@0
|
132 pScene->mRootNode = new aiNode();
|
nuclear@0
|
133 pScene->mRootNode->mNumMeshes = 1;
|
nuclear@0
|
134 pScene->mRootNode->mMeshes = new unsigned int[1];
|
nuclear@0
|
135 pScene->mRootNode->mMeshes[0] = 0;
|
nuclear@0
|
136
|
nuclear@0
|
137 bool bMatClr = false;
|
nuclear@0
|
138
|
nuclear@0
|
139 // check whether the file starts with 'solid' -
|
nuclear@0
|
140 // in this case we can simply assume it IS a text file. finished.
|
nuclear@0
|
141 if (!::strncmp(mBuffer,"solid",5)) {
|
nuclear@0
|
142 LoadASCIIFile();
|
nuclear@0
|
143 }
|
nuclear@0
|
144 else bMatClr = LoadBinaryFile();
|
nuclear@0
|
145
|
nuclear@0
|
146 // now copy faces
|
nuclear@0
|
147 pMesh->mFaces = new aiFace[pMesh->mNumFaces];
|
nuclear@0
|
148 for (unsigned int i = 0, p = 0; i < pMesh->mNumFaces;++i) {
|
nuclear@0
|
149
|
nuclear@0
|
150 aiFace& face = pMesh->mFaces[i];
|
nuclear@0
|
151 face.mIndices = new unsigned int[face.mNumIndices = 3];
|
nuclear@0
|
152 for (unsigned int o = 0; o < 3;++o,++p) {
|
nuclear@0
|
153 face.mIndices[o] = p;
|
nuclear@0
|
154 }
|
nuclear@0
|
155 }
|
nuclear@0
|
156
|
nuclear@0
|
157 // create a single default material - everything white, as we have vertex colors
|
nuclear@0
|
158 aiMaterial* pcMat = new aiMaterial();
|
nuclear@0
|
159 aiString s;
|
nuclear@0
|
160 s.Set(AI_DEFAULT_MATERIAL_NAME);
|
nuclear@0
|
161 pcMat->AddProperty(&s, AI_MATKEY_NAME);
|
nuclear@0
|
162
|
nuclear@0
|
163 aiColor4D clrDiffuse(1.0f,1.0f,1.0f,1.0f);
|
nuclear@0
|
164 if (bMatClr) {
|
nuclear@0
|
165 clrDiffuse = clrColorDefault;
|
nuclear@0
|
166 }
|
nuclear@0
|
167 pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_DIFFUSE);
|
nuclear@0
|
168 pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_SPECULAR);
|
nuclear@0
|
169 clrDiffuse = aiColor4D(0.05f,0.05f,0.05f,1.0f);
|
nuclear@0
|
170 pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_AMBIENT);
|
nuclear@0
|
171
|
nuclear@0
|
172 pScene->mNumMaterials = 1;
|
nuclear@0
|
173 pScene->mMaterials = new aiMaterial*[1];
|
nuclear@0
|
174 pScene->mMaterials[0] = pcMat;
|
nuclear@0
|
175 }
|
nuclear@0
|
176 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
177 // Read an ASCII STL file
|
nuclear@0
|
178 void STLImporter::LoadASCIIFile()
|
nuclear@0
|
179 {
|
nuclear@0
|
180 aiMesh* pMesh = pScene->mMeshes[0];
|
nuclear@0
|
181
|
nuclear@0
|
182 const char* sz = mBuffer + 5; // skip the "solid"
|
nuclear@0
|
183 SkipSpaces(&sz);
|
nuclear@0
|
184 const char* szMe = sz;
|
nuclear@0
|
185 while (!::IsSpaceOrNewLine(*sz)) {
|
nuclear@0
|
186 sz++;
|
nuclear@0
|
187 }
|
nuclear@0
|
188
|
nuclear@0
|
189 size_t temp;
|
nuclear@0
|
190 // setup the name of the node
|
nuclear@0
|
191 if ((temp = (size_t)(sz-szMe))) {
|
nuclear@0
|
192
|
nuclear@0
|
193 pScene->mRootNode->mName.length = temp;
|
nuclear@0
|
194 memcpy(pScene->mRootNode->mName.data,szMe,temp);
|
nuclear@0
|
195 pScene->mRootNode->mName.data[temp] = '\0';
|
nuclear@0
|
196 }
|
nuclear@0
|
197 else pScene->mRootNode->mName.Set("<STL_ASCII>");
|
nuclear@0
|
198
|
nuclear@0
|
199 // try to guess how many vertices we could have
|
nuclear@0
|
200 // assume we'll need 160 bytes for each face
|
nuclear@0
|
201 pMesh->mNumVertices = ( pMesh->mNumFaces = std::max(1u,fileSize / 160u )) * 3;
|
nuclear@0
|
202 pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
|
nuclear@0
|
203 pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
|
nuclear@0
|
204
|
nuclear@0
|
205 unsigned int curFace = 0, curVertex = 3;
|
nuclear@0
|
206 for ( ;; )
|
nuclear@0
|
207 {
|
nuclear@0
|
208 // go to the next token
|
nuclear@0
|
209 if(!SkipSpacesAndLineEnd(&sz))
|
nuclear@0
|
210 {
|
nuclear@0
|
211 // seems we're finished although there was no end marker
|
nuclear@0
|
212 DefaultLogger::get()->warn("STL: unexpected EOF. \'endsolid\' keyword was expected");
|
nuclear@0
|
213 break;
|
nuclear@0
|
214 }
|
nuclear@0
|
215 // facet normal -0.13 -0.13 -0.98
|
nuclear@0
|
216 if (!strncmp(sz,"facet",5) && IsSpaceOrNewLine(*(sz+5))) {
|
nuclear@0
|
217
|
nuclear@0
|
218 if (3 != curVertex) {
|
nuclear@0
|
219 DefaultLogger::get()->warn("STL: A new facet begins but the old is not yet complete");
|
nuclear@0
|
220 }
|
nuclear@0
|
221 if (pMesh->mNumFaces == curFace) {
|
nuclear@0
|
222 ai_assert(pMesh->mNumFaces != 0);
|
nuclear@0
|
223
|
nuclear@0
|
224 // need to resize the arrays, our size estimate was wrong
|
nuclear@0
|
225 unsigned int iNeededSize = (unsigned int)(sz-mBuffer) / pMesh->mNumFaces;
|
nuclear@0
|
226 if (iNeededSize <= 160)iNeededSize >>= 1; // prevent endless looping
|
nuclear@0
|
227 unsigned int add = (unsigned int)((mBuffer+fileSize)-sz) / iNeededSize;
|
nuclear@0
|
228 add += add >> 3; // add 12.5% as buffer
|
nuclear@0
|
229 iNeededSize = (pMesh->mNumFaces + add)*3;
|
nuclear@0
|
230 aiVector3D* pv = new aiVector3D[iNeededSize];
|
nuclear@0
|
231 memcpy(pv,pMesh->mVertices,pMesh->mNumVertices*sizeof(aiVector3D));
|
nuclear@0
|
232 delete[] pMesh->mVertices;
|
nuclear@0
|
233 pMesh->mVertices = pv;
|
nuclear@0
|
234 pv = new aiVector3D[iNeededSize];
|
nuclear@0
|
235 memcpy(pv,pMesh->mNormals,pMesh->mNumVertices*sizeof(aiVector3D));
|
nuclear@0
|
236 delete[] pMesh->mNormals;
|
nuclear@0
|
237 pMesh->mNormals = pv;
|
nuclear@0
|
238
|
nuclear@0
|
239 pMesh->mNumVertices = iNeededSize;
|
nuclear@0
|
240 pMesh->mNumFaces += add;
|
nuclear@0
|
241 }
|
nuclear@0
|
242 aiVector3D* vn = &pMesh->mNormals[curFace++*3];
|
nuclear@0
|
243
|
nuclear@0
|
244 sz += 6;
|
nuclear@0
|
245 curVertex = 0;
|
nuclear@0
|
246 SkipSpaces(&sz);
|
nuclear@0
|
247 if (strncmp(sz,"normal",6)) {
|
nuclear@0
|
248 DefaultLogger::get()->warn("STL: a facet normal vector was expected but not found");
|
nuclear@0
|
249 }
|
nuclear@0
|
250 else
|
nuclear@0
|
251 {
|
nuclear@0
|
252 sz += 7;
|
nuclear@0
|
253 SkipSpaces(&sz);
|
nuclear@0
|
254 sz = fast_atoreal_move<float>(sz, (float&)vn->x );
|
nuclear@0
|
255 SkipSpaces(&sz);
|
nuclear@0
|
256 sz = fast_atoreal_move<float>(sz, (float&)vn->y );
|
nuclear@0
|
257 SkipSpaces(&sz);
|
nuclear@0
|
258 sz = fast_atoreal_move<float>(sz, (float&)vn->z );
|
nuclear@0
|
259 *(vn+1) = *vn;
|
nuclear@0
|
260 *(vn+2) = *vn;
|
nuclear@0
|
261 }
|
nuclear@0
|
262 }
|
nuclear@0
|
263 // vertex 1.50000 1.50000 0.00000
|
nuclear@0
|
264 else if (!strncmp(sz,"vertex",6) && ::IsSpaceOrNewLine(*(sz+6)))
|
nuclear@0
|
265 {
|
nuclear@0
|
266 if (3 == curVertex) {
|
nuclear@0
|
267 DefaultLogger::get()->error("STL: a facet with more than 3 vertices has been found");
|
nuclear@0
|
268 }
|
nuclear@0
|
269 else
|
nuclear@0
|
270 {
|
nuclear@0
|
271 sz += 7;
|
nuclear@0
|
272 SkipSpaces(&sz);
|
nuclear@0
|
273 aiVector3D* vn = &pMesh->mVertices[(curFace-1)*3 + curVertex++];
|
nuclear@0
|
274 sz = fast_atoreal_move<float>(sz, (float&)vn->x );
|
nuclear@0
|
275 SkipSpaces(&sz);
|
nuclear@0
|
276 sz = fast_atoreal_move<float>(sz, (float&)vn->y );
|
nuclear@0
|
277 SkipSpaces(&sz);
|
nuclear@0
|
278 sz = fast_atoreal_move<float>(sz, (float&)vn->z );
|
nuclear@0
|
279 }
|
nuclear@0
|
280 }
|
nuclear@0
|
281 else if (!::strncmp(sz,"endsolid",8)) {
|
nuclear@0
|
282 // finished!
|
nuclear@0
|
283 break;
|
nuclear@0
|
284 }
|
nuclear@0
|
285 // else skip the whole identifier
|
nuclear@0
|
286 else while (!::IsSpaceOrNewLine(*sz)) {
|
nuclear@0
|
287 ++sz;
|
nuclear@0
|
288 }
|
nuclear@0
|
289 }
|
nuclear@0
|
290
|
nuclear@0
|
291 if (!curFace) {
|
nuclear@0
|
292 pMesh->mNumFaces = 0;
|
nuclear@0
|
293 throw DeadlyImportError("STL: ASCII file is empty or invalid; no data loaded");
|
nuclear@0
|
294 }
|
nuclear@0
|
295 pMesh->mNumFaces = curFace;
|
nuclear@0
|
296 pMesh->mNumVertices = curFace*3;
|
nuclear@0
|
297 // we are finished!
|
nuclear@0
|
298 }
|
nuclear@0
|
299
|
nuclear@0
|
300 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
301 // Read a binary STL file
|
nuclear@0
|
302 bool STLImporter::LoadBinaryFile()
|
nuclear@0
|
303 {
|
nuclear@0
|
304 // skip the first 80 bytes
|
nuclear@0
|
305 if (fileSize < 84) {
|
nuclear@0
|
306 throw DeadlyImportError("STL: file is too small for the header");
|
nuclear@0
|
307 }
|
nuclear@0
|
308 bool bIsMaterialise = false;
|
nuclear@0
|
309
|
nuclear@0
|
310 // search for an occurence of "COLOR=" in the header
|
nuclear@0
|
311 const char* sz2 = (const char*)mBuffer;
|
nuclear@0
|
312 const char* const szEnd = sz2+80;
|
nuclear@0
|
313 while (sz2 < szEnd) {
|
nuclear@0
|
314
|
nuclear@0
|
315 if ('C' == *sz2++ && 'O' == *sz2++ && 'L' == *sz2++ &&
|
nuclear@0
|
316 'O' == *sz2++ && 'R' == *sz2++ && '=' == *sz2++) {
|
nuclear@0
|
317
|
nuclear@0
|
318 // read the default vertex color for facets
|
nuclear@0
|
319 bIsMaterialise = true;
|
nuclear@0
|
320 DefaultLogger::get()->info("STL: Taking code path for Materialise files");
|
nuclear@0
|
321 clrColorDefault.r = (*sz2++) / 255.0f;
|
nuclear@0
|
322 clrColorDefault.g = (*sz2++) / 255.0f;
|
nuclear@0
|
323 clrColorDefault.b = (*sz2++) / 255.0f;
|
nuclear@0
|
324 clrColorDefault.a = (*sz2++) / 255.0f;
|
nuclear@0
|
325 break;
|
nuclear@0
|
326 }
|
nuclear@0
|
327 }
|
nuclear@0
|
328 const unsigned char* sz = (const unsigned char*)mBuffer + 80;
|
nuclear@0
|
329
|
nuclear@0
|
330 // now read the number of facets
|
nuclear@0
|
331 aiMesh* pMesh = pScene->mMeshes[0];
|
nuclear@0
|
332 pScene->mRootNode->mName.Set("<STL_BINARY>");
|
nuclear@0
|
333
|
nuclear@0
|
334 pMesh->mNumFaces = *((uint32_t*)sz);
|
nuclear@0
|
335 sz += 4;
|
nuclear@0
|
336
|
nuclear@0
|
337 if (fileSize < 84 + pMesh->mNumFaces*50) {
|
nuclear@0
|
338 throw DeadlyImportError("STL: file is too small to hold all facets");
|
nuclear@0
|
339 }
|
nuclear@0
|
340
|
nuclear@0
|
341 if (!pMesh->mNumFaces) {
|
nuclear@0
|
342 throw DeadlyImportError("STL: file is empty. There are no facets defined");
|
nuclear@0
|
343 }
|
nuclear@0
|
344
|
nuclear@0
|
345 pMesh->mNumVertices = pMesh->mNumFaces*3;
|
nuclear@0
|
346
|
nuclear@0
|
347 aiVector3D* vp,*vn;
|
nuclear@0
|
348 vp = pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
|
nuclear@0
|
349 vn = pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
|
nuclear@0
|
350
|
nuclear@0
|
351 for (unsigned int i = 0; i < pMesh->mNumFaces;++i) {
|
nuclear@0
|
352
|
nuclear@0
|
353 // NOTE: Blender sometimes writes empty normals ... this is not
|
nuclear@0
|
354 // our fault ... the RemoveInvalidData helper step should fix that
|
nuclear@0
|
355 *vn = *((aiVector3D*)sz);
|
nuclear@0
|
356 sz += sizeof(aiVector3D);
|
nuclear@0
|
357 *(vn+1) = *vn;
|
nuclear@0
|
358 *(vn+2) = *vn;
|
nuclear@0
|
359 vn += 3;
|
nuclear@0
|
360
|
nuclear@0
|
361 *vp++ = *((aiVector3D*)sz);
|
nuclear@0
|
362 sz += sizeof(aiVector3D);
|
nuclear@0
|
363
|
nuclear@0
|
364 *vp++ = *((aiVector3D*)sz);
|
nuclear@0
|
365 sz += sizeof(aiVector3D);
|
nuclear@0
|
366
|
nuclear@0
|
367 *vp++ = *((aiVector3D*)sz);
|
nuclear@0
|
368 sz += sizeof(aiVector3D);
|
nuclear@0
|
369
|
nuclear@0
|
370 uint16_t color = *((uint16_t*)sz);
|
nuclear@0
|
371 sz += 2;
|
nuclear@0
|
372
|
nuclear@0
|
373 if (color & (1 << 15))
|
nuclear@0
|
374 {
|
nuclear@0
|
375 // seems we need to take the color
|
nuclear@0
|
376 if (!pMesh->mColors[0])
|
nuclear@0
|
377 {
|
nuclear@0
|
378 pMesh->mColors[0] = new aiColor4D[pMesh->mNumVertices];
|
nuclear@0
|
379 for (unsigned int i = 0; i <pMesh->mNumVertices;++i)
|
nuclear@0
|
380 *pMesh->mColors[0]++ = this->clrColorDefault;
|
nuclear@0
|
381 pMesh->mColors[0] -= pMesh->mNumVertices;
|
nuclear@0
|
382
|
nuclear@0
|
383 DefaultLogger::get()->info("STL: Mesh has vertex colors");
|
nuclear@0
|
384 }
|
nuclear@0
|
385 aiColor4D* clr = &pMesh->mColors[0][i*3];
|
nuclear@0
|
386 clr->a = 1.0f;
|
nuclear@0
|
387 if (bIsMaterialise) // this is reversed
|
nuclear@0
|
388 {
|
nuclear@0
|
389 clr->r = (color & 0x31u) / 31.0f;
|
nuclear@0
|
390 clr->g = ((color & (0x31u<<5))>>5u) / 31.0f;
|
nuclear@0
|
391 clr->b = ((color & (0x31u<<10))>>10u) / 31.0f;
|
nuclear@0
|
392 }
|
nuclear@0
|
393 else
|
nuclear@0
|
394 {
|
nuclear@0
|
395 clr->b = (color & 0x31u) / 31.0f;
|
nuclear@0
|
396 clr->g = ((color & (0x31u<<5))>>5u) / 31.0f;
|
nuclear@0
|
397 clr->r = ((color & (0x31u<<10))>>10u) / 31.0f;
|
nuclear@0
|
398 }
|
nuclear@0
|
399 // assign the color to all vertices of the face
|
nuclear@0
|
400 *(clr+1) = *clr;
|
nuclear@0
|
401 *(clr+2) = *clr;
|
nuclear@0
|
402 }
|
nuclear@0
|
403 }
|
nuclear@0
|
404 if (bIsMaterialise && !pMesh->mColors[0])
|
nuclear@0
|
405 {
|
nuclear@0
|
406 // use the color as diffuse material color
|
nuclear@0
|
407 return true;
|
nuclear@0
|
408 }
|
nuclear@0
|
409 return false;
|
nuclear@0
|
410 }
|
nuclear@0
|
411
|
nuclear@0
|
412 #endif // !! ASSIMP_BUILD_NO_STL_IMPORTER
|