Browse Source

Merge branch 'master' into coverity_scan

Kim Kulling 8 years ago
parent
commit
0702778761

+ 2 - 2
code/X3DExporter.cpp

@@ -140,7 +140,7 @@ void X3DExporter::AttrHelper_Col3DArrToString(const aiColor3D* pArray, const siz
 	AttrHelper_CommaToPoint(pTargetString);
 }
 
-void X3DExporter::AttrHelper_Color3ToAttrList(std::list<SAttribute> pList, const std::string& pName, const aiColor3D& pValue, const aiColor3D& pDefaultValue)
+void X3DExporter::AttrHelper_Color3ToAttrList(std::list<SAttribute>& pList, const std::string& pName, const aiColor3D& pValue, const aiColor3D& pDefaultValue)
 {
 string tstr;
 
@@ -150,7 +150,7 @@ string tstr;
 	pList.push_back({pName, tstr});
 }
 
-void X3DExporter::AttrHelper_FloatToAttrList(std::list<SAttribute> pList, const string& pName, const float pValue, const float pDefaultValue)
+void X3DExporter::AttrHelper_FloatToAttrList(std::list<SAttribute>& pList, const string& pName, const float pValue, const float pDefaultValue)
 {
 string tstr;
 

+ 2 - 2
code/X3DExporter.hpp

@@ -134,7 +134,7 @@ private:
 
 	/// \fn void AttrHelper_FloatToAttrList(std::list<SAttribute> pList, const std::string& pName, const float pValue, const float pDefaultValue)
 	/// \overload void AttrHelper_Col3DArrToString(const aiColor3D* pArray, const size_t pArray_Size, std::string& pTargetString)
-	void AttrHelper_FloatToAttrList(std::list<SAttribute> pList, const std::string& pName, const float pValue, const float pDefaultValue);
+	void AttrHelper_FloatToAttrList(std::list<SAttribute> &pList, const std::string& pName, const float pValue, const float pDefaultValue);
 
 	/// \fn void AttrHelper_Color3ToAttrList(std::list<SAttribute> pList, const std::string& pName, const aiColor3D& pValue, const aiColor3D& pDefaultValue)
 	/// Add attribute to list if value not equal to default.
@@ -142,7 +142,7 @@ private:
 	/// \param [in] pName - name of new attribute.
 	/// \param [in] pValue - value of the new attribute.
 	/// \param [in] pDefaultValue - default value for checking: if pValue is equal to pDefaultValue then attribute will not be added.
-	void AttrHelper_Color3ToAttrList(std::list<SAttribute> pList, const std::string& pName, const aiColor3D& pValue, const aiColor3D& pDefaultValue);
+	void AttrHelper_Color3ToAttrList(std::list<SAttribute> &pList, const std::string& pName, const aiColor3D& pValue, const aiColor3D& pDefaultValue);
 
 	/// \fn void NodeHelper_OpenNode(const std::string& pNodeName, const size_t pTabLevel, const bool pEmptyElement, const std::list<SAttribute>& pAttrList)
 	/// Begin new XML-node element.

+ 42 - 52
code/X3DImporter.cpp

@@ -74,6 +74,8 @@ const aiImporterDesc X3DImporter::Description = {
 	"x3d"
 };
 
+const std::string X3DImporter::whitespace(" ,\t\n\r");
+
 X3DImporter::X3DImporter()
 : NodeElement_Cur( nullptr )
 , mReader( nullptr ) {
@@ -241,7 +243,7 @@ void X3DImporter::XML_CheckNode_MustBeEmpty()
 
 void X3DImporter::XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName)
 {
-    static const size_t Uns_Skip_Len = 190;
+    static const size_t Uns_Skip_Len = 192;
     const char* Uns_Skip[ Uns_Skip_Len ] = {
 	    // CAD geometry component
 	    "CADAssembly", "CADFace", "CADLayer", "CADPart", "IndexedQuadSet", "QuadSet",
@@ -276,7 +278,7 @@ void X3DImporter::XML_CheckNode_SkipUnsupported(const std::string& pParentNodeNa
 	    // Navigation component
 	    "Billboard", "Collision", "LOD", "NavigationInfo", "OrthoViewpoint", "Viewpoint", "ViewpointGroup",
 	    // Networking component
-	    "Anchor", "LoadSensor",
+	    "EXPORT", "IMPORT", "Anchor", "LoadSensor",
 	    // NURBS component
 	    "Contour2D", "ContourPolyline2D", "CoordinateDouble", "NurbsCurve", "NurbsCurve2D", "NurbsOrientationInterpolator", "NurbsPatchSurface",
 	    "NurbsPositionInterpolator", "NurbsSet", "NurbsSurfaceInterpolator", "NurbsSweptSurface", "NurbsSwungSurface", "NurbsTextureCoordinate",
@@ -437,43 +439,30 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsVec3f(const int pAttrIdx, aiVector3D
 
 void X3DImporter::XML_ReadNode_GetAttrVal_AsListB(const int pAttrIdx, std::list<bool>& pValue)
 {
-	// make copy of attribute value - string with list of bool values. Also all bool values is strings.
-	size_t tok_str_len = strlen(mReader->getAttributeValue(pAttrIdx));
-    if ( 0 == tok_str_len ) {
-        Throw_IncorrectAttrValue( mReader->getAttributeName( pAttrIdx ) );
-    }
-
-	tok_str_len++;// take in account terminating '\0'.
-	char *tok_str = new char[tok_str_len];
+	const char *tok_cur = mReader->getAttributeValue(pAttrIdx);
+	const char *tok_end = tok_cur + strlen(tok_cur);
 
-	strcpy(tok_str, mReader->getAttributeValue(pAttrIdx));
-	// change all spacebars to symbol '\0'. That is needed for parsing.
-	for(size_t i = 0; i < tok_str_len; i++)
+	for(;;)
 	{
-		if(tok_str[i] == ' ') tok_str[i] = 0;
-	}
+		while((tok_cur < tok_end) && (whitespace.find_first_of(*tok_cur) != std::string::npos)) tok_cur++;// skip spaces between values.
+		if (tok_cur >= tok_end)
+			break;
 
-	// at now check what current token is
-	for(char *tok_cur = tok_str, *tok_end = (tok_str + tok_str_len); tok_cur < tok_end;)
-	{
 		if(strncmp(tok_cur, "true", 4) == 0)
 		{
 			pValue.push_back(true);
-			tok_cur += 5;// five, not four. Because '\0' must be skipped too.
+			tok_cur += 4;
 		}
 		else if(strncmp(tok_cur, "false", 5) == 0)
 		{
-			pValue.push_back(true);
-			tok_cur += 6;// six, not five. Because '\0' must be skipped too.
+			pValue.push_back(false);
+			tok_cur += 5;
 		}
 		else
 		{
 			Throw_IncorrectAttrValue(mReader->getAttributeName(pAttrIdx));
 		}
-	}// for(char* tok_cur = tok_str, tok_end = (tok_str + tok_str_len); tok_cur < tok_end;)
-
-	// delete temporary string
-	delete [] tok_str;
+	}// for(;;)
 }
 
 void X3DImporter::XML_ReadNode_GetAttrVal_AsArrB(const int pAttrIdx, std::vector<bool>& pValue)
@@ -500,11 +489,11 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsListI32(const int pAttrIdx, std::lis
 
 		int32_t tval32;
 
+		while((tstr < tstr_end) && (whitespace.find_first_of(*tstr) != std::string::npos)) tstr++;// skip spaces between values.
+
 		tval32 = strtol10(tstr, &ostr);
 		if(ostr == tstr) break;
 
-		while((ostr < tstr_end) && (*ostr == ' ')) ostr++;// skip spaces between values.
-
 		tstr = ostr;
 		pValue.push_back(tval32);
 	} while(tstr < tstr_end);
@@ -529,7 +518,6 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsListF(const int pAttrIdx, std::list<
 
 	// at first check string values like '.xxx'.
 	ParseHelper_FixTruncatedFloatString(mReader->getAttributeValue(pAttrIdx), str_fixed);
-	if(!str_fixed.size()) Throw_ConvertFail_Str2ArrF(mReader->getAttributeValue(pAttrIdx));
 
 	// and convert all values and place it in list.
 	const char* pstr = str_fixed.c_str();
@@ -539,7 +527,7 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsListF(const int pAttrIdx, std::list<
 	{
 		float tvalf;
 
-		while((*pstr == ' ') && (pstr < pstr_end)) pstr++;// skip spaces between values.
+		while((pstr < pstr_end) && (whitespace.find_first_of(*pstr) != std::string::npos)) pstr++;// skip spaces between values.
 
 		if(pstr < pstr_end)// additional check, because attribute value can be ended with spaces.
 		{
@@ -568,7 +556,6 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsListD(const int pAttrIdx, std::list<
 
 	// at first check string values like '.xxx'.
 	ParseHelper_FixTruncatedFloatString(mReader->getAttributeValue(pAttrIdx), str_fixed);
-	if(!str_fixed.size()) Throw_ConvertFail_Str2ArrF(mReader->getAttributeValue(pAttrIdx));
 
 	// and convert all values and place it in list.
 	const char* pstr = str_fixed.c_str();
@@ -578,7 +565,7 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsListD(const int pAttrIdx, std::list<
 	{
 		double tvald;
 
-		while((*pstr == ' ') && (pstr < pstr_end)) pstr++;// skip spaces between values.
+		while((pstr < pstr_end) && (whitespace.find_first_of(*pstr) != std::string::npos)) pstr++;// skip spaces between values.
 
 		if(pstr < pstr_end)// additional check, because attribute value can be ended with spaces.
 		{
@@ -1153,35 +1140,36 @@ void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::list<int32_t>
 
 	if(pNormalPerVertex)
 	{
-		const std::list<int32_t>* srcidx;
-
 		if(pNormalIdx.size() > 0)
 		{
 			// check indices array count.
 			if(pNormalIdx.size() != pCoordIdx.size()) throw DeadlyImportError("Normals and Coords inidces count must be equal.");
 
-			srcidx = &pNormalIdx;
-		}
-		else
-		{
-			srcidx = &pCoordIdx;
-		}
+			tind.reserve(pNormalIdx.size());
+			for(std::list<int32_t>::const_iterator it = pNormalIdx.begin(); it != pNormalIdx.end(); it++)
+			{
+				if(*it != (-1)) tind.push_back(*it);
+			}
 
-		tind.reserve(srcidx->size());
-		for(std::list<int32_t>::const_iterator it = srcidx->begin(); it != srcidx->end(); it++)
-		{
-			if(*it != (-1)) tind.push_back(*it);
-		}
+			// copy normals to mesh
+			pMesh.mNormals = new aiVector3D[pMesh.mNumVertices];
+			for(size_t i = 0; (i < pMesh.mNumVertices) && (i < tind.size()); i++)
+			{
+				if(tind[i] >= norm_arr_copy.size())
+					throw DeadlyImportError("MeshGeometry_AddNormal. Normal index(" + to_string(tind[i]) +
+											") is out of range. Normals count: " + to_string(norm_arr_copy.size()) + ".");
 
-		// copy normals to mesh
-		pMesh.mNormals = new aiVector3D[pMesh.mNumVertices];
-		for(size_t i = 0; (i < pMesh.mNumVertices) && (i < tind.size()); i++)
+				pMesh.mNormals[i] = norm_arr_copy[tind[i]];
+			}
+		}
+		else
 		{
-			if(tind[i] >= norm_arr_copy.size())
-				throw DeadlyImportError("MeshGeometry_AddNormal. Normal index(" + to_string(tind[i]) +
-										") is out of range. Normals count: " + to_string(norm_arr_copy.size()) + ".");
+			if(pNormals.size() != pMesh.mNumVertices) throw DeadlyImportError("MeshGeometry_AddNormal. Normals and vertices count must be equal.");
 
-			pMesh.mNormals[i] = norm_arr_copy[tind[i]];
+			// copy normals to mesh
+			pMesh.mNormals = new aiVector3D[pMesh.mNumVertices];
+			std::list<aiVector3D>::const_iterator norm_it = pNormals.begin();
+			for(size_t i = 0; i < pMesh.mNumVertices; i++) pMesh.mNormals[i] = *norm_it++;
 		}
 	}// if(pNormalPerVertex)
 	else
@@ -1679,8 +1667,10 @@ const aiImporterDesc* X3DImporter::GetInfo () const
 
 void X3DImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
 {
+	mpIOHandler = pIOHandler;
+
 	Clear();// delete old graph.
-	mFileDir = DefaultIOSystem::absolutePath(pFile);
+	pIOHandler->PushDirectory(DefaultIOSystem::absolutePath(pFile));
 	ParseFile(pFile, pIOHandler);
 	//
 	// Assimp use static arrays of objects for fast speed of rendering. That's good, but need some additional operations/

+ 3 - 2
code/X3DImporter.hpp

@@ -101,7 +101,7 @@ namespace Assimp {
 ///		Navigation component:
 ///			"Billboard", "Collision", "LOD", "NavigationInfo", "OrthoViewpoint", "Viewpoint", "ViewpointGroup"
 ///		Networking component:
-///			"Anchor", "LoadSensor"
+///			"EXPORT", "IMPORT", "Anchor", "LoadSensor"
 ///		NURBS component:
 ///			"Contour2D", "ContourPolyline2D", "CoordinateDouble", "NurbsCurve", "NurbsCurve2D", "NurbsOrientationInterpolator", "NurbsPatchSurface",
 ///			"NurbsPositionInterpolator", "NurbsSet", "NurbsSurfaceInterpolator", "NurbsSweptSurface", "NurbsSwungSurface", "NurbsTextureCoordinate",
@@ -826,13 +826,14 @@ private:
     /****************** Constants ******************/
     /***********************************************/
     static const aiImporterDesc Description;
+    static const std::string whitespace;
 
     /***********************************************/
     /****************** Variables ******************/
     /***********************************************/
     CX3DImporter_NodeElement* NodeElement_Cur;///< Current element.
     irr::io::IrrXMLReader* mReader;///< Pointer to XML-reader object
-    std::string mFileDir;
+    IOSystem *mpIOHandler;
 };// class X3DImporter
 
 }// namespace Assimp

+ 4 - 3
code/X3DImporter_Networking.cpp

@@ -89,12 +89,13 @@ void X3DImporter::ParseNode_Networking_Inline()
 
 		if(load && (url.size() > 0))
 		{
-			DefaultIOSystem io_handler;
 			std::string full_path;
 
-			full_path = mFileDir + "/" + url.front();
+			full_path = mpIOHandler->CurrentDirectory() + "/" + url.front();
 			// Attribute "url" can contain list of strings. But we need only one - first.
-			ParseFile(full_path, &io_handler);
+			mpIOHandler->PushDirectory(DefaultIOSystem::absolutePath(full_path));
+			ParseFile(full_path, mpIOHandler);
+			mpIOHandler->PopDirectory();
 		}
 
 		// check for X3DMetadataObject childs.

+ 98 - 3
code/X3DImporter_Rendering.cpp

@@ -288,9 +288,46 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleFanSet()
 
 		ne_alias.CCW = ccw;
 		ne_alias.ColorPerVertex = colorPerVertex;
-		ne_alias.CoordIndex = index;
 		ne_alias.NormalPerVertex = normalPerVertex;
 		ne_alias.Solid = solid;
+
+		ne_alias.CoordIndex.clear();
+		int counter = 0;
+		int32_t idx[3];
+		for(std::list<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++)
+		{
+			idx[2] = *idx_it;
+			if (idx[2] < 0)
+			{
+				counter = 0;
+			}
+			else
+			{
+				if (counter >= 2)
+				{
+					if(ccw)
+					{
+						ne_alias.CoordIndex.push_back(idx[0]);
+						ne_alias.CoordIndex.push_back(idx[1]);
+						ne_alias.CoordIndex.push_back(idx[2]);
+					}
+					else
+					{
+						ne_alias.CoordIndex.push_back(idx[0]);
+						ne_alias.CoordIndex.push_back(idx[2]);
+						ne_alias.CoordIndex.push_back(idx[1]);
+					}
+					ne_alias.CoordIndex.push_back(-1);
+					idx[1] = idx[2];
+				}
+				else
+				{
+					idx[counter] = idx[2];
+				}
+				++counter;
+			}
+		}// for(std::list<int32_t>::const_iterator idx_it = index.begin(); idx_it != ne_alias.index.end(); idx_it++)
+
         // check for child nodes
         if(!mReader->isEmptyElement())
         {
@@ -369,9 +406,34 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleSet()
 
 		ne_alias.CCW = ccw;
 		ne_alias.ColorPerVertex = colorPerVertex;
-		ne_alias.CoordIndex = index;
 		ne_alias.NormalPerVertex = normalPerVertex;
 		ne_alias.Solid = solid;
+
+		ne_alias.CoordIndex.clear();
+		int counter = 0;
+		int32_t idx[3];
+		for(std::list<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++)
+		{
+			idx[counter++] = *idx_it;
+			if (counter > 2)
+			{
+				counter = 0;
+				if(ccw)
+				{
+					ne_alias.CoordIndex.push_back(idx[0]);
+					ne_alias.CoordIndex.push_back(idx[1]);
+					ne_alias.CoordIndex.push_back(idx[2]);
+				}
+				else
+				{
+					ne_alias.CoordIndex.push_back(idx[0]);
+					ne_alias.CoordIndex.push_back(idx[2]);
+					ne_alias.CoordIndex.push_back(idx[1]);
+				}
+				ne_alias.CoordIndex.push_back(-1);
+			}
+		}// for(std::list<int32_t>::const_iterator idx_it = index.begin(); idx_it != ne_alias.index.end(); idx_it++)
+
         // check for child nodes
         if(!mReader->isEmptyElement())
         {
@@ -450,9 +512,42 @@ void X3DImporter::ParseNode_Rendering_IndexedTriangleStripSet()
 
 		ne_alias.CCW = ccw;
 		ne_alias.ColorPerVertex = colorPerVertex;
-		ne_alias.CoordIndex = index;
 		ne_alias.NormalPerVertex = normalPerVertex;
 		ne_alias.Solid = solid;
+
+		ne_alias.CoordIndex.clear();
+		int counter = 0;
+		int32_t idx[3];
+		for(std::list<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++)
+		{
+			idx[2] = *idx_it;
+			if (idx[2] < 0)
+			{
+				counter = 0;
+			}
+			else
+			{
+				if (counter >= 2)
+				{
+					if(ccw)
+					{
+						ne_alias.CoordIndex.push_back(idx[0]);
+						ne_alias.CoordIndex.push_back(idx[1]);
+						ne_alias.CoordIndex.push_back(idx[2]);
+					}
+					else
+					{
+						ne_alias.CoordIndex.push_back(idx[0]);
+						ne_alias.CoordIndex.push_back(idx[2]);
+						ne_alias.CoordIndex.push_back(idx[1]);
+					}
+					ne_alias.CoordIndex.push_back(-1);
+				}
+				idx[counter & 1] = idx[2];
+				++counter;
+			}
+		}// for(std::list<int32_t>::const_iterator idx_it = index.begin(); idx_it != ne_alias.index.end(); idx_it++)
+
         // check for child nodes
         if(!mReader->isEmptyElement())
         {