﻿/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------

Copyright (c) 2006-2017, assimp team


All rights reserved.

Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:

* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.

* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.

* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/

/// \file AMFImporter_Postprocess.cpp
/// \brief Convert built scenegraph and objects to Assimp scenegraph.
/// \date 2016
/// \author smal.root@gmail.com

#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER

#include "AMFImporter.hpp"

// Header files, Assimp.
#include <assimp/SceneCombiner.h>
#include "StandardShapes.h"
#include "StringUtils.h"

// Header files, stdlib.
#include <iterator>

namespace Assimp
{

aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*pY*/, const float /*pZ*/) const
{
    aiColor4D tcol;

	// Check if stored data are supported.
	if(Composition.size() != 0)
	{
		throw DeadlyImportError("IME. GetColor for composition");
	}
	else if(Color->Composed)
	{
		throw DeadlyImportError("IME. GetColor, composed color");
	}
	else
	{
		tcol = Color->Color;
	}

	// Check if default color must be used
	if((tcol.r == 0) && (tcol.g == 0) && (tcol.b == 0) && (tcol.a == 0))
	{
		tcol.r = 0.5f;
		tcol.g = 0.5f;
		tcol.b = 0.5f;
		tcol.a = 1;
	}

	return tcol;
}

void AMFImporter::PostprocessHelper_CreateMeshDataArray(const CAMFImporter_NodeElement_Mesh& pNodeElement, std::vector<aiVector3D>& pVertexCoordinateArray,
														std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray) const
{
    CAMFImporter_NodeElement_Vertices* vn = nullptr;
    size_t col_idx;

	// All data stored in "vertices", search for it.
	for(CAMFImporter_NodeElement* ne_child: pNodeElement.Child)
	{
		if(ne_child->Type == CAMFImporter_NodeElement::ENET_Vertices) vn = (CAMFImporter_NodeElement_Vertices*)ne_child;
	}

	// If "vertices" not found then no work for us.
	if(vn == nullptr) return;

	pVertexCoordinateArray.reserve(vn->Child.size());// all coordinates stored as child and we need to reserve space for future push_back's.
	pVertexColorArray.resize(vn->Child.size());// colors count equal vertices count.
	col_idx = 0;
	// Inside vertices collect all data and place to arrays
	for(CAMFImporter_NodeElement* vn_child: vn->Child)
	{
		// vertices, colors
		if(vn_child->Type == CAMFImporter_NodeElement::ENET_Vertex)
		{
			// by default clear color for current vertex
			pVertexColorArray[col_idx] = nullptr;

			for(CAMFImporter_NodeElement* vtx: vn_child->Child)
			{
				if(vtx->Type == CAMFImporter_NodeElement::ENET_Coordinates)
				{
					pVertexCoordinateArray.push_back(((CAMFImporter_NodeElement_Coordinates*)vtx)->Coordinate);

					continue;
				}

				if(vtx->Type == CAMFImporter_NodeElement::ENET_Color)
				{
					pVertexColorArray[col_idx] = (CAMFImporter_NodeElement_Color*)vtx;

					continue;
				}
			}// for(CAMFImporter_NodeElement* vtx: vn_child->Child)

			col_idx++;
		}// if(vn_child->Type == CAMFImporter_NodeElement::ENET_Vertex)
	}// for(CAMFImporter_NodeElement* vn_child: vn->Child)
}

size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B,
																const std::string& pID_A)
{
    size_t TextureConverted_Index;
    std::string TextureConverted_ID;

	// check input data
	if(pID_R.empty() && pID_G.empty() && pID_B.empty() && pID_A.empty())
		throw DeadlyImportError("PostprocessHelper_GetTextureID_Or_Create. At least one texture ID must be defined.");

	// Create ID
	TextureConverted_ID = pID_R + "_" + pID_G + "_" + pID_B + "_" + pID_A;
	// Check if texture specified by set of IDs is converted already.
	TextureConverted_Index = 0;
	for(const SPP_Texture& tex_convd: mTexture_Converted)
	{
		if(tex_convd.ID == TextureConverted_ID)
			return TextureConverted_Index;
		else
			TextureConverted_Index++;
	}

	//
	// Converted texture not found, create it.
	//
	CAMFImporter_NodeElement_Texture* src_texture[4]{nullptr};
	std::vector<CAMFImporter_NodeElement_Texture*> src_texture_4check;
	SPP_Texture converted_texture;

	{// find all specified source textures
		CAMFImporter_NodeElement* t_tex;

		// R
		if(!pID_R.empty())
		{
			if(!Find_NodeElement(pID_R, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_R);

			src_texture[0] = (CAMFImporter_NodeElement_Texture*)t_tex;
			src_texture_4check.push_back((CAMFImporter_NodeElement_Texture*)t_tex);
		}
		else
		{
			src_texture[0] = nullptr;
		}

		// G
		if(!pID_G.empty())
		{
			if(!Find_NodeElement(pID_G, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_G);

			src_texture[1] = (CAMFImporter_NodeElement_Texture*)t_tex;
			src_texture_4check.push_back((CAMFImporter_NodeElement_Texture*)t_tex);
		}
		else
		{
			src_texture[1] = nullptr;
		}

		// B
		if(!pID_B.empty())
		{
			if(!Find_NodeElement(pID_B, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_B);

			src_texture[2] = (CAMFImporter_NodeElement_Texture*)t_tex;
			src_texture_4check.push_back((CAMFImporter_NodeElement_Texture*)t_tex);
		}
		else
		{
			src_texture[2] = nullptr;
		}

		// A
		if(!pID_A.empty())
		{
			if(!Find_NodeElement(pID_A, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_A);

			src_texture[3] = (CAMFImporter_NodeElement_Texture*)t_tex;
			src_texture_4check.push_back((CAMFImporter_NodeElement_Texture*)t_tex);
		}
		else
		{
			src_texture[3] = nullptr;
		}
	}// END: find all specified source textures

	// check that all textures has same size
	if(src_texture_4check.size() > 1)
	{
		for (size_t i = 0, i_e = (src_texture_4check.size() - 1); i < i_e; i++)
		{
			if((src_texture_4check[i]->Width != src_texture_4check[i + 1]->Width) || (src_texture_4check[i]->Height != src_texture_4check[i + 1]->Height) ||
				(src_texture_4check[i]->Depth != src_texture_4check[i + 1]->Depth))
			{
				throw DeadlyImportError("PostprocessHelper_GetTextureID_Or_Create. Source texture must has the same size.");
			}
		}
	}// if(src_texture_4check.size() > 1)

	// set texture attributes
	converted_texture.Width = src_texture_4check[0]->Width;
	converted_texture.Height = src_texture_4check[0]->Height;
	converted_texture.Depth = src_texture_4check[0]->Depth;
	// if one of source texture is tiled then converted texture is tiled too.
	converted_texture.Tiled = false;
	for(uint8_t i = 0; i < src_texture_4check.size(); i++) converted_texture.Tiled |= src_texture_4check[i]->Tiled;

	// Create format hint.
	strcpy(converted_texture.FormatHint, "rgba0000");// copy initial string.
	if(!pID_R.empty()) converted_texture.FormatHint[4] = '8';
	if(!pID_G.empty()) converted_texture.FormatHint[5] = '8';
	if(!pID_B.empty()) converted_texture.FormatHint[6] = '8';
	if(!pID_A.empty()) converted_texture.FormatHint[7] = '8';

	//
	// Сopy data of textures.
	//
	size_t tex_size = 0;
	size_t step = 0;
	size_t off_g = 0;
	size_t off_b = 0;

	// Calculate size of the target array and rule how data will be copied.
    if(!pID_R.empty() && nullptr != src_texture[ 0 ] ) {
        tex_size += src_texture[0]->Data.size(); step++, off_g++, off_b++;
    }
    if(!pID_G.empty() && nullptr != src_texture[ 1 ] ) {
        tex_size += src_texture[1]->Data.size(); step++, off_b++;
    }
    if(!pID_B.empty() && nullptr != src_texture[ 2 ] ) {
        tex_size += src_texture[2]->Data.size(); step++;
    }
    if(!pID_A.empty() && nullptr != src_texture[ 3 ] ) {
        tex_size += src_texture[3]->Data.size(); step++;
    }

    // Create target array.
	converted_texture.Data = new uint8_t[tex_size];
	// And copy data
	auto CopyTextureData = [&](const std::string& pID, const size_t pOffset, const size_t pStep, const uint8_t pSrcTexNum) -> void
	{
		if(!pID.empty())
		{
			for(size_t idx_target = pOffset, idx_src = 0; idx_target < tex_size; idx_target += pStep, idx_src++) {
				CAMFImporter_NodeElement_Texture* tex = src_texture[pSrcTexNum];
				ai_assert(tex);
				converted_texture.Data[idx_target] = tex->Data.at(idx_src);
			}
		}
	};// auto CopyTextureData = [&](const size_t pOffset, const size_t pStep, const uint8_t pSrcTexNum) -> void

	CopyTextureData(pID_R, 0, step, 0);
	CopyTextureData(pID_G, off_g, step, 1);
	CopyTextureData(pID_B, off_b, step, 2);
	CopyTextureData(pID_A, step - 1, step, 3);

	// Store new converted texture ID
	converted_texture.ID = TextureConverted_ID;
	// Store new converted texture
	mTexture_Converted.push_back(converted_texture);

	return TextureConverted_Index;
}

void AMFImporter::PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace>& pInputList, std::list<std::list<SComplexFace> >& pOutputList_Separated)
{
    auto texmap_is_equal = [](const CAMFImporter_NodeElement_TexMap* pTexMap1, const CAMFImporter_NodeElement_TexMap* pTexMap2) -> bool
    {
	    if((pTexMap1 == nullptr) && (pTexMap2 == nullptr)) return true;
	    if(pTexMap1 == nullptr) return false;
	    if(pTexMap2 == nullptr) return false;

	    if(pTexMap1->TextureID_R != pTexMap2->TextureID_R) return false;
	    if(pTexMap1->TextureID_G != pTexMap2->TextureID_G) return false;
	    if(pTexMap1->TextureID_B != pTexMap2->TextureID_B) return false;
	    if(pTexMap1->TextureID_A != pTexMap2->TextureID_A) return false;

	    return true;
    };

	pOutputList_Separated.clear();
	if(pInputList.size() == 0) return;

	do
	{
		SComplexFace face_start = pInputList.front();
		std::list<SComplexFace> face_list_cur;

		for(std::list<SComplexFace>::iterator it = pInputList.begin(), it_end = pInputList.end(); it != it_end;)
		{
			if(texmap_is_equal(face_start.TexMap, it->TexMap))
			{
				auto it_old = it;

				it++;
				face_list_cur.push_back(*it_old);
				pInputList.erase(it_old);
			}
			else
			{
				it++;
			}
		}

		if(face_list_cur.size() > 0) pOutputList_Separated.push_back(face_list_cur);

	} while(pInputList.size() > 0);
}

void AMFImporter::Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& metadataList, aiNode& sceneNode) const
{
	if ( !metadataList.empty() )
	{
		if(sceneNode.mMetaData != nullptr) throw DeadlyImportError("Postprocess. MetaData member in node are not nullptr. Something went wrong.");

		// copy collected metadata to output node.
        sceneNode.mMetaData = aiMetadata::Alloc( static_cast<unsigned int>(metadataList.size()) );
		size_t meta_idx( 0 );

		for(const CAMFImporter_NodeElement_Metadata& metadata: metadataList)
		{
			sceneNode.mMetaData->Set(static_cast<unsigned int>(meta_idx++), metadata.Type, aiString(metadata.Value));
		}
	}// if(!metadataList.empty())
}

void AMFImporter::Postprocess_BuildNodeAndObject(const CAMFImporter_NodeElement_Object& pNodeElement, std::list<aiMesh*>& pMeshList, aiNode** pSceneNode)
{
CAMFImporter_NodeElement_Color* object_color = nullptr;

	// create new aiNode and set name as <object> has.
	*pSceneNode = new aiNode;
	(*pSceneNode)->mName = pNodeElement.ID;
	// read mesh and color
	for(const CAMFImporter_NodeElement* ne_child: pNodeElement.Child)
	{
		std::vector<aiVector3D> vertex_arr;
		std::vector<CAMFImporter_NodeElement_Color*> color_arr;

		// color for object
		if(ne_child->Type == CAMFImporter_NodeElement::ENET_Color) object_color = (CAMFImporter_NodeElement_Color*)ne_child;

		if(ne_child->Type == CAMFImporter_NodeElement::ENET_Mesh)
		{
			// Create arrays from children of mesh: vertices.
			PostprocessHelper_CreateMeshDataArray(*((CAMFImporter_NodeElement_Mesh*)ne_child), vertex_arr, color_arr);
			// Use this arrays as a source when creating every aiMesh
			Postprocess_BuildMeshSet(*((CAMFImporter_NodeElement_Mesh*)ne_child), vertex_arr, color_arr, object_color, pMeshList, **pSceneNode);
		}
	}// for(const CAMFImporter_NodeElement* ne_child: pNodeElement)
}

void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh& pNodeElement, const std::vector<aiVector3D>& pVertexCoordinateArray,
											const std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray,
											const CAMFImporter_NodeElement_Color* pObjectColor, std::list<aiMesh*>& pMeshList, aiNode& pSceneNode)
{
std::list<unsigned int> mesh_idx;

	// all data stored in "volume", search for it.
	for(const CAMFImporter_NodeElement* ne_child: pNodeElement.Child)
	{
		const CAMFImporter_NodeElement_Color* ne_volume_color = nullptr;
		const SPP_Material* cur_mat = nullptr;

		if(ne_child->Type == CAMFImporter_NodeElement::ENET_Volume)
		{
			/******************* Get faces *******************/
			const CAMFImporter_NodeElement_Volume* ne_volume = reinterpret_cast<const CAMFImporter_NodeElement_Volume*>(ne_child);

			std::list<SComplexFace> complex_faces_list;// List of the faces of the volume.
			std::list<std::list<SComplexFace> > complex_faces_toplist;// List of the face list for every mesh.

			// check if volume use material
			if(!ne_volume->MaterialID.empty())
			{
				if(!Find_ConvertedMaterial(ne_volume->MaterialID, &cur_mat)) Throw_ID_NotFound(ne_volume->MaterialID);
			}

			// inside "volume" collect all data and place to arrays or create new objects
			for(const CAMFImporter_NodeElement* ne_volume_child: ne_volume->Child)
			{
				// color for volume
				if(ne_volume_child->Type == CAMFImporter_NodeElement::ENET_Color)
				{
					ne_volume_color = reinterpret_cast<const CAMFImporter_NodeElement_Color*>(ne_volume_child);
				}
				else if(ne_volume_child->Type == CAMFImporter_NodeElement::ENET_Triangle)// triangles, triangles colors
				{
					const CAMFImporter_NodeElement_Triangle& tri_al = *reinterpret_cast<const CAMFImporter_NodeElement_Triangle*>(ne_volume_child);

					SComplexFace complex_face;

					// initialize pointers
					complex_face.Color = nullptr;
					complex_face.TexMap = nullptr;
					// get data from triangle children: color, texture coordinates.
					if(tri_al.Child.size())
					{
						for(const CAMFImporter_NodeElement* ne_triangle_child: tri_al.Child)
						{
							if(ne_triangle_child->Type == CAMFImporter_NodeElement::ENET_Color)
								complex_face.Color = reinterpret_cast<const CAMFImporter_NodeElement_Color*>(ne_triangle_child);
							else if(ne_triangle_child->Type == CAMFImporter_NodeElement::ENET_TexMap)
								complex_face.TexMap = reinterpret_cast<const CAMFImporter_NodeElement_TexMap*>(ne_triangle_child);
						}
					}// if(tri_al.Child.size())

					// create new face and store it.
					complex_face.Face.mNumIndices = 3;
					complex_face.Face.mIndices = new unsigned int[3];
					complex_face.Face.mIndices[0] = static_cast<unsigned int>(tri_al.V[0]);
					complex_face.Face.mIndices[1] = static_cast<unsigned int>(tri_al.V[1]);
					complex_face.Face.mIndices[2] = static_cast<unsigned int>(tri_al.V[2]);
					complex_faces_list.push_back(complex_face);
				}
			}// for(const CAMFImporter_NodeElement* ne_volume_child: ne_volume->Child)

			/**** Split faces list: one list per mesh ****/
			PostprocessHelper_SplitFacesByTextureID(complex_faces_list, complex_faces_toplist);

			/***** Create mesh for every faces list ******/
			for(std::list<SComplexFace>& face_list_cur: complex_faces_toplist)
			{
				auto VertexIndex_GetMinimal = [](const std::list<SComplexFace>& pFaceList, const size_t* pBiggerThan) -> size_t
				{
					size_t rv;

					if(pBiggerThan != nullptr)
					{
						bool found = false;

						for(const SComplexFace& face: pFaceList)
						{
							for(size_t idx_vert = 0; idx_vert < face.Face.mNumIndices; idx_vert++)
							{
								if(face.Face.mIndices[idx_vert] > *pBiggerThan)
								{
									rv = face.Face.mIndices[idx_vert];
									found = true;

									break;
								}
							}

							if(found) break;
						}

						if(!found) return *pBiggerThan;
					}
					else
					{
						rv = pFaceList.front().Face.mIndices[0];
					}// if(pBiggerThan != nullptr) else

					for(const SComplexFace& face: pFaceList)
					{
						for(size_t vi = 0; vi < face.Face.mNumIndices; vi++)
						{
							if(face.Face.mIndices[vi] < rv)
							{
								if(pBiggerThan != nullptr)
								{
									if(face.Face.mIndices[vi] > *pBiggerThan) rv = face.Face.mIndices[vi];
								}
								else
								{
									rv = face.Face.mIndices[vi];
								}
							}
						}
					}// for(const SComplexFace& face: pFaceList)

					return rv;
				};// auto VertexIndex_GetMinimal = [](const std::list<SComplexFace>& pFaceList, const size_t* pBiggerThan) -> size_t

				auto VertexIndex_Replace = [](std::list<SComplexFace>& pFaceList, const size_t pIdx_From, const size_t pIdx_To) -> void
				{
					for(const SComplexFace& face: pFaceList)
					{
						for(size_t vi = 0; vi < face.Face.mNumIndices; vi++)
						{
							if(face.Face.mIndices[vi] == pIdx_From) face.Face.mIndices[vi] = static_cast<unsigned int>(pIdx_To);
						}
					}
				};// auto VertexIndex_Replace = [](std::list<SComplexFace>& pFaceList, const size_t pIdx_From, const size_t pIdx_To) -> void

				auto Vertex_CalculateColor = [&](const size_t pIdx) -> aiColor4D
				{
					// Color priorities(In descending order):
					// 1. triangle color;
					// 2. vertex color;
					// 3. volume color;
					// 4. object color;
					// 5. material;
					// 6. default - invisible coat.
					//
					// Fill vertices colors in color priority list above that's points from 1 to 6.
					if((pIdx < pVertexColorArray.size()) && (pVertexColorArray[pIdx] != nullptr))// check for vertex color
					{
						if(pVertexColorArray[pIdx]->Composed)
							throw DeadlyImportError("IME: vertex color composed");
						else
							return pVertexColorArray[pIdx]->Color;
					}
					else if(ne_volume_color != nullptr)// check for volume color
					{
						if(ne_volume_color->Composed)
							throw DeadlyImportError("IME: volume color composed");
						else
							return ne_volume_color->Color;
					}
					else if(pObjectColor != nullptr)// check for object color
					{
						if(pObjectColor->Composed)
							throw DeadlyImportError("IME: object color composed");
						else
							return pObjectColor->Color;
					}
					else if(cur_mat != nullptr)// check for material
					{
						return cur_mat->GetColor(pVertexCoordinateArray.at(pIdx).x, pVertexCoordinateArray.at(pIdx).y, pVertexCoordinateArray.at(pIdx).z);
					}
					else// set default color.
					{
						return {0, 0, 0, 0};
					}// if((vi < pVertexColorArray.size()) && (pVertexColorArray[vi] != nullptr)) else

				};// auto Vertex_CalculateColor = [&](const size_t pIdx) -> aiColor4D

				aiMesh* tmesh = new aiMesh;

				tmesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;// Only triangles is supported by AMF.
				//
				// set geometry and colors (vertices)
				//
				// copy faces/triangles
				tmesh->mNumFaces = static_cast<unsigned int>(face_list_cur.size());
				tmesh->mFaces = new aiFace[tmesh->mNumFaces];

				// Create vertices list and optimize indices. Optimisation mean following.In AMF all volumes use one big list of vertices. And one volume
				// can use only part of vertices list, for example: vertices list contain few thousands of vertices and volume use vertices 1, 3, 10.
				// Do you need all this thousands of garbage? Of course no. So, optimisation step transformate sparse indices set to continuous.
				size_t VertexCount_Max = tmesh->mNumFaces * 3;// 3 - triangles.
				std::vector<aiVector3D> vert_arr, texcoord_arr;
				std::vector<aiColor4D> col_arr;

				vert_arr.reserve(VertexCount_Max * 2);// "* 2" - see below TODO.
				col_arr.reserve(VertexCount_Max * 2);

				{// fill arrays
					size_t vert_idx_from, vert_idx_to;

					// first iteration.
					vert_idx_to = 0;
					vert_idx_from = VertexIndex_GetMinimal(face_list_cur, nullptr);
					vert_arr.push_back(pVertexCoordinateArray.at(vert_idx_from));
					col_arr.push_back(Vertex_CalculateColor(vert_idx_from));
					if(vert_idx_from != vert_idx_to) VertexIndex_Replace(face_list_cur, vert_idx_from, vert_idx_to);

					// rest iterations
					do
					{
						vert_idx_from = VertexIndex_GetMinimal(face_list_cur, &vert_idx_to);
						if(vert_idx_from == vert_idx_to) break;// all indices are transferred,

						vert_arr.push_back(pVertexCoordinateArray.at(vert_idx_from));
						col_arr.push_back(Vertex_CalculateColor(vert_idx_from));
						vert_idx_to++;
						if(vert_idx_from != vert_idx_to) VertexIndex_Replace(face_list_cur, vert_idx_from, vert_idx_to);

					} while(true);
				}// fill arrays. END.

				//
				// check if triangle colors are used and create additional faces if needed.
				//
				for(const SComplexFace& face_cur: face_list_cur)
				{
					if(face_cur.Color != nullptr)
					{
						aiColor4D face_color;
						size_t vert_idx_new = vert_arr.size();

						if(face_cur.Color->Composed)
							throw DeadlyImportError("IME: face color composed");
						else
							face_color = face_cur.Color->Color;

						for(size_t idx_ind = 0; idx_ind < face_cur.Face.mNumIndices; idx_ind++)
						{
							vert_arr.push_back(vert_arr.at(face_cur.Face.mIndices[idx_ind]));
							col_arr.push_back(face_color);
							face_cur.Face.mIndices[idx_ind] = static_cast<unsigned int>(vert_idx_new++);
						}
					}// if(face_cur.Color != nullptr)
				}// for(const SComplexFace& face_cur: face_list_cur)

				//
				// if texture is used then copy texture coordinates too.
				//
				if(face_list_cur.front().TexMap != nullptr)
				{
					size_t idx_vert_new = vert_arr.size();
					///TODO: clean unused vertices. "* 2": in certain cases - mesh full of triangle colors - vert_arr will contain duplicated vertices for
					/// colored triangles and initial vertices (for colored vertices) which in real became unused. This part need more thinking about
					/// optimisation.
					bool* idx_vert_used;

					idx_vert_used = new bool[VertexCount_Max * 2];
					for(size_t i = 0, i_e = VertexCount_Max * 2; i < i_e; i++) idx_vert_used[i] = false;

					// This ID's will be used when set materials ID in scene.
					tmesh->mMaterialIndex = static_cast<unsigned int>(PostprocessHelper_GetTextureID_Or_Create(face_list_cur.front().TexMap->TextureID_R,
																						face_list_cur.front().TexMap->TextureID_G,
																						face_list_cur.front().TexMap->TextureID_B,
																						face_list_cur.front().TexMap->TextureID_A));
					texcoord_arr.resize(VertexCount_Max * 2);
					for(const SComplexFace& face_cur: face_list_cur)
					{
						for(size_t idx_ind = 0; idx_ind < face_cur.Face.mNumIndices; idx_ind++)
						{
							const size_t idx_vert = face_cur.Face.mIndices[idx_ind];

							if(!idx_vert_used[idx_vert])
							{
								texcoord_arr.at(idx_vert) = face_cur.TexMap->TextureCoordinate[idx_ind];
								idx_vert_used[idx_vert] = true;
							}
							else if(texcoord_arr.at(idx_vert) != face_cur.TexMap->TextureCoordinate[idx_ind])
							{
								// in that case one vertex is shared with many texture coordinates. We need to duplicate vertex with another texture
								// coordinates.
								vert_arr.push_back(vert_arr.at(idx_vert));
								col_arr.push_back(col_arr.at(idx_vert));
								texcoord_arr.at(idx_vert_new) = face_cur.TexMap->TextureCoordinate[idx_ind];
								face_cur.Face.mIndices[idx_ind] = static_cast<unsigned int>(idx_vert_new++);
							}
						}// for(size_t idx_ind = 0; idx_ind < face_cur.Face.mNumIndices; idx_ind++)
					}// for(const SComplexFace& face_cur: face_list_cur)

					delete [] idx_vert_used;
					// shrink array
					texcoord_arr.resize(idx_vert_new);
				}// if(face_list_cur.front().TexMap != nullptr)

				//
				// copy collected data to mesh
				//
				tmesh->mNumVertices = static_cast<unsigned int>(vert_arr.size());
				tmesh->mVertices = new aiVector3D[tmesh->mNumVertices];
				tmesh->mColors[0] = new aiColor4D[tmesh->mNumVertices];

				memcpy(tmesh->mVertices, vert_arr.data(), tmesh->mNumVertices * sizeof(aiVector3D));
				memcpy(tmesh->mColors[0], col_arr.data(), tmesh->mNumVertices * sizeof(aiColor4D));
				if(texcoord_arr.size() > 0)
				{
					tmesh->mTextureCoords[0] = new aiVector3D[tmesh->mNumVertices];
					memcpy(tmesh->mTextureCoords[0], texcoord_arr.data(), tmesh->mNumVertices * sizeof(aiVector3D));
					tmesh->mNumUVComponents[0] = 2;// U and V stored in "x", "y" of aiVector3D.
				}

				size_t idx_face = 0;
				for(const SComplexFace& face_cur: face_list_cur) tmesh->mFaces[idx_face++] = face_cur.Face;

				// store new aiMesh
				mesh_idx.push_back(static_cast<unsigned int>(pMeshList.size()));
				pMeshList.push_back(tmesh);
			}// for(const std::list<SComplexFace>& face_list_cur: complex_faces_toplist)
		}// if(ne_child->Type == CAMFImporter_NodeElement::ENET_Volume)
	}// for(const CAMFImporter_NodeElement* ne_child: pNodeElement.Child)

	// if meshes was created then assign new indices with current aiNode
	if(mesh_idx.size() > 0)
	{
		std::list<unsigned int>::const_iterator mit = mesh_idx.begin();

		pSceneNode.mNumMeshes = static_cast<unsigned int>(mesh_idx.size());
		pSceneNode.mMeshes = new unsigned int[pSceneNode.mNumMeshes];
		for(size_t i = 0; i < pSceneNode.mNumMeshes; i++) pSceneNode.mMeshes[i] = *mit++;
	}// if(mesh_idx.size() > 0)
}

void AMFImporter::Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Material& pMaterial)
{
SPP_Material new_mat;

	new_mat.ID = pMaterial.ID;
	for(const CAMFImporter_NodeElement* mat_child: pMaterial.Child)
	{
		if(mat_child->Type == CAMFImporter_NodeElement::ENET_Color)
		{
			new_mat.Color = (CAMFImporter_NodeElement_Color*)mat_child;
		}
		else if(mat_child->Type == CAMFImporter_NodeElement::ENET_Metadata)
		{
			new_mat.Metadata.push_back((CAMFImporter_NodeElement_Metadata*)mat_child);
		}
	}// for(const CAMFImporter_NodeElement* mat_child; pMaterial.Child)

	// place converted material to special list
	mMaterial_Converted.push_back(new_mat);
}

void AMFImporter::Postprocess_BuildConstellation(CAMFImporter_NodeElement_Constellation& pConstellation, std::list<aiNode*>& pNodeList) const
{
aiNode* con_node;
std::list<aiNode*> ch_node;

	// We will build next hierarchy:
	// aiNode as parent (<constellation>) for set of nodes as a children
	//  |- aiNode for transformation (<instance> -> <delta...>, <r...>) - aiNode for pointing to object ("objectid")
	//  ...
	//  \_ aiNode for transformation (<instance> -> <delta...>, <r...>) - aiNode for pointing to object ("objectid")
	con_node = new aiNode;
	con_node->mName = pConstellation.ID;
	// Walk through children and search for instances of another objects, constellations.
	for(const CAMFImporter_NodeElement* ne: pConstellation.Child)
	{
		aiMatrix4x4 tmat;
		aiNode* t_node;
		aiNode* found_node;

		if(ne->Type == CAMFImporter_NodeElement::ENET_Metadata) continue;
		if(ne->Type != CAMFImporter_NodeElement::ENET_Instance) throw DeadlyImportError("Only <instance> nodes can be in <constellation>.");

		// create alias for conveniance
		CAMFImporter_NodeElement_Instance& als = *((CAMFImporter_NodeElement_Instance*)ne);
		// find referenced object
		if(!Find_ConvertedNode(als.ObjectID, pNodeList, &found_node)) Throw_ID_NotFound(als.ObjectID);

		// create node for apllying transformation
		t_node = new aiNode;
		t_node->mParent = con_node;
		// apply transformation
		aiMatrix4x4::Translation(als.Delta, tmat), t_node->mTransformation *= tmat;
		aiMatrix4x4::RotationX(als.Rotation.x, tmat), t_node->mTransformation *= tmat;
		aiMatrix4x4::RotationY(als.Rotation.y, tmat), t_node->mTransformation *= tmat;
		aiMatrix4x4::RotationZ(als.Rotation.z, tmat), t_node->mTransformation *= tmat;
		// create array for one child node
		t_node->mNumChildren = 1;
		t_node->mChildren = new aiNode*[t_node->mNumChildren];
		SceneCombiner::Copy(&t_node->mChildren[0], found_node);
		t_node->mChildren[0]->mParent = t_node;
		ch_node.push_back(t_node);
	}// for(const CAMFImporter_NodeElement* ne: pConstellation.Child)

	// copy found aiNode's as children
	if(ch_node.size() == 0) throw DeadlyImportError("<constellation> must have at least one <instance>.");

	size_t ch_idx = 0;

	con_node->mNumChildren = static_cast<unsigned int>(ch_node.size());
	con_node->mChildren = new aiNode*[con_node->mNumChildren];
	for(aiNode* node: ch_node) con_node->mChildren[ch_idx++] = node;

	// and place "root" of <constellation> node to node list
	pNodeList.push_back(con_node);
}

void AMFImporter::Postprocess_BuildScene(aiScene* pScene)
{
std::list<aiNode*> node_list;
std::list<aiMesh*> mesh_list;
std::list<CAMFImporter_NodeElement_Metadata*> meta_list;

	//
	// Because for AMF "material" is just complex colors mixing so aiMaterial will not be used.
	// For building aiScene we are must to do few steps:
	// at first creating root node for aiScene.
	pScene->mRootNode = new aiNode;
	pScene->mRootNode->mParent = nullptr;
	pScene->mFlags |= AI_SCENE_FLAGS_ALLOW_SHARED;
	// search for root(<amf>) element
	CAMFImporter_NodeElement* root_el = nullptr;

	for(CAMFImporter_NodeElement* ne: mNodeElement_List)
	{
		if(ne->Type != CAMFImporter_NodeElement::ENET_Root) continue;

		root_el = ne;

		break;
	}// for(const CAMFImporter_NodeElement* ne: mNodeElement_List)

	// Check if root element are found.
	if(root_el == nullptr) throw DeadlyImportError("Root(<amf>) element not found.");

	// after that walk through children of root and collect data. Five types of nodes can be placed at top level - in <amf>: <object>, <material>, <texture>,
	// <constellation> and <metadata>. But at first we must read <material> and <texture> because they will be used in <object>. <metadata> can be read
	// at any moment.
	//
	// 1. <material>
	// 2. <texture> will be converted later when processing triangles list. \sa Postprocess_BuildMeshSet
	for(const CAMFImporter_NodeElement* root_child: root_el->Child)
	{
		if(root_child->Type == CAMFImporter_NodeElement::ENET_Material) Postprocess_BuildMaterial(*((CAMFImporter_NodeElement_Material*)root_child));
	}

	// After "appearance" nodes we must read <object> because it will be used in <constellation> -> <instance>.
	//
	// 3. <object>
	for(const CAMFImporter_NodeElement* root_child: root_el->Child)
	{
		if(root_child->Type == CAMFImporter_NodeElement::ENET_Object)
		{
			aiNode* tnode = nullptr;

			// for <object> mesh and node must be built: object ID assigned to aiNode name and will be used in future for <instance>
			Postprocess_BuildNodeAndObject(*((CAMFImporter_NodeElement_Object*)root_child), mesh_list, &tnode);
			if(tnode != nullptr) node_list.push_back(tnode);

		}
	}// for(const CAMFImporter_NodeElement* root_child: root_el->Child)

	// And finally read rest of nodes.
	//
	for(const CAMFImporter_NodeElement* root_child: root_el->Child)
	{
		// 4. <constellation>
		if(root_child->Type == CAMFImporter_NodeElement::ENET_Constellation)
		{
			// <object> and <constellation> at top of self abstraction use aiNode. So we can use only aiNode list for creating new aiNode's.
			Postprocess_BuildConstellation(*((CAMFImporter_NodeElement_Constellation*)root_child), node_list);
		}

		// 5, <metadata>
		if(root_child->Type == CAMFImporter_NodeElement::ENET_Metadata) meta_list.push_back((CAMFImporter_NodeElement_Metadata*)root_child);
	}// for(const CAMFImporter_NodeElement* root_child: root_el->Child)

	// at now we can add collected metadata to root node
	Postprocess_AddMetadata(meta_list, *pScene->mRootNode);
	//
	// Check constellation children
	//
	// As said in specification:
	// "When multiple objects and constellations are defined in a single file, only the top level objects and constellations are available for printing."
	// What that means? For example: if some object is used in constellation then you must show only constellation but not original object.
	// And at this step we are checking that relations.
nl_clean_loop:

	if(node_list.size() > 1)
	{
		// walk through all nodes
		for(std::list<aiNode*>::iterator nl_it = node_list.begin(); nl_it != node_list.end(); nl_it++)
		{
			// and try to find them in another top nodes.
			std::list<aiNode*>::const_iterator next_it = nl_it;

			next_it++;
			for(; next_it != node_list.end(); next_it++)
			{
				if((*next_it)->FindNode((*nl_it)->mName) != nullptr)
				{
					// if current top node(nl_it) found in another top node then erase it from node_list and restart search loop.
					node_list.erase(nl_it);

					goto nl_clean_loop;
				}
			}// for(; next_it != node_list.end(); next_it++)
		}// for(std::list<aiNode*>::const_iterator nl_it = node_list.begin(); nl_it != node_list.end(); nl_it++)
	}

	//
	// move created objects to aiScene
	//
	//
	// Nodes
	if(node_list.size() > 0)
	{
		std::list<aiNode*>::const_iterator nl_it = node_list.begin();

		pScene->mRootNode->mNumChildren = static_cast<unsigned int>(node_list.size());
		pScene->mRootNode->mChildren = new aiNode*[pScene->mRootNode->mNumChildren];
		for(size_t i = 0; i < pScene->mRootNode->mNumChildren; i++)
		{
			// Objects and constellation that must be showed placed at top of hierarchy in <amf> node. So all aiNode's in node_list must have
			// mRootNode only as parent.
			(*nl_it)->mParent = pScene->mRootNode;
			pScene->mRootNode->mChildren[i] = *nl_it++;
		}
	}// if(node_list.size() > 0)

	//
	// Meshes
	if(mesh_list.size() > 0)
	{
		std::list<aiMesh*>::const_iterator ml_it = mesh_list.begin();

		pScene->mNumMeshes = static_cast<unsigned int>(mesh_list.size());
		pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
		for(size_t i = 0; i < pScene->mNumMeshes; i++) pScene->mMeshes[i] = *ml_it++;
	}// if(mesh_list.size() > 0)

	//
	// Textures
	pScene->mNumTextures = static_cast<unsigned int>(mTexture_Converted.size());
	if(pScene->mNumTextures > 0)
	{
		size_t idx;

		idx = 0;
		pScene->mTextures = new aiTexture*[pScene->mNumTextures];
		for(const SPP_Texture& tex_convd: mTexture_Converted)
		{
			pScene->mTextures[idx] = new aiTexture;
			pScene->mTextures[idx]->mWidth = static_cast<unsigned int>(tex_convd.Width);
			pScene->mTextures[idx]->mHeight = static_cast<unsigned int>(tex_convd.Height);
			pScene->mTextures[idx]->pcData = (aiTexel*)tex_convd.Data;
			// texture format description.
			strcpy(pScene->mTextures[idx]->achFormatHint, tex_convd.FormatHint);
			idx++;
		}// for(const SPP_Texture& tex_convd: mTexture_Converted)

		// Create materials for embedded textures.
		idx = 0;
		pScene->mNumMaterials = static_cast<unsigned int>(mTexture_Converted.size());
		pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
		for(const SPP_Texture& tex_convd: mTexture_Converted)
		{
			const aiString texture_id(AI_EMBEDDED_TEXNAME_PREFIX + to_string(idx));
			const int mode = aiTextureOp_Multiply;
			const int repeat = tex_convd.Tiled ? 1 : 0;

			pScene->mMaterials[idx] = new aiMaterial;
			pScene->mMaterials[idx]->AddProperty(&texture_id, AI_MATKEY_TEXTURE_DIFFUSE(0));
			pScene->mMaterials[idx]->AddProperty(&mode, 1, AI_MATKEY_TEXOP_DIFFUSE(0));
			pScene->mMaterials[idx]->AddProperty(&repeat, 1, AI_MATKEY_MAPPINGMODE_U_DIFFUSE(0));
			pScene->mMaterials[idx]->AddProperty(&repeat, 1, AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0));
			idx++;
		}
	}// if(pScene->mNumTextures > 0)
}// END: after that walk through children of root and collect data

}// namespace Assimp

#endif // !ASSIMP_BUILD_NO_AMF_IMPORTER
