LIB3MFMETHODIMP CCOMModelMeshObject::SetGeometry(_In_ MODELMESHVERTEX * pVertices, _In_ DWORD nVertexCount, _In_ MODELMESHTRIANGLE * pTriangles, _In_ DWORD nTriangleCount)
	{
		UINT j, nIndex;


		try {
			if ((!pVertices) || (!pTriangles))
				throw CNMRException(NMR_ERROR_INVALIDPOINTER);

			CMesh * pMesh = getMesh();
			__NMRASSERT(pMesh);

			// Clear old mesh
			pMesh->clear();

			// Rebuild Mesh Coordinates
			MODELMESHVERTEX * pVertex = pVertices;
			for (nIndex = 0; nIndex < nVertexCount; nIndex++) {
				NVEC3 vPosition;
				for (j = 0; j < 3; j++) {
					FLOAT fCoord = pVertex->m_fPosition[j];
					if (fabs(fCoord) > NMR_MESH_MAXCOORDINATE)
						throw CNMRException_Windows(NMR_ERROR_INVALIDCOORDINATES, LIB3MF_INVALIDARG);
					vPosition.m_fields[j] = fCoord;
				}
				pMesh->addNode(vPosition);

				pVertex++;
			}

			// Rebuild Mesh Faces
			MODELMESHTRIANGLE * pTriangle = pTriangles;
			for (nIndex = 0; nIndex < nTriangleCount; nIndex++) {
				MESHNODE * pNodes[3];

				for (j = 0; j < 3; j++) {
					if (pTriangle->m_nIndices[j] >= nVertexCount)
						throw CNMRException_Windows(NMR_ERROR_INVALIDINDEX, LIB3MF_INVALIDARG);
					pNodes[j] = pMesh->getNode(pTriangle->m_nIndices[j]);
				}

				if ((pTriangle->m_nIndices[0] == pTriangle->m_nIndices[1]) ||
					(pTriangle->m_nIndices[0] == pTriangle->m_nIndices[2]) ||
					(pTriangle->m_nIndices[1] == pTriangle->m_nIndices[2]))
					throw CNMRException_Windows(NMR_ERROR_INVALIDINDEX, LIB3MF_INVALIDARG);

				pMesh->addFace(pNodes[0], pNodes[1], pNodes[2]);

				pTriangle++;
			}

			return handleSuccess();
		}
		catch (CNMRException & Exception) {
			return handleNMRException(&Exception);
		}
		catch (...) {
			return handleGenericException();
		}
	}
	LIB3MFMETHODIMP CCOMModelMeshObject::AddTriangle(_In_ MODELMESHTRIANGLE * pTriangle, _Out_opt_ DWORD * pnIndex)
	{
		UINT j;

		try {
			if (!pTriangle)
				throw CNMRException(NMR_ERROR_INVALIDPOINTER);

			CMesh * pMesh = getMesh();
			__NMRASSERT(pMesh);

			// Check for input validity
			UINT nNodeCount = pMesh->getNodeCount();
			for (j = 0; j < 3; j++)
				if (pTriangle->m_nIndices[j] >= nNodeCount)
					throw CNMRException_Windows(NMR_ERROR_INVALIDINDEX, LIB3MF_INVALIDARG);
			if ((pTriangle->m_nIndices[0] == pTriangle->m_nIndices[1]) ||
				(pTriangle->m_nIndices[0] == pTriangle->m_nIndices[2]) ||
				(pTriangle->m_nIndices[1] == pTriangle->m_nIndices[2]))
				throw CNMRException_Windows(NMR_ERROR_INVALIDINDEX, LIB3MF_INVALIDARG);

			MESHNODE * pNodes[3];
			for (j = 0; j < 3; j++)
				pNodes[j] = pMesh->getNode(pTriangle->m_nIndices[j]);

			// retrieve node and return position
			MESHFACE * pFace = pMesh->addFace(pNodes[0], pNodes[1], pNodes[2]);
			if (pnIndex) {
				*pnIndex = pFace->m_index;
			}

			return handleSuccess();
		}
		catch (CNMRException & Exception) {
			return handleNMRException(&Exception);
		}
		catch (...) {
			return handleGenericException();
		}
	}