LIB3MFMETHODIMP CCOMModelMeshObject::SetTriangle(_In_ DWORD nIndex, _In_ MODELMESHTRIANGLE * pTriangle)
	{
		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);

			// retrieve node and return position
			MESHFACE * pFace = pMesh->getFace(nIndex);
			for (j = 0; j < 3; j++)
				pFace->m_nodeindices[j] = pTriangle->m_nIndices[j];

			return handleSuccess();
		}
		catch (CNMRException & Exception) {
			return handleNMRException(&Exception);
		}
		catch (...) {
			return handleGenericException();
		}
	}
	CXmlWriter_COM::CXmlWriter_COM(_In_ PExportStream pExportStream)
		: CXmlWriter(pExportStream)
	{
		HRESULT hResult;
		if (pExportStream.get() == nullptr)
			throw CNMRException(NMR_ERROR_INVALIDPARAM);

		// Create XML Writer
		hResult = CreateXmlWriter(__uuidof(IXmlWriter), (void**)&m_pXMLWriter, nullptr);
		if (hResult != S_OK)
			throw CNMRException_Windows(NMR_ERROR_COULDNOTCREATEXMLWRITER, hResult);

		// Cast to COM Streams
		CExportStream_COM * pCOMExportStream = dynamic_cast<CExportStream_COM *> (pExportStream.get());
		if (pCOMExportStream == nullptr)
			throw CNMRException(NMR_ERROR_INVALIDSTREAMTYPE);
		m_pCOMStream = pCOMExportStream->getCOMStream();

		// Set XML Writer Output
		hResult = m_pXMLWriter->SetOutput(m_pCOMStream);
		if (hResult != S_OK)
		  throw CNMRException_Windows(NMR_ERROR_COULDNOTSETXMLOUTPUT, hResult);

		// Set XML Writer Property
		hResult = m_pXMLWriter->SetProperty(XmlWriterProperty_Indent, true);
		if (hResult != S_OK)
			throw CNMRException_Windows(NMR_ERROR_COULDNOTSETXMLPROPERTY, hResult);
	}
	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();
		}
	}
	PImportStream CModelReader_3MF_OPC::extract3MFOPCPackage(_In_ PImportStream pPackageStream)
	{
		HRESULT hResult;
		__NMRASSERT(pPackageStream != nullptr);

		// Cast to COM Streams
		CImportStream_COM * pCOMImportStream = dynamic_cast<CImportStream_COM *> (pPackageStream.get());
		if (pCOMImportStream == nullptr)
			throw CNMRException(NMR_ERROR_INVALIDSTREAMTYPE);
		CComPtr<IStream> pCOMPackageStream = pCOMImportStream->getCOMStream ();

		// Define result model stream;
		CComPtr<IStream> pModelStream = nullptr;

		// Reset all values
		m_pPackagePartSet = nullptr;
		m_pPackageRelationshipSet = nullptr;
		m_pModelPart = nullptr;

		// Create OPC Factory
		CComPtr<IOpcFactory> pFactory;
		hResult = CoCreateInstance(__uuidof(OpcFactory), NULL, CLSCTX_INPROC_SERVER, __uuidof(IOpcFactory), (LPVOID*)&pFactory);
		if (hResult != S_OK)
			throw CNMRException_Windows(NMR_ERROR_OPCFACTORYCREATEFAILED, hResult);

		// Read OPC Package
		CComPtr<IOpcPackage> pPackage;
		hResult = pFactory->ReadPackageFromStream(pCOMPackageStream, OPC_READ_DEFAULT, &pPackage);
		if (hResult != S_OK)
			throw CNMRException_Windows(NMR_ERROR_OPCREADFAILED, hResult);

		// Read	OPC Package Part Set
		hResult = pPackage->GetPartSet(&m_pPackagePartSet);
		if (hResult != S_OK)
			throw CNMRException_Windows(NMR_ERROR_OPCPARTSETREADFAILED, hResult);

		// Read OPC Relationship Set
		hResult = pPackage->GetRelationshipSet(&m_pPackageRelationshipSet);
		if (hResult != S_OK)
			throw CNMRException_Windows(NMR_ERROR_OPCRELATIONSHIPSETREADFAILED, hResult);

		// Extract Model from OPC Package
		__NMRASSERT(m_pPackagePartSet != nullptr);
		__NMRASSERT(m_pPackageRelationshipSet != nullptr);
		m_pModelPart = getPartFromPackage(m_pPackagePartSet, m_pPackageRelationshipSet, PACKAGE_START_PART_RELATIONSHIP_TYPE, PACKAGE_3D_MODEL_CONTENT_TYPE);

		// Extract Model Stream
		__NMRASSERT(m_pModelPart != nullptr);
		hResult = m_pModelPart->GetContentStream(&pModelStream);
		if (hResult != S_OK)
			throw CNMRException_Windows(NMR_ERROR_OPCCOULDNOTGETMODELSTREAM, hResult);

		return std::make_shared<CImportStream_COM>(pModelStream);
	}
	LIB3MFMETHODIMP CCOMModelTexture2D::ReadFromBuffer(_In_ BYTE * pBuffer, _In_ ULONG64 cbBufferSize)
		try {
		if (pBuffer == nullptr)
			throw CNMRException(NMR_ERROR_INVALIDPOINTER);

		HRESULT hResult;

		CModelTexture2DResource * pTextureResource = getTexture2D();
		__NMRASSERT(pTextureResource);

		CComPtr<IStream> pMemoryStream = nullptr;
		hResult = CreateStreamOnHGlobal(nullptr, true, &pMemoryStream);
		if (hResult != S_OK)
			throw CNMRException_Windows(NMR_ERROR_COULDNOTCREATESTREAM, hResult);

		BYTE * pByte = pBuffer;

		nfUint64 cbBytesLeft = cbBufferSize;
		while (cbBytesLeft > 0) {
			nfUint64 cbLength = cbBytesLeft;
			if (cbLength > NMR_IMPORTSTREAM_COPYBUFFERSIZE)
				cbLength = NMR_IMPORTSTREAM_COPYBUFFERSIZE;

			ULONG cbWrittenBytes = 0;
			hResult = pMemoryStream->Write(pByte, (nfUint32)cbLength, &cbWrittenBytes);
			if (hResult != S_OK)
				throw CNMRException_Windows(NMR_ERROR_COULDNOTWRITESTREAM, hResult);

			if (cbWrittenBytes != cbLength)
				throw CNMRException(NMR_ERROR_COULDNOTWRITEFULLDATA);
			cbBytesLeft -= cbLength;
			pByte += cbLength;
		}


		PImportStream pImportStream = std::make_shared<CImportStream_COM>(pMemoryStream);

		CModel * pModel = pTextureResource->getModel();
		__NMRASSERT(pModel);

		pModel->removeTextureStream(pTextureResource->getPath());
		pModel->addTextureStream(pTextureResource->getPath(), pImportStream);

		return handleSuccess();
	}
	catch (CNMRException & Exception) {
		return handleNMRException(&Exception);
	}
	catch (...) {
		return handleGenericException();
	}
	CComPtr<IOpcRelationship> CModelReader_3MF_OPC::getSingleRelationShipByType(_In_ IOpcRelationshipSet * pRelationshipSet, _In_ LPCWSTR pszRelationshipType)
	{
		__NMRASSERT(pRelationshipSet != nullptr);
		__NMRASSERT(pszRelationshipType != nullptr);
		HRESULT hResult;

		// Retrieve Enumerator
		CComPtr<IOpcRelationshipEnumerator> pEnumerator;
		hResult = pRelationshipSet->GetEnumeratorForType(pszRelationshipType, &pEnumerator);
		if (hResult != S_OK)
			throw CNMRException_Windows(NMR_ERROR_OPCRELATIONSHIPENUMERATIONFAILED, hResult);

		// Enumerate the first two relationships
		CComPtr<IOpcRelationship> pFirstRelationShip = nullptr;
		CComPtr<IOpcRelationship> pSecondRelationShip = nullptr;

		// Get the first relationship
		BOOL bHasFirst;
		hResult = pEnumerator->MoveNext(&bHasFirst);
		if (hResult != S_OK)
			throw CNMRException_Windows(NMR_ERROR_OPCRELATIONSHIPENUMERATIONFAILED, hResult);

		if (bHasFirst) {
			hResult = pEnumerator->GetCurrent(&pFirstRelationShip);
			if (hResult != S_OK)
				throw CNMRException_Windows(NMR_ERROR_OPCRELATIONSHIPENUMERATIONFAILED, hResult);

			// Get the first relationship
			BOOL bHasSecond;
			hResult = pEnumerator->MoveNext(&bHasSecond);
			if (hResult != S_OK)
				throw CNMRException_Windows(NMR_ERROR_OPCRELATIONSHIPENUMERATIONFAILED, hResult);

			if (bHasSecond) {
				hResult = pEnumerator->GetCurrent(&pSecondRelationShip);
				if (hResult != S_OK)
					throw CNMRException_Windows(NMR_ERROR_OPCRELATIONSHIPENUMERATIONFAILED, hResult);
			}
		}

		// We may only have exactly one relationship, otherwise it is ambigouus
		if (!pFirstRelationShip)
			throw CNMRException(NMR_ERROR_OPCRELATIONSHIPNOTFOUND);
		if (pSecondRelationShip)
			throw CNMRException(NMR_ERROR_OPCRELATIONSHIPNOTUNIQUE);

		return pFirstRelationShip;
	}
	void CXmlWriter_COM::WriteAttributeString(_In_opt_ LPCWSTR pwszPrefix, _In_opt_ LPCWSTR pwszLocalName, _In_opt_ LPCWSTR pwszNamespaceUri, _In_opt_ LPCWSTR pwszValue)
	{
		HRESULT hResult = m_pXMLWriter->WriteAttributeString(pwszPrefix, pwszLocalName, pwszNamespaceUri, pwszValue);
		if (hResult != S_OK)
			throw CNMRException_Windows(NMR_ERROR_COULDNOTWRITEXMLATTRIBUTE, hResult);

	}
	LIB3MFMETHODIMP CCOMModelMeshObject::AddVertex(_In_ MODELMESHVERTEX * pVertex, _Out_opt_ DWORD * pnIndex)
	{
		UINT j;

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

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

			// Create Position Vector and check input
			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;
			}

			// Set position to node
			MESHNODE * pNode = pMesh->addNode(vPosition);
			if (pnIndex) {
				*pnIndex = pNode->m_index;
			}

			return handleSuccess();
		}
		catch (CNMRException & Exception) {
			return handleNMRException(&Exception);
		}
		catch (...) {
			return handleGenericException();
		}
	}
	void CXmlWriter_COM::WriteEndDocument()
	{
		HRESULT hResult;
		hResult = m_pXMLWriter->WriteEndDocument();
		if (hResult != S_OK)
			throw CNMRException_Windows(NMR_ERROR_COULDNOTWRITEXMLENDDOCUMENT, hResult);
	}
Exemple #10
0
	void CXmlWriter_COM::Flush()
	{
		HRESULT hResult;
		hResult = m_pXMLWriter->Flush();
		if (hResult != S_OK)
			throw CNMRException_Windows(NMR_ERROR_COULDNOTFLUSHXMLWRITER, hResult);
	}
Exemple #11
0
	void CXmlWriter_COM::WriteStartDocument()
	{
		HRESULT hResult;
		hResult = m_pXMLWriter->WriteStartDocument(XmlStandalone_Omit);
		if (hResult != S_OK)
			throw CNMRException_Windows(NMR_ERROR_COULDNOTWRITEXMLSTARTDOCUMENT, hResult);
	}
	CComPtr<IOpcPart> CModelReader_3MF_OPC::getRelationshipTargetPart(_In_ IOpcPartSet* pPartSet, _In_ IOpcRelationship * pRelationship, _In_opt_ LPCWSTR pszExpectedContentType)
	{
		__NMRASSERT(pPartSet != nullptr);
		__NMRASSERT(pRelationship != nullptr);
		HRESULT hResult;

		CComPtr<IOpcUri> pSourceURI;
		hResult = pRelationship->GetSourceUri(&pSourceURI);
		if (hResult != S_OK)
			throw CNMRException_Windows(NMR_ERROR_OPCRELATIONSHIPSOURCEURIFAILED, hResult);

		CComPtr<IUri> pTargetURI;
		hResult = pRelationship->GetTargetUri(&pTargetURI);
		if (hResult != S_OK)
			throw CNMRException_Windows(NMR_ERROR_OPCRELATIONSHIPTARGETURIFAILED, hResult);

		CComPtr<IOpcPartUri> pPartURI;
		hResult = pSourceURI->CombinePartUri(pTargetURI, &pPartURI);
		if (hResult != S_OK)
			throw CNMRException_Windows(NMR_ERROR_OPCRELATIONSHIPCOMBINEURIFAILED, hResult);

		CComPtr<IOpcPart> pPart;
		hResult = pPartSet->GetPart(pPartURI, &pPart);
		if (hResult != S_OK)
			throw CNMRException_Windows(NMR_ERROR_OPCRELATIONSHIPGETPARTFAILED, hResult);

		__NMRASSERT(pPart != nullptr);

		// Check optional content type match, if provided
		if (pszExpectedContentType) {
			wchar_t * pszContentType = nullptr;
			hResult = pPart->GetContentType(&pszContentType);
			if (hResult != S_OK)
				throw CNMRException_Windows(NMR_ERROR_OPCGETCONTENTTYPEFAILED, hResult);
			if (!pszContentType)
				throw CNMRException(NMR_ERROR_OPCGETCONTENTTYPEFAILED);

			nfBool bContentTypeIsValid = wcscmp(pszContentType, pszExpectedContentType) == 0;

			CoTaskMemFree(pszContentType);

			if (!bContentTypeIsValid)
				throw CNMRException(NMR_ERROR_OPCCONTENTTYPEMISMATCH);
		}

		return pPart;
	}
	LIB3MFMETHODIMP CCOMModelTexture2D::WriteToStream(_In_ IStream * pStream)
	{
		try {
			if (pStream == nullptr)
				throw CNMRException(NMR_ERROR_INVALIDPOINTER);

			CModelTexture2DResource * pTextureResource = getTexture2D();
			__NMRASSERT(pTextureResource);

			PImportStream pTextureStream = pTextureResource->getTextureStream();

			if (pTextureStream.get() != nullptr) {
				nfUint64 cbStreamSize = pTextureStream->retrieveSize();

				pTextureStream->seekPosition(0, true);
				std::array<nfByte, NMR_IMPORTSTREAM_COPYBUFFERSIZE> pBuffer;
				
				nfUint64 cbBytesLeft = cbStreamSize;
				while (cbBytesLeft > 0) {
					nfUint64 cbLength = cbBytesLeft;
					if (cbLength > NMR_IMPORTSTREAM_COPYBUFFERSIZE)
						cbLength = NMR_IMPORTSTREAM_COPYBUFFERSIZE;

					ULONG cbWrittenBytes = 0;
					pTextureStream->readBuffer(&pBuffer[0], cbLength, true);
					HRESULT hResult = pStream->Write(&pBuffer[0], (nfUint32) cbLength, &cbWrittenBytes);
					if (hResult != S_OK)
						throw CNMRException_Windows(NMR_ERROR_COULDNOTWRITESTREAM, hResult);
					
					if (cbWrittenBytes != cbLength)
						throw CNMRException(NMR_ERROR_COULDNOTWRITEFULLDATA);
					cbBytesLeft -= cbLength;
				}

			}
			else {
				throw CNMRException(NMR_ERROR_NOTEXTURESTREAM);
			}

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

	}
Exemple #14
0
	void CXmlWriter_COM::WriteText(_In_ const nfWChar * pwszContent, _In_ const nfUint32 cbLength)
	{
		HRESULT hResult = m_pXMLWriter->WriteChars(pwszContent, cbLength);
		if (hResult != S_OK)
			throw CNMRException_Windows(NMR_ERROR_COULDNOTWRITEXMLCONTENT, hResult);
	}
Exemple #15
0
	void CXmlWriter_COM::WriteFullEndElement()
	{
		HRESULT hResult = m_pXMLWriter->WriteFullEndElement();
		if (hResult != S_OK)
			throw CNMRException_Windows(NMR_ERROR_COULDNOTWRITEXMLENDELEMENT, hResult);
	}
Exemple #16
0
	void CXmlWriter_COM::WriteStartElement(_In_opt_  LPCWSTR pwszPrefix, _In_  LPCWSTR pwszLocalName, _In_opt_  LPCWSTR pwszNamespaceUri)
	{
		HRESULT hResult = m_pXMLWriter->WriteStartElement(pwszPrefix, pwszLocalName, pwszNamespaceUri);
		if (hResult != S_OK)
			throw CNMRException_Windows(NMR_ERROR_COULDNOTWRITEXMLSTARTELEMENT, hResult);
	}
	LIB3MFMETHODIMP CCOMModelTexture2D::ReadFromStream(_In_ IStream * pStream)
	{
		try {
			if (pStream == nullptr)
				throw CNMRException(NMR_ERROR_INVALIDPOINTER);

			HRESULT hResult;

			CModelTexture2DResource * pTextureResource = getTexture2D();
			__NMRASSERT(pTextureResource);

			CComPtr<IStream> pMemoryStream = nullptr;
			hResult = CreateStreamOnHGlobal(nullptr, true, &pMemoryStream);
			if (hResult != S_OK)
				throw CNMRException_Windows(NMR_ERROR_COULDNOTCREATESTREAM, hResult);

			// Seek Stream
			LARGE_INTEGER nOriginPosition;
			ULARGE_INTEGER nNewPosition;
			nOriginPosition.HighPart = 0;
			nOriginPosition.LowPart = 0;
			hResult = pStream->Seek(nOriginPosition, STREAM_SEEK_END, &nNewPosition);
			if (hResult != S_OK)
				throw CNMRException_Windows(NMR_ERROR_COULDNOTSEEKSTREAM, hResult);

			nfUint64 cbStreamSize = nNewPosition.QuadPart;

			hResult = pStream->Seek(nOriginPosition, STREAM_SEEK_SET, &nNewPosition);
			if (hResult != S_OK)
				throw CNMRException_Windows(NMR_ERROR_COULDNOTSEEKSTREAM, hResult);

			std::array<nfByte, NMR_IMPORTSTREAM_COPYBUFFERSIZE> pBuffer;

			nfUint64 cbBytesLeft = cbStreamSize;
			while (cbBytesLeft > 0) {
				nfUint64 cbLength = cbBytesLeft;
				if (cbLength > NMR_IMPORTSTREAM_COPYBUFFERSIZE)
					cbLength = NMR_IMPORTSTREAM_COPYBUFFERSIZE;

				ULONG cbReadBytes = 0;
				ULONG cbWrittenBytes = 0;
				hResult = pStream->Read(&pBuffer[0], (nfUint32)cbLength, &cbReadBytes);
				if (hResult != S_OK)
					throw CNMRException_Windows(NMR_ERROR_COULDNOTREADSTREAM, hResult);

				if (cbReadBytes != cbLength)
					throw CNMRException(NMR_ERROR_COULDNOTREADFULLDATA);

				hResult = pMemoryStream->Write(&pBuffer[0], (nfUint32)cbLength, &cbWrittenBytes);
				if (hResult != S_OK)
					throw CNMRException_Windows(NMR_ERROR_COULDNOTWRITESTREAM, hResult);

				if (cbWrittenBytes != cbLength)
					throw CNMRException(NMR_ERROR_COULDNOTWRITEFULLDATA);
				cbBytesLeft -= cbLength;
			}


			PImportStream pImportStream = std::make_shared<CImportStream_COM>(pMemoryStream);

			CModel * pModel = pTextureResource->getModel();
			__NMRASSERT(pModel);

			pModel->removeTextureStream(pTextureResource->getPath());
			pModel->addTextureStream(pTextureResource->getPath(), pImportStream);

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

	}