| 
									
										
										
										
											2011-02-23 10:52:22 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |  * ***** BEGIN GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-27 20:30:35 +00:00
										 |  |  | /** \file blender/collada/MeshImporter.cpp
 | 
					
						
							|  |  |  |  *  \ingroup collada | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | #include <algorithm>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-09 21:31:32 +00:00
										 |  |  | #if !defined(WIN32) || defined(FREE_WINDOWS)
 | 
					
						
							| 
									
										
										
										
											2010-10-06 12:04:56 +00:00
										 |  |  | #include <iostream>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-12 06:25:04 +00:00
										 |  |  | /* COLLADABU_ASSERT, may be able to remove later */ | 
					
						
							|  |  |  | #include "COLLADABUPlatform.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | #include "COLLADAFWMeshPrimitive.h"
 | 
					
						
							|  |  |  | #include "COLLADAFWMeshVertexData.h"
 | 
					
						
							|  |  |  | #include "COLLADAFWPolygons.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | extern "C" { | 
					
						
							| 
									
										
										
										
											2012-08-12 17:13:07 +00:00
										 |  |  | 	#include "BKE_blender.h"
 | 
					
						
							|  |  |  | 	#include "BKE_customdata.h"
 | 
					
						
							|  |  |  | 	#include "BKE_displist.h"
 | 
					
						
							|  |  |  | 	#include "BKE_global.h"
 | 
					
						
							|  |  |  | 	#include "BKE_library.h"
 | 
					
						
							|  |  |  | 	#include "BKE_main.h"
 | 
					
						
							|  |  |  | 	#include "BKE_material.h"
 | 
					
						
							|  |  |  | 	#include "BKE_mesh.h"
 | 
					
						
							|  |  |  | 	#include "BKE_object.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	#include "BLI_listbase.h"
 | 
					
						
							|  |  |  | 	#include "BLI_math.h"
 | 
					
						
							|  |  |  | 	#include "BLI_string.h"
 | 
					
						
							|  |  |  | 	#include "BLI_edgehash.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	#include "MEM_guardedalloc.h"
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "ArmatureImporter.h"
 | 
					
						
							|  |  |  | #include "MeshImporter.h"
 | 
					
						
							|  |  |  | #include "collada_utils.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-20 12:43:10 +00:00
										 |  |  | // get node name, or fall back to original id if not present (name is optional)
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | template<class T> | 
					
						
							| 
									
										
										
										
											2013-02-08 00:27:35 +00:00
										 |  |  | static const std::string bc_get_dae_name(T *node) | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-02-08 00:27:35 +00:00
										 |  |  | 	return node->getName().size() ? node->getName(): node->getOriginalId(); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const char *bc_primTypeToStr(COLLADAFW::MeshPrimitive::PrimitiveType type) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	switch (type) { | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 		case COLLADAFW::MeshPrimitive::LINES: | 
					
						
							|  |  |  | 			return "LINES"; | 
					
						
							|  |  |  | 		case COLLADAFW::MeshPrimitive::LINE_STRIPS: | 
					
						
							|  |  |  | 			return "LINESTRIPS"; | 
					
						
							|  |  |  | 		case COLLADAFW::MeshPrimitive::POLYGONS: | 
					
						
							|  |  |  | 			return "POLYGONS"; | 
					
						
							|  |  |  | 		case COLLADAFW::MeshPrimitive::POLYLIST: | 
					
						
							|  |  |  | 			return "POLYLIST"; | 
					
						
							|  |  |  | 		case COLLADAFW::MeshPrimitive::TRIANGLES: | 
					
						
							|  |  |  | 			return "TRIANGLES"; | 
					
						
							|  |  |  | 		case COLLADAFW::MeshPrimitive::TRIANGLE_FANS: | 
					
						
							|  |  |  | 			return "TRIANGLE_FANS"; | 
					
						
							|  |  |  | 		case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS: | 
					
						
							| 
									
										
										
										
											2014-08-22 02:46:29 +02:00
										 |  |  | 			return "TRIANGLE_STRIPS"; | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 		case COLLADAFW::MeshPrimitive::POINTS: | 
					
						
							|  |  |  | 			return "POINTS"; | 
					
						
							|  |  |  | 		case COLLADAFW::MeshPrimitive::UNDEFINED_PRIMITIVE_TYPE: | 
					
						
							|  |  |  | 			return "UNDEFINED_PRIMITIVE_TYPE"; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return "UNKNOWN"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const char *bc_geomTypeToStr(COLLADAFW::Geometry::GeometryType type) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	switch (type) { | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 		case COLLADAFW::Geometry::GEO_TYPE_MESH: | 
					
						
							|  |  |  | 			return "MESH"; | 
					
						
							|  |  |  | 		case COLLADAFW::Geometry::GEO_TYPE_SPLINE: | 
					
						
							|  |  |  | 			return "SPLINE"; | 
					
						
							|  |  |  | 		case COLLADAFW::Geometry::GEO_TYPE_CONVEX_MESH: | 
					
						
							|  |  |  | 			return "CONVEX_MESH"; | 
					
						
							|  |  |  | 		case COLLADAFW::Geometry::GEO_TYPE_UNKNOWN: | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			return "UNKNOWN"; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | UVDataWrapper::UVDataWrapper(COLLADAFW::MeshVertexData& vdata) : mVData(&vdata) | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef COLLADA_DEBUG
 | 
					
						
							|  |  |  | void WVDataWrapper::print() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	fprintf(stderr, "UVs:\n"); | 
					
						
							| 
									
										
										
										
											2012-04-28 06:31:57 +00:00
										 |  |  | 	switch (mVData->getType()) { | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 		case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 			COLLADAFW::ArrayPrimitiveType<float> *values = mVData->getFloatValues(); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 			if (values->getCount()) { | 
					
						
							|  |  |  | 				for (int i = 0; i < values->getCount(); i += 2) { | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 					fprintf(stderr, "%.1f, %.1f\n", (*values)[i], (*values)[i + 1]); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 		case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 			COLLADAFW::ArrayPrimitiveType<double> *values = mVData->getDoubleValues(); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 			if (values->getCount()) { | 
					
						
							|  |  |  | 				for (int i = 0; i < values->getCount(); i += 2) { | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 					fprintf(stderr, "%.1f, %.1f\n", (float)(*values)[i], (float)(*values)[i + 1]); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	fprintf(stderr, "\n"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-06 21:37:31 +00:00
										 |  |  | void UVDataWrapper::getUV(int uv_index, float *uv) | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-07-06 21:37:31 +00:00
										 |  |  | 	int stride = mVData->getStride(0); | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 	if (stride == 0) stride = 2; | 
					
						
							| 
									
										
										
										
											2011-07-06 21:37:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-28 06:31:57 +00:00
										 |  |  | 	switch (mVData->getType()) { | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 		case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 			COLLADAFW::ArrayPrimitiveType<float> *values = mVData->getFloatValues(); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 			if (values->empty()) return; | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 			uv[0] = (*values)[uv_index * stride]; | 
					
						
							|  |  |  | 			uv[1] = (*values)[uv_index * stride + 1]; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 			 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 		case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 			COLLADAFW::ArrayPrimitiveType<double> *values = mVData->getDoubleValues(); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 			if (values->empty()) return; | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 			uv[0] = (float)(*values)[uv_index * stride]; | 
					
						
							|  |  |  | 			uv[1] = (float)(*values)[uv_index * stride + 1]; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 			 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 		case COLLADAFW::MeshVertexData::DATA_TYPE_UNKNOWN: | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			fprintf(stderr, "MeshImporter.getUV(): unknown data type\n"); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-01 14:52:10 +02:00
										 |  |  | VCOLDataWrapper::VCOLDataWrapper(COLLADAFW::MeshVertexData& vdata) : mVData(&vdata){ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void VCOLDataWrapper::get_vcol(int v_index, MLoopCol *mloopcol) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int stride = mVData->getStride(0); | 
					
						
							| 
									
										
										
										
											2014-05-08 04:53:05 +10:00
										 |  |  | 	if (stride == 0) stride = 3; | 
					
						
							| 
									
										
										
										
											2014-05-01 14:52:10 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	switch (mVData->getType()) { | 
					
						
							|  |  |  | 		case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			COLLADAFW::ArrayPrimitiveType<float> *values = mVData->getFloatValues(); | 
					
						
							|  |  |  | 			if (values->empty()) return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			mloopcol->r = FTOCHAR((*values)[v_index * stride]); | 
					
						
							|  |  |  | 			mloopcol->g = FTOCHAR((*values)[v_index * stride + 1]); | 
					
						
							|  |  |  | 			mloopcol->b = FTOCHAR((*values)[v_index * stride + 2]); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			COLLADAFW::ArrayPrimitiveType<double> *values = mVData->getDoubleValues(); | 
					
						
							|  |  |  | 			if (values->empty()) return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			mloopcol->r = FTOCHAR((*values)[v_index * stride]); | 
					
						
							|  |  |  | 			mloopcol->g = FTOCHAR((*values)[v_index * stride + 1]); | 
					
						
							|  |  |  | 			mloopcol->b = FTOCHAR((*values)[v_index * stride + 2]); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			fprintf(stderr, "VCOLDataWrapper.getvcol(): unknown data type\n"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | MeshImporter::MeshImporter(UnitConverter *unitconv, ArmatureImporter *arm, Scene *sce) : unitconverter(unitconv), scene(sce), armature_importer(arm) { | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | void MeshImporter::set_poly_indices(MPoly *mpoly, MLoop *mloop, int loop_index, unsigned int *indices, int loop_count) | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 	mpoly->loopstart = loop_index; | 
					
						
							|  |  |  | 	mpoly->totloop   = loop_count; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 	for (int index=0; index < loop_count; index++) { | 
					
						
							|  |  |  | 		mloop->v = indices[index]; | 
					
						
							|  |  |  | 		mloop++; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-01 14:52:10 +02:00
										 |  |  | void MeshImporter::set_vcol(MLoopCol *mlc, VCOLDataWrapper &vob, int loop_index, COLLADAFW::IndexList &index_list, int count) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	COLLADAFW::UIntValuesArray& indices =index_list.getIndices(); | 
					
						
							|  |  |  | 	int index; | 
					
						
							| 
									
										
										
										
											2015-01-24 01:59:09 +11:00
										 |  |  | 	for (index = 0; index < count; index++, mlc++) { | 
					
						
							| 
									
										
										
										
											2014-05-01 14:52:10 +02:00
										 |  |  | 		int v_index = indices[index+loop_index]; | 
					
						
							|  |  |  | 		vob.get_vcol(v_index,mlc); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | void MeshImporter::set_face_uv(MLoopUV *mloopuv, UVDataWrapper &uvs, | 
					
						
							|  |  |  |                                int start_index, COLLADAFW::IndexList& index_list, int count) | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	// per face vertex indices, this means for quad we have 4 indices, not 8
 | 
					
						
							|  |  |  | 	COLLADAFW::UIntValuesArray& indices = index_list.getIndices(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 	for (int index = 0; index < count; index++) { | 
					
						
							|  |  |  | 		int uv_index = indices[index+start_index]; | 
					
						
							|  |  |  | 		uvs.getUV(uv_index, mloopuv[index].uv); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef COLLADA_DEBUG
 | 
					
						
							|  |  |  | void MeshImporter::print_index_list(COLLADAFW::IndexList& index_list) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	fprintf(stderr, "Index list for \"%s\":\n", index_list.getName().c_str()); | 
					
						
							|  |  |  | 	for (int i = 0; i < index_list.getIndicesCount(); i += 2) { | 
					
						
							|  |  |  | 		fprintf(stderr, "%u, %u\n", index_list.getIndex(i), index_list.getIndex(i + 1)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	fprintf(stderr, "\n"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh)  // checks if mesh has supported primitive types: lines, polylist, triangles, triangle_fans
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-08 00:27:35 +00:00
										 |  |  | 	const std::string &name = bc_get_dae_name(mesh); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	for (unsigned i = 0; i < prim_arr.getCount(); i++) { | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		COLLADAFW::MeshPrimitive *mp = prim_arr[i]; | 
					
						
							|  |  |  | 		COLLADAFW::MeshPrimitive::PrimitiveType type = mp->getPrimitiveType(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		const char *type_str = bc_primTypeToStr(type); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		// OpenCollada passes POLYGONS type for <polylist>
 | 
					
						
							|  |  |  | 		if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 			COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 			COLLADAFW::Polygons::VertexCountArray& vca = mpvc->getGroupedVerticesVertexCountArray(); | 
					
						
							|  |  |  | 			 | 
					
						
							| 
									
										
										
										
											2012-03-28 05:03:24 +00:00
										 |  |  | 			for (unsigned int j = 0; j < vca.getCount(); j++) { | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 				int count = vca[j]; | 
					
						
							|  |  |  | 				if (count < 3) { | 
					
						
							|  |  |  | 					fprintf(stderr, "Primitive %s in %s has at least one face with vertex count < 3\n", | 
					
						
							| 
									
										
										
										
											2013-02-08 00:27:35 +00:00
										 |  |  | 					        type_str, name.c_str()); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 					return false; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-27 18:29:47 +00:00
										 |  |  | 		else if (type == COLLADAFW::MeshPrimitive::LINES) { | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | 			// TODO: Add Checker for line syntax here
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 		else if (type != COLLADAFW::MeshPrimitive::TRIANGLES && type != COLLADAFW::MeshPrimitive::TRIANGLE_FANS) { | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 			fprintf(stderr, "Primitive type %s is not supported.\n", type_str); | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (mesh->getPositions().empty()) { | 
					
						
							| 
									
										
										
										
											2013-02-08 00:27:35 +00:00
										 |  |  | 		fprintf(stderr, "Mesh %s has no vertices.\n", name.c_str()); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MeshImporter::read_vertices(COLLADAFW::Mesh *mesh, Mesh *me) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-01-27 19:39:06 +00:00
										 |  |  | 	// vertices
 | 
					
						
							|  |  |  | 	COLLADAFW::MeshVertexData& pos = mesh->getPositions(); | 
					
						
							|  |  |  | 	int stride = pos.getStride(0); | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 	if (stride == 0) stride = 3; | 
					
						
							| 
									
										
										
										
											2011-01-27 19:39:06 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	me->totvert = mesh->getPositions().getFloatValues()->getCount() / stride; | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 	me->mvert = (MVert *)CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	MVert *mvert; | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-09 21:17:14 +00:00
										 |  |  | 	for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) { | 
					
						
							| 
									
										
										
										
											2011-01-27 19:39:06 +00:00
										 |  |  | 		get_vector(mvert->co, pos, i, stride); | 
					
						
							| 
									
										
										
										
											2010-10-09 21:17:14 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | // =====================================================================
 | 
					
						
							|  |  |  | // condition 1: The Primitive has normals
 | 
					
						
							|  |  |  | // condition 2: The number of normals equals the number of faces.
 | 
					
						
							|  |  |  | // return true if both conditions apply.
 | 
					
						
							|  |  |  | // return false otherwise.
 | 
					
						
							|  |  |  | // =====================================================================
 | 
					
						
							|  |  |  | bool MeshImporter::primitive_has_useable_normals(COLLADAFW::MeshPrimitive *mp) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bool has_useable_normals = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int normals_count = mp->getNormalIndices().getCount(); | 
					
						
							|  |  |  | 	if (normals_count > 0) { | 
					
						
							|  |  |  | 		int index_count   = mp->getPositionIndices().getCount(); | 
					
						
							|  |  |  | 		if (index_count == normals_count)  | 
					
						
							|  |  |  | 			has_useable_normals = true; | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			fprintf(stderr, | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 			        "Warning: Number of normals %d is different from the number of vertices %d, skipping normals\n", | 
					
						
							|  |  |  | 			        normals_count, index_count); | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return has_useable_normals; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // =====================================================================
 | 
					
						
							|  |  |  | // Assume that only TRIANGLES, TRIANGLE_FANS, POLYLIST and POLYGONS
 | 
					
						
							|  |  |  | // have faces. (to be verified)
 | 
					
						
							|  |  |  | // =====================================================================
 | 
					
						
							|  |  |  | bool MeshImporter::primitive_has_faces(COLLADAFW::MeshPrimitive *mp) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bool has_faces = false; | 
					
						
							|  |  |  | 	int type = mp->getPrimitiveType(); | 
					
						
							|  |  |  | 	switch (type) { | 
					
						
							|  |  |  | 		case COLLADAFW::MeshPrimitive::TRIANGLES: | 
					
						
							|  |  |  | 		case COLLADAFW::MeshPrimitive::TRIANGLE_FANS: | 
					
						
							|  |  |  | 		case COLLADAFW::MeshPrimitive::POLYLIST: | 
					
						
							| 
									
										
										
										
											2013-07-19 10:40:43 +00:00
										 |  |  | 		case COLLADAFW::MeshPrimitive::POLYGONS: | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | 			has_faces = true; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		default: { | 
					
						
							|  |  |  | 			has_faces = false;  | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return has_faces; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-01 14:52:10 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | static std::string extract_vcolname(const COLLADAFW::String &collada_id) { | 
					
						
							|  |  |  | 	std::string colname =  collada_id; | 
					
						
							|  |  |  | 	int spos = colname.find("-mesh-colors-"); | 
					
						
							|  |  |  | 	if (spos != std::string::npos) { | 
					
						
							|  |  |  | 		colname = colname.substr(spos+13); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return colname; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | // =================================================================
 | 
					
						
							| 
									
										
										
										
											2012-08-11 22:12:32 +00:00
										 |  |  | // Return the number of faces by summing up
 | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | // the facecounts of the parts.
 | 
					
						
							|  |  |  | // hint: This is done because mesh->getFacesCount() does
 | 
					
						
							|  |  |  | // count loose edges as extra faces, which is not what we want here.
 | 
					
						
							|  |  |  | // =================================================================
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me) | 
					
						
							| 
									
										
										
										
											2012-08-11 22:12:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 	COLLADAFW::MeshPrimitiveArray& prim_arr = collada_mesh->getMeshPrimitives(); | 
					
						
							| 
									
										
										
										
											2014-05-01 14:52:10 +02:00
										 |  |  | 	int total_poly_count  = 0; | 
					
						
							|  |  |  | 	int total_loop_count  = 0; | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// collect edge_count and face_count from all parts
 | 
					
						
							| 
									
										
										
										
											2012-10-21 05:46:41 +00:00
										 |  |  | 	for (int i = 0; i < prim_arr.getCount(); i++) { | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | 		COLLADAFW::MeshPrimitive *mp = prim_arr[i]; | 
					
						
							|  |  |  | 		int type = mp->getPrimitiveType(); | 
					
						
							|  |  |  | 		switch (type) { | 
					
						
							|  |  |  | 			case COLLADAFW::MeshPrimitive::TRIANGLES: | 
					
						
							|  |  |  | 			case COLLADAFW::MeshPrimitive::TRIANGLE_FANS: | 
					
						
							|  |  |  | 			case COLLADAFW::MeshPrimitive::POLYLIST: | 
					
						
							| 
									
										
										
										
											2013-07-19 10:40:43 +00:00
										 |  |  | 			case COLLADAFW::MeshPrimitive::POLYGONS: | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 				COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp; | 
					
						
							|  |  |  | 				size_t prim_poly_count    = mpvc->getFaceCount(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				size_t prim_loop_count    = 0; | 
					
						
							| 
									
										
										
										
											2013-03-18 18:25:05 +00:00
										 |  |  | 				for (int index=0; index < prim_poly_count; index++) { | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 					prim_loop_count += get_vertex_count(mpvc, index); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				total_poly_count += prim_poly_count; | 
					
						
							|  |  |  | 				total_loop_count += prim_loop_count; | 
					
						
							| 
									
										
										
										
											2014-05-01 14:52:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2013-07-19 10:40:43 +00:00
										 |  |  | 			default: | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 	// Add the data containers
 | 
					
						
							|  |  |  | 	if (total_poly_count > 0) { | 
					
						
							|  |  |  | 		me->totpoly = total_poly_count; | 
					
						
							|  |  |  | 		me->totloop = total_loop_count; | 
					
						
							|  |  |  | 		me->mpoly   = (MPoly *)CustomData_add_layer(&me->pdata, CD_MPOLY, CD_CALLOC, NULL, me->totpoly); | 
					
						
							|  |  |  | 		me->mloop   = (MLoop *)CustomData_add_layer(&me->ldata, CD_MLOOP, CD_CALLOC, NULL, me->totloop); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		unsigned int totuvset = collada_mesh->getUVCoords().getInputInfosArray().getCount(); | 
					
						
							|  |  |  | 		for (int i = 0; i < totuvset; i++) { | 
					
						
							|  |  |  | 			if (collada_mesh->getUVCoords().getLength(i) == 0) { | 
					
						
							|  |  |  | 				totuvset = 0; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (totuvset > 0) { | 
					
						
							|  |  |  | 			for (int i = 0; i < totuvset; i++) { | 
					
						
							|  |  |  | 				COLLADAFW::MeshVertexData::InputInfos *info = collada_mesh->getUVCoords().getInputInfosArray()[i]; | 
					
						
							|  |  |  | 				COLLADAFW::String &uvname = info->mName; | 
					
						
							|  |  |  | 				// Allocate space for UV_data
 | 
					
						
							|  |  |  | 				CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, uvname.c_str()); | 
					
						
							|  |  |  | 				CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, me->totloop, uvname.c_str()); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			// activate the first uv map
 | 
					
						
							|  |  |  | 			me->mtpoly  = (MTexPoly *)CustomData_get_layer_n(&me->pdata, CD_MTEXPOLY, 0); | 
					
						
							|  |  |  | 			me->mloopuv = (MLoopUV *) CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, 0); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-05-01 14:52:10 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		int totcolset = collada_mesh->getColors().getInputInfosArray().getCount(); | 
					
						
							|  |  |  | 		if (totcolset > 0) { | 
					
						
							|  |  |  | 			for (int i = 0; i < totcolset; i++) { | 
					
						
							|  |  |  | 				COLLADAFW::MeshVertexData::InputInfos *info = collada_mesh->getColors().getInputInfosArray()[i]; | 
					
						
							|  |  |  | 				COLLADAFW::String colname = extract_vcolname(info->mName); | 
					
						
							|  |  |  | 				CustomData_add_layer_named(&me->ldata,CD_MLOOPCOL,CD_DEFAULT,NULL,me->totloop, colname.c_str()); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			me->mloopcol = (MLoopCol *) CustomData_get_layer_n(&me->ldata, CD_MLOOPCOL, 0); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | unsigned int MeshImporter::get_vertex_count(COLLADAFW::Polygons *mp, int index) { | 
					
						
							|  |  |  | 	int type = mp->getPrimitiveType(); | 
					
						
							|  |  |  | 	int result; | 
					
						
							|  |  |  | 	switch (type) { | 
					
						
							|  |  |  | 		case COLLADAFW::MeshPrimitive::TRIANGLES: | 
					
						
							| 
									
										
										
										
											2013-07-19 10:40:43 +00:00
										 |  |  | 		case COLLADAFW::MeshPrimitive::TRIANGLE_FANS: | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 			result = 3; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		case COLLADAFW::MeshPrimitive::POLYLIST: | 
					
						
							| 
									
										
										
										
											2013-07-19 10:40:43 +00:00
										 |  |  | 		case COLLADAFW::MeshPrimitive::POLYGONS: | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 			result = mp->getGroupedVerticesVertexCountArray()[index]; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-07-19 10:40:43 +00:00
										 |  |  | 		default: | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 			result = -1; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | unsigned int MeshImporter::get_loose_edge_count(COLLADAFW::Mesh *mesh) { | 
					
						
							|  |  |  | 	COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives(); | 
					
						
							|  |  |  | 	int loose_edge_count = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// collect edge_count and face_count from all parts
 | 
					
						
							| 
									
										
										
										
											2012-10-21 05:46:41 +00:00
										 |  |  | 	for (int i = 0; i < prim_arr.getCount(); i++) { | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | 		COLLADAFW::MeshPrimitive *mp = prim_arr[i]; | 
					
						
							|  |  |  | 		int type = mp->getPrimitiveType(); | 
					
						
							|  |  |  | 		switch (type) { | 
					
						
							| 
									
										
										
										
											2013-07-19 10:40:43 +00:00
										 |  |  | 			case COLLADAFW::MeshPrimitive::LINES: | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | 				size_t prim_totface = mp->getFaceCount(); | 
					
						
							|  |  |  | 				loose_edge_count += prim_totface; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2013-07-19 10:40:43 +00:00
										 |  |  | 			default: | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return loose_edge_count; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // =================================================================
 | 
					
						
							|  |  |  | // This functin is copied from source/blender/editors/mesh/mesh_data.c
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // TODO: (As discussed with sergey-) :
 | 
					
						
							|  |  |  | // Maybe move this function to blenderkernel/intern/mesh.c 
 | 
					
						
							|  |  |  | // and add definition to BKE_mesh.c
 | 
					
						
							|  |  |  | // =================================================================
 | 
					
						
							|  |  |  | void MeshImporter::mesh_add_edges(Mesh *mesh, int len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	CustomData edata; | 
					
						
							|  |  |  | 	MEdge *medge; | 
					
						
							|  |  |  | 	int i, totedge; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (len == 0) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	totedge = mesh->totedge + len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* update customdata  */ | 
					
						
							|  |  |  | 	CustomData_copy(&mesh->edata, &edata, CD_MASK_MESH, CD_DEFAULT, totedge); | 
					
						
							|  |  |  | 	CustomData_copy_data(&mesh->edata, &edata, 0, 0, mesh->totedge); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!CustomData_has_layer(&edata, CD_MEDGE)) | 
					
						
							|  |  |  | 		CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	CustomData_free(&mesh->edata, mesh->totedge); | 
					
						
							|  |  |  | 	mesh->edata = edata; | 
					
						
							| 
									
										
										
										
											2013-03-17 19:55:10 +00:00
										 |  |  | 	BKE_mesh_update_customdata_pointers(mesh, false); /* new edges don't change tessellation */ | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* set default flags */ | 
					
						
							|  |  |  | 	medge = &mesh->medge[mesh->totedge]; | 
					
						
							|  |  |  | 	for (i = 0; i < len; i++, medge++) | 
					
						
							|  |  |  | 		medge->flag = ME_EDGEDRAW | ME_EDGERENDER | SELECT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mesh->totedge = totedge; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // =================================================================
 | 
					
						
							|  |  |  | // Read all loose edges.
 | 
					
						
							|  |  |  | // Important: This function assumes that all edges from existing 
 | 
					
						
							|  |  |  | // faces have allready been generated and added to me->medge
 | 
					
						
							|  |  |  | // So this function MUST be called after read_faces() (see below)
 | 
					
						
							|  |  |  | // =================================================================
 | 
					
						
							|  |  |  | void MeshImporter::read_lines(COLLADAFW::Mesh *mesh, Mesh *me) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned int loose_edge_count = get_loose_edge_count(mesh); | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 	if (loose_edge_count > 0) { | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		unsigned int face_edge_count  = me->totedge; | 
					
						
							| 
									
										
										
										
											2012-09-03 22:04:14 +00:00
										 |  |  | 		/* unsigned int total_edge_count = loose_edge_count + face_edge_count; */ /* UNUSED */ | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		mesh_add_edges(me, loose_edge_count); | 
					
						
							|  |  |  | 		MEdge *med = me->medge + face_edge_count; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (int i = 0; i < prim_arr.getCount(); i++) { | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			COLLADAFW::MeshPrimitive *mp = prim_arr[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			int type = mp->getPrimitiveType(); | 
					
						
							| 
									
										
										
										
											2012-06-27 18:29:47 +00:00
										 |  |  | 			if (type == COLLADAFW::MeshPrimitive::LINES) { | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | 				unsigned int edge_count  = mp->getFaceCount(); | 
					
						
							|  |  |  | 				unsigned int *indices    = mp->getPositionIndices().getData(); | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				for (int i = 0; i < edge_count; i++, med++) { | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 					med->bweight = 0; | 
					
						
							|  |  |  | 					med->crease  = 0; | 
					
						
							| 
									
										
										
										
											2012-12-06 06:13:43 +00:00
										 |  |  | 					med->flag   |= ME_LOOSEEDGE; | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 					med->v1      = indices[2 * i]; | 
					
						
							|  |  |  | 					med->v2      = indices[2 * i + 1]; | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // =======================================================================
 | 
					
						
							|  |  |  | // Read all faces from TRIANGLES, TRIANGLE_FANS, POLYLIST, POLYGON
 | 
					
						
							|  |  |  | // Important: This function MUST be called before read_lines() 
 | 
					
						
							|  |  |  | // Otherwise we will loose all edges from faces (see read_lines() above)
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | // TODO: import uv set names
 | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | // ========================================================================
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me) | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	unsigned int i; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 	allocate_poly_data(collada_mesh, me); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 	UVDataWrapper uvs(collada_mesh->getUVCoords()); | 
					
						
							| 
									
										
										
										
											2014-05-01 14:52:10 +02:00
										 |  |  | 	VCOLDataWrapper vcol(collada_mesh->getColors()); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 	MPoly *mpoly = me->mpoly; | 
					
						
							|  |  |  | 	MLoop *mloop = me->mloop; | 
					
						
							|  |  |  | 	int loop_index = 0; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	MaterialIdPrimitiveArrayMap mat_prim_map; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 	COLLADAFW::MeshPrimitiveArray& prim_arr = collada_mesh->getMeshPrimitives(); | 
					
						
							|  |  |  | 	COLLADAFW::MeshVertexData& nor = collada_mesh->getNormals(); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < prim_arr.getCount(); i++) { | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		COLLADAFW::MeshPrimitive *mp = prim_arr[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// faces
 | 
					
						
							| 
									
										
										
										
											2014-05-01 14:52:10 +02:00
										 |  |  | 		size_t prim_totpoly                           = mp->getFaceCount(); | 
					
						
							|  |  |  | 		unsigned int *position_indices                = mp->getPositionIndices().getData(); | 
					
						
							|  |  |  | 		unsigned int *normal_indices                  = mp->getNormalIndices().getData(); | 
					
						
							| 
									
										
										
										
											2011-03-08 13:26:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | 		bool mp_has_normals = primitive_has_useable_normals(mp); | 
					
						
							|  |  |  | 		bool mp_has_faces   = primitive_has_faces(mp); | 
					
						
							| 
									
										
										
										
											2011-03-08 13:26:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 		int collada_meshtype = mp->getPrimitiveType(); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2013-03-04 13:12:56 +00:00
										 |  |  | 		// since we cannot set mpoly->mat_nr here, we store a portion of me->mpoly in Primitive
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 		Primitive prim = {mpoly, 0}; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-08 13:26:41 +00:00
										 |  |  | 		// If MeshPrimitive is TRIANGLE_FANS we split it into triangles
 | 
					
						
							|  |  |  | 		// The first trifan vertex will be the first vertex in every triangle
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 		// XXX The proper function of TRIANGLE_FANS is not tested!!!
 | 
					
						
							|  |  |  | 		// XXX In particular the handling of the normal_indices looks very wrong to me
 | 
					
						
							|  |  |  | 		if (collada_meshtype == COLLADAFW::MeshPrimitive::TRIANGLE_FANS) { | 
					
						
							| 
									
										
										
										
											2011-03-08 13:26:41 +00:00
										 |  |  | 			unsigned grouped_vertex_count = mp->getGroupedVertexElementsCount(); | 
					
						
							| 
									
										
										
										
											2012-03-28 05:03:24 +00:00
										 |  |  | 			for (unsigned int group_index = 0; group_index < grouped_vertex_count; group_index++) { | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 				unsigned int first_vertex = position_indices[0]; // Store first trifan vertex
 | 
					
						
							|  |  |  | 				unsigned int first_normal = normal_indices[0]; // Store first trifan vertex normal
 | 
					
						
							| 
									
										
										
										
											2011-03-08 13:26:41 +00:00
										 |  |  | 				unsigned int vertex_count = mp->getGroupedVerticesVertexCount(group_index); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-28 05:03:24 +00:00
										 |  |  | 				for (unsigned int vertex_index = 0; vertex_index < vertex_count - 2; vertex_index++) { | 
					
						
							| 
									
										
										
										
											2011-03-08 13:26:41 +00:00
										 |  |  | 					// For each triangle store indeces of its 3 vertices
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 					unsigned int triangle_vertex_indices[3] = {first_vertex, position_indices[1], position_indices[2]}; | 
					
						
							|  |  |  | 					set_poly_indices(mpoly, mloop, loop_index, triangle_vertex_indices, 3); | 
					
						
							| 
									
										
										
										
											2011-03-08 13:26:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | 					if (mp_has_normals) {  // vertex normals, same inplementation as for the triangles
 | 
					
						
							| 
									
										
										
										
											2011-03-08 13:26:41 +00:00
										 |  |  | 						// the same for vertces normals
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 						unsigned int vertex_normal_indices[3] = {first_normal, normal_indices[1], normal_indices[2]}; | 
					
						
							|  |  |  | 						if (!is_flat_face(vertex_normal_indices, nor, 3)) | 
					
						
							|  |  |  | 							mpoly->flag |= ME_SMOOTH; | 
					
						
							|  |  |  | 						normal_indices++; | 
					
						
							| 
									
										
										
										
											2011-03-08 13:26:41 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 					mpoly++; | 
					
						
							|  |  |  | 					mloop += 3; | 
					
						
							|  |  |  | 					loop_index += 3; | 
					
						
							|  |  |  | 					prim.totpoly++; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-08 13:26:41 +00:00
										 |  |  | 				// Moving cursor  to the next triangle fan.
 | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | 				if (mp_has_normals) | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 					normal_indices += 2; | 
					
						
							| 
									
										
										
										
											2011-03-08 13:26:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 				position_indices +=  2; | 
					
						
							| 
									
										
										
										
											2011-03-08 13:26:41 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 		if (collada_meshtype == COLLADAFW::MeshPrimitive::POLYLIST || | 
					
						
							|  |  |  | 			collada_meshtype == COLLADAFW::MeshPrimitive::POLYGONS || | 
					
						
							|  |  |  | 			collada_meshtype == COLLADAFW::MeshPrimitive::TRIANGLES) { | 
					
						
							|  |  |  | 			COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp; | 
					
						
							| 
									
										
										
										
											2013-04-18 21:40:06 +00:00
										 |  |  | 			unsigned int start_index = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-01 14:52:10 +02:00
										 |  |  | 			COLLADAFW::IndexListArray& index_list_array_uvcoord = mp->getUVCoordIndicesArray(); | 
					
						
							|  |  |  | 			COLLADAFW::IndexListArray& index_list_array_vcolor  = mp->getColorIndicesArray(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 			for (unsigned int j = 0; j < prim_totpoly; j++) { | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 				 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 				// Vertices in polygon:
 | 
					
						
							|  |  |  | 				int vcount = get_vertex_count(mpvc, j); | 
					
						
							|  |  |  | 				set_poly_indices(mpoly, mloop, loop_index, position_indices, vcount); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-01 14:52:10 +02:00
										 |  |  | 				for (unsigned int uvset_index = 0; uvset_index < index_list_array_uvcoord.getCount(); uvset_index++) { | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 					// get mtface by face index and uv set index
 | 
					
						
							| 
									
										
										
										
											2014-05-01 14:52:10 +02:00
										 |  |  | 					COLLADAFW::IndexList& index_list = *index_list_array_uvcoord[uvset_index]; | 
					
						
							| 
									
										
										
										
											2014-02-08 13:14:58 +01:00
										 |  |  | 					MLoopUV  *mloopuv = (MLoopUV  *)CustomData_get_layer_named(&me->ldata, CD_MLOOPUV, index_list.getName().c_str()); | 
					
						
							|  |  |  | 					if (mloopuv == NULL) { | 
					
						
							| 
									
										
										
										
											2014-05-01 14:52:10 +02:00
										 |  |  | 						fprintf(stderr, "Collada import: Mesh [%s] : Unknown reference to TEXCOORD [#%s].\n", me->id.name, index_list.getName().c_str() ); | 
					
						
							| 
									
										
										
										
											2014-02-08 13:14:58 +01:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							| 
									
										
										
										
											2014-05-01 14:52:10 +02:00
										 |  |  | 						set_face_uv(mloopuv+loop_index, uvs, start_index, *index_list_array_uvcoord[uvset_index], vcount); | 
					
						
							| 
									
										
										
										
											2014-02-08 13:14:58 +01:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 				if (mp_has_normals) { | 
					
						
							|  |  |  | 					if (!is_flat_face(normal_indices, nor, vcount)) | 
					
						
							|  |  |  | 						mpoly->flag |= ME_SMOOTH; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-05-01 14:52:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-24 01:59:09 +11:00
										 |  |  | 				for (unsigned int vcolor_index = 0 ; vcolor_index < index_list_array_vcolor.getCount();vcolor_index++) { | 
					
						
							| 
									
										
										
										
											2014-05-01 14:52:10 +02:00
										 |  |  | 					COLLADAFW::IndexList& index_list = *index_list_array_vcolor[vcolor_index]; | 
					
						
							|  |  |  | 					COLLADAFW::String colname = extract_vcolname(index_list.getName()); | 
					
						
							|  |  |  | 					MLoopCol *mloopcol = (MLoopCol  *)CustomData_get_layer_named(&me->ldata, CD_MLOOPCOL, colname.c_str()); | 
					
						
							|  |  |  | 					if (mloopcol == NULL) { | 
					
						
							|  |  |  | 						fprintf(stderr, "Collada import: Mesh [%s] : Unknown reference to VCOLOR [#%s].\n", me->id.name, index_list.getName().c_str() ); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							|  |  |  | 						set_vcol(mloopcol+loop_index, vcol, start_index, *index_list_array_vcolor[vcolor_index], vcount); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 				mpoly++; | 
					
						
							| 
									
										
										
										
											2014-05-01 14:52:10 +02:00
										 |  |  | 				mloop       += vcount; | 
					
						
							|  |  |  | 				loop_index  += vcount; | 
					
						
							| 
									
										
										
										
											2013-04-18 21:40:06 +00:00
										 |  |  | 				start_index += vcount; | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 				prim.totpoly++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (mp_has_normals) | 
					
						
							|  |  |  | 					normal_indices += vcount; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 				position_indices += vcount; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		else if (collada_meshtype == COLLADAFW::MeshPrimitive::LINES) { | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | 			continue; // read the lines later after all the rest is done
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (mp_has_faces) | 
					
						
							|  |  |  | 			mat_prim_map[mp->getMaterialId()].push_back(prim); | 
					
						
							| 
									
										
										
										
											2014-05-01 14:52:10 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 	geom_uid_mat_mapping_map[collada_mesh->getUniqueId()] = mat_prim_map; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-27 19:39:06 +00:00
										 |  |  | void MeshImporter::get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i, int stride) | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-01-27 19:39:06 +00:00
										 |  |  | 	i *= stride; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-04-28 06:31:57 +00:00
										 |  |  | 	switch (arr.getType()) { | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 		case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 			COLLADAFW::ArrayPrimitiveType<float> *values = arr.getFloatValues(); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 			if (values->empty()) return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			v[0] = (*values)[i++]; | 
					
						
							|  |  |  | 			v[1] = (*values)[i++]; | 
					
						
							| 
									
										
										
										
											2013-09-21 10:46:58 +00:00
										 |  |  | 			if (stride>=3) { | 
					
						
							| 
									
										
										
										
											2013-09-19 21:59:22 +00:00
										 |  |  | 				v[2] = (*values)[i]; | 
					
						
							| 
									
										
										
										
											2013-09-21 10:46:58 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2013-09-19 21:59:22 +00:00
										 |  |  | 				v[2] = 0.0f; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2011-01-27 19:39:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 		case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 			COLLADAFW::ArrayPrimitiveType<double> *values = arr.getDoubleValues(); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 			if (values->empty()) return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			v[0] = (float)(*values)[i++]; | 
					
						
							|  |  |  | 			v[1] = (float)(*values)[i++]; | 
					
						
							| 
									
										
										
										
											2013-09-21 10:46:58 +00:00
										 |  |  | 			if (stride >= 3) { | 
					
						
							| 
									
										
										
										
											2013-09-19 21:59:22 +00:00
										 |  |  | 				v[2] = (float)(*values)[i]; | 
					
						
							| 
									
										
										
										
											2013-09-21 10:46:58 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2013-09-19 21:59:22 +00:00
										 |  |  | 				v[2] = 0.0f; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 		default: | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-09-19 21:59:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | bool MeshImporter::is_flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor, int count) | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	float a[3], b[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-27 19:39:06 +00:00
										 |  |  | 	get_vector(a, nor, *nind, 3); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	normalize_v3(a); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	nind++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (int i = 1; i < count; i++, nind++) { | 
					
						
							| 
									
										
										
										
											2011-01-27 19:39:06 +00:00
										 |  |  | 		get_vector(b, nor, *nind, 3); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 		normalize_v3(b); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		float dp = dot_v3v3(a, b); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (dp < 0.99999f || dp > 1.00001f) | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-03 21:32:49 +00:00
										 |  |  | void MeshImporter::bmeshConversion() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 	for (std::map<COLLADAFW::UniqueId, Mesh *>::iterator m = uid_mesh_map.begin(); | 
					
						
							|  |  |  | 	     m != uid_mesh_map.end(); ++m) | 
					
						
							| 
									
										
										
										
											2012-05-03 21:32:49 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		if ((*m).second) { | 
					
						
							|  |  |  | 			Mesh *me = (*m).second; | 
					
						
							|  |  |  | 			BKE_mesh_tessface_clear(me); | 
					
						
							| 
									
										
										
										
											2013-05-28 14:23:07 +00:00
										 |  |  | 			BKE_mesh_calc_normals(me); | 
					
						
							| 
									
										
										
										
											2015-02-05 14:03:01 +01:00
										 |  |  | 			/* BKE_mesh_validate(me, true, true); */ | 
					
						
							| 
									
										
										
										
											2012-05-03 21:32:49 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | Object *MeshImporter::get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (uid_object_map.find(geom_uid) != uid_object_map.end()) | 
					
						
							|  |  |  | 		return uid_object_map[geom_uid]; | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-21 13:45:49 +00:00
										 |  |  | Mesh *MeshImporter::get_mesh_by_geom_uid(const COLLADAFW::UniqueId& mesh_uid) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (uid_mesh_map.find(mesh_uid) != uid_mesh_map.end()) | 
					
						
							|  |  |  | 		return uid_mesh_map[mesh_uid]; | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-12 17:52:18 +00:00
										 |  |  | std::string *MeshImporter::get_geometry_name(const std::string &mesh_name) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (this->mesh_geom_map.find(mesh_name) != this->mesh_geom_map.end()) | 
					
						
							|  |  |  | 		return &this->mesh_geom_map[mesh_name]; | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | MTex *MeshImporter::assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBinding &ctexture, | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  |                                                Mesh *me, TexIndexTextureArrayMap& texindex_texarray_map, | 
					
						
							|  |  |  |                                                MTex *color_texture) | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	const COLLADAFW::TextureMapId texture_index = ctexture.getTextureMapId(); | 
					
						
							| 
									
										
										
										
											2011-06-20 09:34:35 +00:00
										 |  |  | 	size_t setindex = ctexture.getSetIndex(); | 
					
						
							| 
									
										
										
										
											2010-10-05 06:10:17 +00:00
										 |  |  | 	std::string uvname = ctexture.getSemantic(); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 	if (setindex == -1) return NULL; | 
					
						
							| 
									
										
										
										
											2011-06-20 09:34:35 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	const CustomData *data = &me->fdata; | 
					
						
							|  |  |  | 	int layer_index = CustomData_get_layer_index(data, CD_MTFACE); | 
					
						
							| 
									
										
										
										
											2012-02-19 17:55:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 	if (layer_index == -1) return NULL; | 
					
						
							| 
									
										
										
										
											2012-02-19 17:55:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 	CustomDataLayer *cdl = &data->layers[layer_index + setindex]; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* set uvname to bind_vertex_input semantic */ | 
					
						
							|  |  |  | 	BLI_strncpy(cdl->name, uvname.c_str(), sizeof(cdl->name)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (texindex_texarray_map.find(texture_index) == texindex_texarray_map.end()) { | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		fprintf(stderr, "Cannot find texture array by texture index.\n"); | 
					
						
							|  |  |  | 		return color_texture; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 	std::vector<MTex *> textures = texindex_texarray_map[texture_index]; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 	std::vector<MTex *>::iterator it; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	for (it = textures.begin(); it != textures.end(); it++) { | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		MTex *texture = *it; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if (texture) { | 
					
						
							|  |  |  | 			BLI_strncpy(texture->uvname, uvname.c_str(), sizeof(texture->uvname)); | 
					
						
							|  |  |  | 			if (texture->mapto == MAP_COL) color_texture = texture; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return color_texture; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-12 17:13:07 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * this function checks if both objects have the same | 
					
						
							|  |  |  |  * materials assigned to Object (in the same order) | 
					
						
							|  |  |  |  * returns true if condition matches, otherwise false; | 
					
						
							|  |  |  |  **/ | 
					
						
							|  |  |  | static bool bc_has_same_material_configuration(Object *ob1, Object *ob2) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (ob1->totcol != ob2->totcol) return false; // not same number of materials
 | 
					
						
							|  |  |  | 	if (ob1->totcol == 0) return false; // no material at all
 | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-10-21 07:58:38 +00:00
										 |  |  | 	for (int index=0; index < ob1->totcol; index++) { | 
					
						
							| 
									
										
										
										
											2012-08-12 17:13:07 +00:00
										 |  |  | 		if (ob1->matbits[index] != ob2->matbits[index]) return false; // shouldn't happen
 | 
					
						
							|  |  |  | 		if (ob1->matbits[index] == 0) return false; // shouldn't happen
 | 
					
						
							|  |  |  | 		if (ob1->mat[index] != ob2->mat[index]) return false; // different material assignment
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Caution here: This code assumes tha all materials are assigned to Object | 
					
						
							|  |  |  |  * and no material is assigned to Data. | 
					
						
							|  |  |  |  * That is true right after the objects have been imported. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  **/ | 
					
						
							|  |  |  | static void bc_copy_materials_to_data(Object *ob, Mesh *me) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	for (int index = 0; index < ob->totcol; index++) { | 
					
						
							|  |  |  | 		ob->matbits[index] = 0; | 
					
						
							|  |  |  | 		me->mat[index] = ob->mat[index]; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Remove all references to materials from the object | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  **/ | 
					
						
							|  |  |  | static void bc_remove_materials_from_object(Object *ob, Mesh *me) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	for (int index = 0; index < ob->totcol; index++) { | 
					
						
							|  |  |  | 		ob->matbits[index] = 0; | 
					
						
							|  |  |  | 		ob->mat[index] = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Returns the list of Users of the given Mesh object. | 
					
						
							|  |  |  |  * Note: This function uses the object user flag to control | 
					
						
							|  |  |  |  * which objects have already been processed. | 
					
						
							|  |  |  |  **/ | 
					
						
							|  |  |  | std::vector<Object *> MeshImporter::get_all_users_of(Mesh *reference_mesh) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	std::vector<Object *> mesh_users; | 
					
						
							|  |  |  | 	for (std::vector<Object *>::iterator it = imported_objects.begin(); | 
					
						
							|  |  |  | 	     it != imported_objects.end(); ++it) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		Object *ob = (*it); | 
					
						
							|  |  |  | 		if (bc_is_marked(ob)) { | 
					
						
							|  |  |  | 			bc_remove_mark(ob); | 
					
						
							|  |  |  | 			Mesh *me = (Mesh *) ob->data; | 
					
						
							|  |  |  | 			if (me == reference_mesh) | 
					
						
							|  |  |  | 				mesh_users.push_back(ob); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return mesh_users; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * During import all materials have been assigned to Object. | 
					
						
							|  |  |  |  * Now we iterate over the imported objects and optimize | 
					
						
							| 
									
										
										
										
											2013-09-05 19:56:49 +00:00
										 |  |  |  * the assignments as follows: | 
					
						
							| 
									
										
										
										
											2012-08-12 17:13:07 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * for each imported geometry: | 
					
						
							|  |  |  |  *     if number of users is 1: | 
					
						
							|  |  |  |  *         get the user (object) | 
					
						
							|  |  |  |  *         move the materials from Object to Data | 
					
						
							|  |  |  |  *     else: | 
					
						
							|  |  |  |  *         determine which materials are assigned to the first user | 
					
						
							|  |  |  |  *         check if all other users have the same materials in the same order | 
					
						
							|  |  |  |  *         if the check is positive: | 
					
						
							|  |  |  |  *             Add the materials of the first user to the geometry | 
					
						
							|  |  |  |  *             adjust all other users accordingly. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  **/ | 
					
						
							| 
									
										
										
										
											2013-01-21 13:45:49 +00:00
										 |  |  | void MeshImporter::optimize_material_assignements() | 
					
						
							| 
									
										
										
										
											2012-08-12 17:13:07 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	for (std::vector<Object *>::iterator it = imported_objects.begin(); | 
					
						
							|  |  |  | 	     it != imported_objects.end(); ++it) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		Object *ob = (*it); | 
					
						
							|  |  |  | 		Mesh *me = (Mesh *) ob->data; | 
					
						
							|  |  |  | 		if (me->id.us==1) { | 
					
						
							| 
									
										
										
										
											2012-12-29 01:54:58 +00:00
										 |  |  | 			bc_copy_materials_to_data(ob, me); | 
					
						
							|  |  |  | 			bc_remove_materials_from_object(ob, me); | 
					
						
							| 
									
										
										
										
											2012-08-12 17:13:07 +00:00
										 |  |  | 			bc_remove_mark(ob); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (me->id.us > 1) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			bool can_move = true; | 
					
						
							|  |  |  | 			std::vector<Object *> mesh_users = get_all_users_of(me); | 
					
						
							|  |  |  | 			if (mesh_users.size() > 1) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				Object *ref_ob = mesh_users[0]; | 
					
						
							|  |  |  | 				for (int index = 1; index < mesh_users.size(); index++) { | 
					
						
							|  |  |  | 					if (!bc_has_same_material_configuration(ref_ob, mesh_users[index])) { | 
					
						
							|  |  |  | 						can_move = false; | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (can_move) { | 
					
						
							| 
									
										
										
										
											2012-12-29 01:54:58 +00:00
										 |  |  | 					bc_copy_materials_to_data(ref_ob, me); | 
					
						
							| 
									
										
										
										
											2012-08-12 17:13:07 +00:00
										 |  |  | 					for (int index = 0; index < mesh_users.size(); index++) { | 
					
						
							|  |  |  | 						Object *object = mesh_users[index]; | 
					
						
							| 
									
										
										
										
											2012-12-29 01:54:58 +00:00
										 |  |  | 						bc_remove_materials_from_object(object, me); | 
					
						
							| 
									
										
										
										
											2012-08-12 17:13:07 +00:00
										 |  |  | 						bc_remove_mark(object); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * We do not know in advance which objects will share geometries. | 
					
						
							|  |  |  |  * And we do not know either if the objects which share geometries | 
					
						
							|  |  |  |  * come along with different materials. So we first create the objects | 
					
						
							|  |  |  |  * and assign the materials to Object, then in a later cleanup we decide | 
					
						
							|  |  |  |  * which materials shall be moved to the created geometries. Also see | 
					
						
							| 
									
										
										
										
											2013-01-21 13:45:49 +00:00
										 |  |  |  * optimize_material_assignements() above. | 
					
						
							| 
									
										
										
										
											2012-08-12 17:13:07 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial, | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  |                                               std::map<COLLADAFW::UniqueId, Material *>& uid_material_map, | 
					
						
							|  |  |  |                                               Object *ob, const COLLADAFW::UniqueId *geom_uid, | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  |                                               char *layername, MTFace *texture_face, | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  |                                               std::map<Material *, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index) | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 	MTex *color_texture = NULL; | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 	Mesh *me = (Mesh *)ob->data; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	const COLLADAFW::UniqueId& ma_uid = cmaterial.getReferencedMaterial(); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	// do we know this material?
 | 
					
						
							|  |  |  | 	if (uid_material_map.find(ma_uid) == uid_material_map.end()) { | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		fprintf(stderr, "Cannot find material by UID.\n"); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-08-12 17:13:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-09 01:13:28 +00:00
										 |  |  | 	// first time we get geom_uid, ma_uid pair. Save for later check.
 | 
					
						
							|  |  |  | 	materials_mapped_to_geom.insert(std::pair<COLLADAFW::UniqueId, COLLADAFW::UniqueId>(*geom_uid, ma_uid)); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	Material *ma = uid_material_map[ma_uid]; | 
					
						
							| 
									
										
										
										
											2012-08-12 17:13:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Attention! This temporaly assigns material to object on purpose!
 | 
					
						
							|  |  |  | 	// See note above.
 | 
					
						
							|  |  |  | 	ob->actcol=0; | 
					
						
							|  |  |  | 	assign_material(ob, ma, mat_index + 1, BKE_MAT_ASSIGN_OBJECT);  | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	COLLADAFW::TextureCoordinateBindingArray& tex_array =  | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 	    cmaterial.getTextureCoordinateBindingArray(); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	TexIndexTextureArrayMap texindex_texarray_map = material_texture_mapping_map[ma]; | 
					
						
							|  |  |  | 	unsigned int i; | 
					
						
							|  |  |  | 	// loop through <bind_vertex_inputs>
 | 
					
						
							|  |  |  | 	for (i = 0; i < tex_array.getCount(); i++) { | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 		color_texture = assign_textures_to_uvlayer(tex_array[i], me, texindex_texarray_map, | 
					
						
							|  |  |  | 		                                            color_texture); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	// set texture face
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 	if (color_texture && | 
					
						
							|  |  |  | 	    strlen((color_texture)->uvname) && | 
					
						
							| 
									
										
										
										
											2015-01-26 16:03:11 +01:00
										 |  |  | 	    !STREQ(layername, color_texture->uvname)) { | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 		texture_face = (MTFace *)CustomData_get_layer_named(&me->fdata, CD_MTFACE, | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 		                                                    color_texture->uvname); | 
					
						
							|  |  |  | 		strcpy(layername, color_texture->uvname); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	MaterialIdPrimitiveArrayMap& mat_prim_map = geom_uid_mat_mapping_map[*geom_uid]; | 
					
						
							|  |  |  | 	COLLADAFW::MaterialId mat_id = cmaterial.getMaterialId(); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	// assign material indices to mesh faces
 | 
					
						
							|  |  |  | 	if (mat_prim_map.find(mat_id) != mat_prim_map.end()) { | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		std::vector<Primitive>& prims = mat_prim_map[mat_id]; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		std::vector<Primitive>::iterator it; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		for (it = prims.begin(); it != prims.end(); it++) { | 
					
						
							|  |  |  | 			Primitive& prim = *it; | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 			MPoly *mpoly = prim.mpoly; | 
					
						
							| 
									
										
										
										
											2012-05-03 21:32:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 			for (i = 0; i < prim.totpoly; i++, mpoly++) { | 
					
						
							|  |  |  | 				mpoly->mat_nr = mat_index; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 				// bind texture images to faces
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 				if (texture_face && color_texture) { | 
					
						
							|  |  |  | 					texture_face->tpage = (Image *)color_texture->tex->ima; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 					texture_face++; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 	}	 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	return texture_face; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom, | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  |                                          bool isController, | 
					
						
							|  |  |  |                                          std::map<COLLADAFW::UniqueId, Material *>& uid_material_map, | 
					
						
							|  |  |  |                                          std::map<Material *, TexIndexTextureArrayMap>& material_texture_mapping_map) | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	const COLLADAFW::UniqueId *geom_uid = &geom->getInstanciatedObjectId(); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	// check if node instanciates controller or geometry
 | 
					
						
							|  |  |  | 	if (isController) { | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		geom_uid = armature_importer->get_geometry_uid(*geom_uid); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if (!geom_uid) { | 
					
						
							|  |  |  | 			fprintf(stderr, "Couldn't find a mesh UID by controller's UID.\n"); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if (uid_mesh_map.find(*geom_uid) == uid_mesh_map.end()) { | 
					
						
							|  |  |  | 			// this could happen if a mesh was not created
 | 
					
						
							|  |  |  | 			// (e.g. if it contains unsupported geometry)
 | 
					
						
							|  |  |  | 			fprintf(stderr, "Couldn't find a mesh by UID.\n"); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (!uid_mesh_map[*geom_uid]) return NULL; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-03 21:32:49 +00:00
										 |  |  | 	// name Object
 | 
					
						
							|  |  |  | 	const std::string& id = node->getName().size() ? node->getName() : node->getOriginalId(); | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 	const char *name = (id.length()) ? id.c_str() : NULL; | 
					
						
							| 
									
										
										
										
											2012-05-03 21:32:49 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	// add object
 | 
					
						
							|  |  |  | 	Object *ob = bc_add_object(scene, OB_MESH, name); | 
					
						
							| 
									
										
										
										
											2012-08-12 17:13:07 +00:00
										 |  |  | 	bc_set_mark(ob); // used later for material assignement optimization
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// store object pointer for ArmatureImporter
 | 
					
						
							|  |  |  | 	uid_object_map[*geom_uid] = ob; | 
					
						
							| 
									
										
										
										
											2012-08-12 17:13:07 +00:00
										 |  |  | 	imported_objects.push_back(ob); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	// replace ob->data freeing the old one
 | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 	Mesh *old_mesh = (Mesh *)ob->data; | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 	Mesh *new_mesh = uid_mesh_map[*geom_uid]; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-17 19:55:10 +00:00
										 |  |  | 	BKE_mesh_assign_object(ob, new_mesh); | 
					
						
							| 
									
										
										
										
											2013-05-28 14:23:07 +00:00
										 |  |  | 	BKE_mesh_calc_normals(new_mesh); | 
					
						
							| 
									
										
										
										
											2013-05-28 13:32:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-15 19:15:51 +01:00
										 |  |  | 	if (old_mesh->id.us == 0) BKE_libblock_free(G.main, old_mesh); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	char layername[100]; | 
					
						
							| 
									
										
										
										
											2011-06-20 12:43:10 +00:00
										 |  |  | 	layername[0] = '\0'; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	MTFace *texture_face = NULL; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	COLLADAFW::MaterialBindingArray& mat_array = | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 	    geom->getMaterialBindings(); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	// loop through geom's materials
 | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 	for (unsigned int i = 0; i < mat_array.getCount(); i++) { | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 		if (mat_array[i].getReferencedMaterial().isValid()) { | 
					
						
							| 
									
										
										
										
											2011-03-08 20:41:43 +00:00
										 |  |  | 			texture_face = assign_material_to_geom(mat_array[i], uid_material_map, ob, geom_uid, | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 			                                       layername, texture_face, | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 			                                       material_texture_mapping_map, i); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2011-03-08 20:41:43 +00:00
										 |  |  | 			fprintf(stderr, "invalid referenced material for %s\n", mat_array[i].getName().c_str()); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-05-02 16:18:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	return ob; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // create a mesh storing a pointer in a map so it can be retrieved later by geometry UID
 | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | bool MeshImporter::write_geometry(const COLLADAFW::Geometry *geom) | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (geom->getType() != COLLADAFW::Geometry::GEO_TYPE_MESH) { | 
					
						
							|  |  |  | 		// TODO: report warning
 | 
					
						
							|  |  |  | 		fprintf(stderr, "Mesh type %s is not supported\n", bc_geomTypeToStr(geom->getType())); | 
					
						
							|  |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | 	COLLADAFW::Mesh *mesh = (COLLADAFW::Mesh *)geom; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	if (!is_nice_mesh(mesh)) { | 
					
						
							| 
									
										
										
										
											2013-02-08 00:27:35 +00:00
										 |  |  | 		fprintf(stderr, "Ignoring mesh %s\n", bc_get_dae_name(mesh).c_str()); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2011-06-20 12:43:10 +00:00
										 |  |  | 	const std::string& str_geom_id = mesh->getName().size() ? mesh->getName() : mesh->getOriginalId(); | 
					
						
							| 
									
										
										
										
											2013-02-05 13:04:01 +00:00
										 |  |  | 	Mesh *me = BKE_mesh_add(G.main, (char *)str_geom_id.c_str()); | 
					
						
							| 
									
										
										
										
											2013-03-17 19:55:10 +00:00
										 |  |  | 	me->id.us--; // is already 1 here, but will be set later in BKE_mesh_assign_object
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// store the Mesh pointer to link it later with an Object
 | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 	// mesh_geom_map needed to map mesh to its geometry name (for shape key naming)
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	this->uid_mesh_map[mesh->getUniqueId()] = me; | 
					
						
							| 
									
										
										
										
											2013-02-12 17:52:18 +00:00
										 |  |  | 	this->mesh_geom_map[std::string(me->id.name)] = str_geom_id; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	read_vertices(mesh, me); | 
					
						
							| 
									
										
										
										
											2013-03-02 15:58:13 +00:00
										 |  |  | 	read_polys(mesh, me); | 
					
						
							| 
									
										
										
										
											2013-03-16 01:19:03 +00:00
										 |  |  | 	BKE_mesh_calc_edges(me, false, false); | 
					
						
							| 
									
										
										
										
											2011-10-28 06:12:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-16 11:21:03 +00:00
										 |  |  | 	// read_lines() must be called after the face edges have been generated.
 | 
					
						
							|  |  |  | 	// Oterwise the loose edges will be silently deleted again.
 | 
					
						
							|  |  |  | 	read_lines(mesh, me); | 
					
						
							| 
									
										
										
										
											2014-05-01 14:52:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 	return true; | 
					
						
							| 
									
										
										
										
											2010-10-06 12:04:56 +00:00
										 |  |  | } |