CModelWriterNode100_Model::CModelWriterNode100_Model(_In_ CModel * pModel, _In_ CXmlWriter * pXMLWriter)
    :CModelWriterNode(pModel, pXMLWriter)
{
    m_ResourceCounter = pModel->generateResourceID();

    m_pColorMapping = std::make_shared<CModelWriter_ColorMapping>(generateOutputResourceID ());

    m_pTexCoordMappingContainer = std::make_shared<CModelWriter_TexCoordMappingContainer>();

    nfInt32 nObjectCount = pModel->getObjectCount();
    nfInt32 nObjectIndex;

    for (nObjectIndex = 0; nObjectIndex < nObjectCount; nObjectIndex++) {
        PModelResource pResource = pModel->getObjectResource(nObjectIndex);

        CModelMeshObject * pMeshObject = dynamic_cast<CModelMeshObject*> (pResource.get());
        if (pMeshObject) {
            CMesh * pMesh = pMeshObject->getMesh();
            if (pMesh) {
                calculateColors(pMesh);
                calculateTexCoords(pMesh);
            }
        }

        // Register Default Property Resources
        CModelObject * pObject = dynamic_cast<CModelObject*> (pResource.get());
        if (pObject) {
            PModelDefaultProperty pProperty = pObject->getDefaultProperty();

            CModelDefaultProperty_Color * pColorProperty = dynamic_cast<CModelDefaultProperty_Color *> (pProperty.get());
            if (pColorProperty != nullptr) {
                nfColor cColor = pColorProperty->getColor();
                if (cColor != 0)
                    m_pColorMapping->registerColor(cColor);
            }

            CModelDefaultProperty_TexCoord2D * pTexCoord2DProperty = dynamic_cast<CModelDefaultProperty_TexCoord2D *> (pProperty.get());
            if (pTexCoord2DProperty != nullptr) {
                PModelWriter_TexCoordMapping pTexCoordMapping = m_pTexCoordMappingContainer->findTexture(pTexCoord2DProperty->getTextureID());
                if (pTexCoordMapping.get() == nullptr) {
                    pTexCoordMapping = m_pTexCoordMappingContainer->addTexture(pTexCoord2DProperty->getTextureID(), generateOutputResourceID());
                }

                pTexCoordMapping->registerTexCoords(pTexCoord2DProperty->getU(), pTexCoord2DProperty->getV());
            }

        }
    }
}
void CModelWriterNode100_Model::writeObjects()
{
    nfUint32 nObjectCount = m_pModel->getObjectCount();
    nfUint32 nObjectIndex;

    for (nObjectIndex = 0; nObjectIndex < nObjectCount; nObjectIndex++) {
        CModelObject * pObject = m_pModel->getObject(nObjectIndex);

        writeStartElement(XML_3MF_ELEMENT_OBJECT);
        // Write Object ID (mandatory)
        writeIntAttribute(XML_3MF_ATTRIBUTE_OBJECT_ID, pObject->getResourceID());

        // Write Object Name (optional)
        std::wstring sObjectName = pObject->getName();
        if (sObjectName.length() > 0)
            writeStringAttribute(XML_3MF_ATTRIBUTE_OBJECT_NAME, sObjectName);

        // Write Object Partnumber (optional)
        std::wstring sObjectPartNumber = pObject->getPartNumber();
        if (sObjectPartNumber.length() > 0)
            writeStringAttribute(XML_3MF_ATTRIBUTE_OBJECT_PARTNUMBER, sObjectPartNumber);

        // Write Object Type (optional)
        writeStringAttribute(XML_3MF_ATTRIBUTE_OBJECT_TYPE, pObject->getObjectTypeString());

        // Write Default Property Indices
        ModelResourceID nPropertyID = 0;
        ModelResourceIndex nPropertyIndex = 0;

        PModelDefaultProperty pProperty = pObject->getDefaultProperty();
        // Color Properties
        CModelDefaultProperty_Color * pColorProperty = dynamic_cast<CModelDefaultProperty_Color *> (pProperty.get());
        if (pColorProperty != nullptr) {
            if (m_pColorMapping->findColor(pColorProperty->getColor(), nPropertyIndex)) {
                nPropertyID = m_pColorMapping->getResourceID();
            }
        }

        // TexCoord2D Properties
        CModelDefaultProperty_TexCoord2D * pTexCoord2DProperty = dynamic_cast<CModelDefaultProperty_TexCoord2D *> (pProperty.get());
        if (pTexCoord2DProperty != nullptr) {
            PModelWriter_TexCoordMapping pTexCoordMapping = m_pTexCoordMappingContainer->findTexture(pTexCoord2DProperty->getTextureID());
            if (pTexCoordMapping.get() != nullptr) {
                if (pTexCoordMapping->findTexCoords(pTexCoord2DProperty->getU(), pTexCoord2DProperty->getV(), nPropertyIndex)) {
                    nPropertyID = pTexCoordMapping->getResourceID();
                }
            }
        }

        // Base Material Properties
        CModelDefaultProperty_BaseMaterial * pBaseMaterialProperty = dynamic_cast<CModelDefaultProperty_BaseMaterial *> (pProperty.get());
        if (pBaseMaterialProperty != nullptr) {
            nPropertyID = pBaseMaterialProperty->getResourceID();
            nPropertyIndex = pBaseMaterialProperty->getResourceIndex();
        }

        // Write Attributes
        if (nPropertyID != 0) {
            writeIntAttribute(XML_3MF_ATTRIBUTE_OBJECT_PID, nPropertyID);
            writeIntAttribute(XML_3MF_ATTRIBUTE_OBJECT_PINDEX, nPropertyIndex);
        }


        // Check if object is a mesh Object
        CModelMeshObject * pMeshObject = dynamic_cast<CModelMeshObject *> (pObject);
        if (pMeshObject) {
            CModelWriterNode100_Mesh ModelWriter_Mesh(pMeshObject, m_pXMLWriter, m_pColorMapping, m_pTexCoordMappingContainer);
            ModelWriter_Mesh.writeToXML();
        }

        // Check if object is a component Object
        CModelComponentsObject * pComponentObject = dynamic_cast<CModelComponentsObject *> (pObject);
        if (pComponentObject) {
            writeComponentsObject(pComponentObject);
        }

        writeFullEndElement();
    }

}