#include "generatefilethread.h"

// vtk头文件
#include <vtkCellData.h>
#include <vtkDataSetAttributes.h>
#include <vtkDoubleArray.h>
#include <vtkIdList.h>
#include <vtkIntArray.h>
#include <vtkMath.h>
#include <vtkNew.h>
#include <vtkPointData.h>
#include <vtkPoints.h>
#include <vtkSmartPointer.h>
#include <vtkStructuredGrid.h>
#include <vtkStructuredGridAppend.h>
#include <vtkDataSetWriter.h>
#include <vtkUnstructuredGrid.h>

#include <random>

#include "cellshapestruct.h"

const int pointNumOfPolyVertex = 5;
const int pointNumOfPolyLine = 5;

GenerateFileThread::GenerateFileThread(QObject *parent)
    : QThread(parent)
{
	initParam();
}

GenerateFileThread::~GenerateFileThread()
{

}

void GenerateFileThread::setConfigParam(ConfigParam p)
{
    mConfigParam = p;
}

int GenerateFileThread::getCellNum()
{
    return mCellTotalNum;
}

void GenerateFileThread::run()
{   
    Q_EMIT progressTip(1, 3, "正在生成数据");
	initParam();

    QStringList strList = mConfigParam.cellIndexs.split(" ");
    QList<int> intList;
    for(auto i : strList)
    {
        intList.append(i.toInt());
    }

    vtkSmartPointer<vtkUnstructuredGrid> dataset = vtkSmartPointer<vtkUnstructuredGrid>::New();
    vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
    vtkNew<vtkDoubleArray> pointArray;
    const char* pointArrayName = "mypoint";
    pointArray->SetName(pointArrayName);
    dataset->GetPointData()->AddArray(pointArray);
    dataset->SetPoints(points);
    double xspan = 5.0;
    double yspan = 6.0;
    double zspan = 7.0;

    for(auto i : intList)
    {
        if(i == 0)
        {
            generatePoint(points, pointArray, xspan, yspan, zspan);
        }
        else if (i == 1)
		{
			generateVertexCoor(points, pointArray, xspan, yspan, zspan);
		}
		else if (i == 2)
		{
			generatePolyVertexCoor(points, pointArray, xspan, yspan, zspan);
		}
		else if (i == 3)
		{
			generateLineCoor(points, pointArray, xspan, yspan, zspan);
		}
		else if (i == 4)
		{
			generatePolyLineCoor(points, pointArray, xspan, yspan, zspan);
		}
		else if(i == 5)
        {
            generateTriangleCoor(points, pointArray, xspan, yspan, zspan);
        }
        else if(i == 9)
        {
            generateQuadCoor(points, pointArray, xspan, yspan, zspan);
        }
        else if(i == 10)
        {
            generateTetraCoor(points, pointArray, xspan, yspan, zspan);
        }
		else if (i == 12)
		{
            generateHexahedronCoor(points, pointArray, xspan, yspan, zspan);
		}
		else if (i == 13)
		{
			generateWedgeCoor(points, pointArray, xspan, yspan, zspan);
		}
		else if (i == 14)
		{
			generatePyramidCoor(points, pointArray, xspan, yspan, zspan);
		}
		else if (i == 15)
		{
			generatePentagonalPrismCoor(points, pointArray, xspan, yspan, zspan);
		}
		else if (i == 16)
		{
			generateHexagonalPrismCoor(points, pointArray, xspan, yspan, zspan);
		}
    }

    vtkNew<vtkDoubleArray> cellValueArray;
    vtkNew<vtkCellArray> cellArray;
    vtkNew<vtkUnsignedCharArray> cellTypes;
    std::string cellArrayName = "Unknow";

    cellArrayName = "mycell";
    cellValueArray->SetNumberOfComponents(mConfigParam.weiDu);
    cellValueArray->SetName(cellArrayName.c_str());

    cellTypes->SetNumberOfValues(mCellTotalNum);

    dataset->SetCells(cellTypes, cellArray);
    dataset->GetCellData()->AddArray(cellValueArray);



    for(auto i : intList)
    {
        if(i == 0)
        {
            break;
        }
        else if (i == 1)
        {
            generateVertexCell(cellValueArray, cellArray, cellTypes);
        }
        else if (i == 2)
        {
            generatePolyVertexCell(cellValueArray, cellArray, cellTypes);
        }
        else if (i == 3)
        {
            generateLineCell(cellValueArray, cellArray, cellTypes);
        }
        else if (i == 4)
        {
            generatePolyLineCell(cellValueArray, cellArray, cellTypes);
        }
        else if(i == 5)
        {
            generateTriangleCell(cellValueArray, cellArray, cellTypes);
        }
        else if(i == 9)
        {
            generateQuadCell(cellValueArray, cellArray, cellTypes);
        }
        else if(i == 10)
        {
            generateTetraCell(cellValueArray, cellArray, cellTypes);
        }
        else if (i == 12)
        {
            generateHexahedronCell(cellValueArray, cellArray, cellTypes);
        }
        else if (i == 13)
        {
            generateWedgeCell(cellValueArray, cellArray, cellTypes);
        }
        else if (i == 14)
        {
            generatePyramidCell(cellValueArray, cellArray, cellTypes);
        }
        else if (i == 15)
        {
            generatePentagonalPrismCell(cellValueArray, cellArray, cellTypes);
        }
        else if (i == 16)
        {
            generateHexagonalPrismCell(cellValueArray, cellArray, cellTypes);
        }
    }


    Q_EMIT progressTip(2, 3, "正在写入文件");

    vtkSmartPointer<vtkDataSetWriter> writer = vtkSmartPointer<vtkDataSetWriter>::New();

    //writer->SetFileType(VTK_ASCII);
    //writer->SetFileTypeToASCII();
    // writer->SetFileType(VTK_BINARY);
    writer->SetFileTypeToBinary();


    writer->SetInputData(dataset);
    writer->SetFileName(mConfigParam.outputFile.toStdString().c_str());
    writer->Write();

    Q_EMIT progressTip(3, 3, "VTK文件生成完成");
}

void GenerateFileThread::initParam()
{
	mCellTotalNum = 0;

	mTempX = 0;
	mTempY = 0;
	mTempZ = 0;

	mNumOfPerCell.clear();

}

void GenerateFileThread::generatePoint(vtkPoints* points, vtkDoubleArray* pointArray, double xspan, double yspan, double zspan)
{
    // 点数据
    //vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
    //vtkNew<vtkDoubleArray> pointArray;
    //const char* pointArrayName = "point1";
    //pointArray->SetName(pointArrayName);
    //dataset->GetPointData()->AddArray(pointArray);

    int _idx = 0;
    for(int i = 0; i < mConfigParam.xLength; i = i + xspan)
    {
        for(int j = 0; j < mConfigParam.yLength; j = j + yspan)
        {
            for(int k = 0; k < mConfigParam.zLength; k = k + zspan)
            {
                points->InsertNextPoint((double)i, (double)j, (double)k);
                pointArray->InsertNextValue((double)_idx);

                _idx++;
            }
        }
    }

    //dataset->SetPoints(points);
}

void GenerateFileThread::generateVertexCoor(vtkPoints* points, vtkDoubleArray* pointArray, double xspan, double yspan, double zspan)
{
	int _tempX = 0;
	int _tempY = 0;
	int _tempZ = 0;
	int _cellNum = 0;
	for (int x = mTempX; x < mConfigParam.xLength + mTempX; x += xspan)
	{
		_tempX = x;
		if (_cellNum > mConfigParam.cellNum)
			break;
		for (int y = mTempY; y < mConfigParam.yLength + mTempY; y += yspan)
		{
			_tempY = y;
			if (_cellNum > mConfigParam.cellNum)
				break;
			for (int z = mTempZ; z < mConfigParam.zLength + mTempZ; z += zspan)
			{
				_tempZ = z;
				if (_cellNum > mConfigParam.cellNum)
					break;

				CellVertex _cell;
				_cell.setCoordinate(x, y, z);

				std::vector<std::array<double, 3>> p = _cell.p;
				for (int i = 0; i < p.size(); i++)
				{
					points->InsertNextPoint((double)p[i][0], (double)p[i][1], (double)p[i][2]);
					pointArray->InsertNextValue((double)_cellNum);
				}

				_cellNum++;
			}
		}
	}

	mCellTotalNum += _cellNum;
	mTempX = _tempX;
	mTempY = _tempY;
	mTempZ = _tempZ;

	mNumOfPerCell[1] = { mCellTotalNum - _cellNum, mCellTotalNum, 1 };
}

void GenerateFileThread::generateVertexCell(vtkDoubleArray* cellValueArray, vtkCellArray* cellArray, vtkUnsignedCharArray* cellTypes)
{
	bool isExist = false;
	QMap<int, std::array<int, 3>>::iterator it1 = mNumOfPerCell.begin();
	while (it1 != mNumOfPerCell.end())
	{
		if (it1.key() == 1)
		{
			isExist = true;
			break;
		}
		it1++;
	}

	if (!isExist)
		return;

	QMap<int, std::array<int, 3>>::iterator it2 = mNumOfPerCell.begin();

	int pointNum = 0;
	while (it2 != it1)
	{
		pointNum += (it2.value()[1] - it2.value()[0]) * it2.value()[2];
		it2++;
	}

	for (int _idx = mNumOfPerCell[1][0]; _idx < mNumOfPerCell[1][1]; _idx++)
	{
		int _id = pointNum + (_idx - mNumOfPerCell[1][0]) * 1;
		long long cellId[1] = { _id };


        for(int _i = 0; _i < mConfigParam.weiDu; _i++)
        {
            cellValueArray->InsertNextValue((double)_idx + 1);
        }

		cellArray->InsertNextCell(1, cellId);
		cellTypes->SetValue(_idx, VTK_VERTEX);
	}
}

void GenerateFileThread::generatePolyVertexCoor(vtkPoints* points, vtkDoubleArray* pointArray, double xspan, double yspan, double zspan)
{
	int _tempX = 0;
	int _tempY = 0;
	int _tempZ = 0;
	int _cellNum = 0;
	
	for (int x = mTempX; x < mConfigParam.xLength + mTempX; x += xspan)
	{
		_tempX = x;
		if (_cellNum > mConfigParam.cellNum)
			break;
		for (int y = mTempY; y < mConfigParam.yLength + mTempY; y += yspan)
		{
			_tempY = y;
			if (_cellNum > mConfigParam.cellNum)
				break;
			for (int z = mTempZ; z < mConfigParam.zLength + mTempZ; z += zspan)
			{
				_tempZ = z;
				if (_cellNum > mConfigParam.cellNum)
					break;

				CellPolyVertex _cell(3.0, 4.0, 5.0, pointNumOfPolyVertex);
				_cell.setCoordinate(x, y, z);

				std::vector<std::array<double, 3>> p = _cell.p;
				for (int i = 0; i < p.size(); i++)
				{
					points->InsertNextPoint((double)p[i][0], (double)p[i][1], (double)p[i][2]);
					pointArray->InsertNextValue((double)_cellNum);
				}

				_cellNum++;
			}
		}
	}

	mCellTotalNum += _cellNum;
	mTempX = _tempX;
	mTempY = _tempY;
	mTempZ = _tempZ;

	mNumOfPerCell[2] = { mCellTotalNum - _cellNum, mCellTotalNum, pointNumOfPolyVertex };
}

void GenerateFileThread::generatePolyVertexCell(vtkDoubleArray* cellValueArray, vtkCellArray* cellArray, vtkUnsignedCharArray* cellTypes)
{
	bool isExist = false;
	QMap<int, std::array<int, 3>>::iterator it1 = mNumOfPerCell.begin();
	while (it1 != mNumOfPerCell.end())
	{
		if (it1.key() == 2)
		{
			isExist = true;
			break;
		}
		it1++;
	}

	if (!isExist)
		return;

	QMap<int, std::array<int, 3>>::iterator it2 = mNumOfPerCell.begin();

	int pointNum = 0;
	while (it2 != it1)
	{
		pointNum += (it2.value()[1] - it2.value()[0]) * it2.value()[2];
		it2++;
	}

	for (int _idx = mNumOfPerCell[2][0]; _idx < mNumOfPerCell[2][1]; _idx++)
	{
		int _id = pointNum + (_idx - mNumOfPerCell[2][0]) * pointNumOfPolyVertex;
		long long cellId[pointNumOfPolyVertex];
		for (int i = 0; i < pointNumOfPolyVertex; i++)
		{
			cellId[i] = _id + i;
		}


        for(int _i = 0; _i < mConfigParam.weiDu; _i++)
        {
            cellValueArray->InsertNextValue((double)_idx);
        }

		cellArray->InsertNextCell(pointNumOfPolyVertex, cellId);
        cellTypes->SetValue(_idx, VTK_POLY_VERTEX);
	}
}

void GenerateFileThread::generateLineCoor(vtkPoints* points, vtkDoubleArray* pointArray, double xspan, double yspan, double zspan)
{
	int _tempX = 0;
	int _tempY = 0;
	int _tempZ = 0;
	int _cellNum = 0;

	for (int x = mTempX; x < mConfigParam.xLength + mTempX; x += xspan)
	{
		_tempX = x;
		if (_cellNum > mConfigParam.cellNum)
			break;
		for (int y = mTempY; y < mConfigParam.yLength + mTempY; y += yspan)
		{
			_tempY = y;
			if (_cellNum > mConfigParam.cellNum)
				break;
			for (int z = mTempZ; z < mConfigParam.zLength + mTempZ; z += zspan)
			{
				_tempZ = z;
				if (_cellNum > mConfigParam.cellNum)
					break;

				CellLine _cell(3.0, 4.0, 5.0);
				_cell.setCoordinate(x, y, z);
				std::vector<std::array<double, 3>> p = _cell.p;
				for (int i = 0; i < p.size(); i++)
				{
					points->InsertNextPoint((double)p[i][0], (double)p[i][1], (double)p[i][2]);
					pointArray->InsertNextValue((double)_cellNum);
				}

				_cellNum++;
			}
		}
	}

	mCellTotalNum += _cellNum;
	mTempX = _tempX;
	mTempY = _tempY;
	mTempZ = _tempZ;

	mNumOfPerCell[3] = { mCellTotalNum - _cellNum, mCellTotalNum, 2 };
}

void GenerateFileThread::generateLineCell(vtkDoubleArray* cellValueArray, vtkCellArray* cellArray, vtkUnsignedCharArray* cellTypes)
{
	bool isExist = false;
	QMap<int, std::array<int, 3>>::iterator it1 = mNumOfPerCell.begin();
	while (it1 != mNumOfPerCell.end())
	{
		if (it1.key() == 3)
		{
			isExist = true;
			break;
		}
		it1++;
	}

	if (!isExist)
		return;

	QMap<int, std::array<int, 3>>::iterator it2 = mNumOfPerCell.begin();

	int pointNum = 0;
	while (it2 != it1)
	{
		pointNum += (it2.value()[1] - it2.value()[0]) * it2.value()[2];
		it2++;
	}

	for (int _idx = mNumOfPerCell[3][0]; _idx < mNumOfPerCell[3][1]; _idx++)
	{
		int _id = pointNum + (_idx - mNumOfPerCell[3][0]) * 2;
		long long cellId[pointNumOfPolyVertex];
		for (int i = 0; i < pointNumOfPolyVertex; i++)
		{
			cellId[i] = _id + i;
		}

        for(int _i = 0; _i < mConfigParam.weiDu; _i++)
        {
            cellValueArray->InsertNextValue((double)_idx);
        }

		cellArray->InsertNextCell(pointNumOfPolyVertex, cellId);
		cellTypes->SetValue(_idx, VTK_LINE);
	}
}


void GenerateFileThread::generatePolyLineCoor(vtkPoints* points, vtkDoubleArray* pointArray, double xspan, double yspan, double zspan)
{
	int _tempX = 0;
	int _tempY = 0;
	int _tempZ = 0;
	int _cellNum = 0;

	for (int x = mTempX; x < mConfigParam.xLength + mTempX; x += xspan)
	{
		_tempX = x;
		if (_cellNum > mConfigParam.cellNum)
			break;
		for (int y = mTempY; y < mConfigParam.yLength + mTempY; y += yspan)
		{
			_tempY = y;
			if (_cellNum > mConfigParam.cellNum)
				break;
			for (int z = mTempZ; z < mConfigParam.zLength + mTempZ; z += zspan)
			{
				_tempZ = z;
				if (_cellNum > mConfigParam.cellNum)
					break;

				CellPolyLine _cell(3.0, 4.0, 5.0, pointNumOfPolyLine);
				_cell.setCoordinate(x, y, z);
				std::vector<std::array<double, 3>> p = _cell.p;
				for (int i = 0; i < p.size(); i++)
				{
					points->InsertNextPoint((double)p[i][0], (double)p[i][1], (double)p[i][2]);
					pointArray->InsertNextValue((double)_cellNum);
				}

				_cellNum++;
			}
		}
	}

	mCellTotalNum += _cellNum;
	mTempX = _tempX;
	mTempY = _tempY;
	mTempZ = _tempZ;

	mNumOfPerCell[4] = { mCellTotalNum - _cellNum, mCellTotalNum, pointNumOfPolyLine };
}

void GenerateFileThread::generatePolyLineCell(vtkDoubleArray* cellValueArray, vtkCellArray* cellArray, vtkUnsignedCharArray* cellTypes)
{
	bool isExist = false;
	QMap<int, std::array<int, 3>>::iterator it1 = mNumOfPerCell.begin();
	while (it1 != mNumOfPerCell.end())
	{
		if (it1.key() == 4)
		{
			isExist = true;
			break;
		}
		it1++;
	}

	if (!isExist)
		return;

	QMap<int, std::array<int, 3>>::iterator it2 = mNumOfPerCell.begin();

	int pointNum = 0;
	while (it2 != it1)
	{
		pointNum += (it2.value()[1] - it2.value()[0]) * it2.value()[2];
		it2++;
	}

	for (int _idx = mNumOfPerCell[4][0]; _idx < mNumOfPerCell[4][1]; _idx++)
	{
		int _id = pointNum + (_idx - mNumOfPerCell[4][0]) * pointNumOfPolyLine;
		long long cellId[pointNumOfPolyLine];
		for (int i = 0; i < pointNumOfPolyLine; i++)
		{
			cellId[i] = _id + i;
		}


        for(int _i = 0; _i < mConfigParam.weiDu; _i++)
        {
            cellValueArray->InsertNextValue((double)_idx);
        }

		cellArray->InsertNextCell(pointNumOfPolyLine, cellId);
		cellTypes->SetValue(_idx, VTK_POLY_LINE);
	}
}


void GenerateFileThread::generateTriangleCoor(vtkPoints* points, vtkDoubleArray* pointArray, double xspan, double yspan, double zspan)
{
    int _tempX = 0;
    int _tempY = 0;
    int _tempZ = 0;
    int _cellNum = 0;
    for(int x = mTempX; x < mConfigParam.xLength + mTempX; x += xspan)
    {
        _tempX = x;
        if(_cellNum > mConfigParam.cellNum)
            break;
        for(int y = mTempY; y < mConfigParam.yLength + mTempY; y += yspan)
        {
            _tempY = y;
            if(_cellNum > mConfigParam.cellNum)
                break;
            for(int z = mTempZ; z < mConfigParam.zLength + mTempZ; z += zspan)
            {
                _tempZ = z;
                if(_cellNum > mConfigParam.cellNum)
                    break;

                CellTriangle _cell;
                _cell.setCoordinate(x, y, z);

                std::vector<std::array<double, 3>> p = _cell.p;
                for(int i = 0; i < p.size(); i++)
                {
                    points->InsertNextPoint((double)p[i][0], (double)p[i][1], (double)p[i][2]);
                    pointArray->InsertNextValue((double)_cellNum);
                }

                _cellNum++;
            }
        }
    }

    mCellTotalNum += _cellNum;
    mTempX = _tempX;
    mTempY = _tempY;
    mTempZ = _tempZ;

    mNumOfPerCell[5] = {mCellTotalNum - _cellNum, mCellTotalNum, 3};
}

void GenerateFileThread::generateTriangleCell(vtkDoubleArray* cellValueArray, vtkCellArray* cellArray, vtkUnsignedCharArray* cellTypes)
{
    bool isExist = false;
    QMap<int, std::array<int, 3>>::iterator it1 = mNumOfPerCell.begin();
	while (it1 != mNumOfPerCell.end())
	{
		if (it1.key() == 5)
		{	
            isExist = true;
			break;
		}
        it1++;
	}

    if (!isExist)
        return;

    QMap<int, std::array<int, 3>>::iterator it2 = mNumOfPerCell.begin();

    int pointNum = 0;
    while (it2 != it1)
    {
        pointNum += (it2.value()[1] - it2.value()[0]) * it2.value()[2];
        it2++;
    }

	for (int _idx = mNumOfPerCell[5][0]; _idx < mNumOfPerCell[5][1]; _idx++)
	{
		int _id = pointNum + (_idx - mNumOfPerCell[5][0]) * 3;
		long long cellId[3] = { _id, _id + 1, _id + 2 };

        for(int _i = 0; _i < mConfigParam.weiDu; _i++)
        {
            cellValueArray->InsertNextValue((double)_idx);
        }

		cellArray->InsertNextCell(3, cellId);
		cellTypes->SetValue(_idx, VTK_TRIANGLE);
	}
}

void GenerateFileThread::generateQuadCoor(vtkPoints *points, vtkDoubleArray *pointArray, double xspan, double yspan, double zspan)
{
    int _tempX = 0;
    int _tempY = 0;
    int _tempZ = 0;
    int _cellNum = 0;
    for(int x = mTempX; x < mConfigParam.xLength + mTempX; x += xspan)
    {
        _tempX = x;
        if(_cellNum > mConfigParam.cellNum)
            break;
        for(int y = mTempY; y < mConfigParam.yLength + mTempY; y += yspan)
        {
            _tempY = y;
            if(_cellNum > mConfigParam.cellNum)
                break;
            for(int z = mTempZ; z < mConfigParam.zLength + mTempZ; z += zspan)
            {
                _tempZ = z;
                if(_cellNum > mConfigParam.cellNum)
                    break;

                CellQuad _cell;
                _cell.setCoordinate(x, y, z);

                std::vector<std::array<double, 3>> p = _cell.p;
                for(int i = 0; i < p.size(); i++)
                {
                    points->InsertNextPoint((double)p[i][0], (double)p[i][1], (double)p[i][2]);
                    pointArray->InsertNextValue((double)_cellNum);
                }

                _cellNum++;
            }
        }
    }

    mCellTotalNum += _cellNum;
    mTempX = _tempX;
    mTempY = _tempY;
    mTempZ = _tempZ;

    mNumOfPerCell[9] = {mCellTotalNum - _cellNum, mCellTotalNum, 4};
}

void GenerateFileThread::generateQuadCell(vtkDoubleArray *cellValueArray, vtkCellArray *cellArray, vtkUnsignedCharArray *cellTypes)
{
	bool isExist = false;
	QMap<int, std::array<int, 3>>::iterator it1 = mNumOfPerCell.begin();
	while (it1 != mNumOfPerCell.end())
	{
		if (it1.key() == 9)
		{
			isExist = true;
			break;
		}
		it1++;
	}

	if (!isExist)
		return;

	QMap<int, std::array<int, 3>>::iterator it2 = mNumOfPerCell.begin();

	int pointNum = 0;
	while (it2 != it1)
	{
		pointNum += (it2.value()[1] - it2.value()[0]) * it2.value()[2];
		it2++;
	}

	for (int _idx = mNumOfPerCell[9][0]; _idx < mNumOfPerCell[9][1]; _idx++)
	{
		int _id = pointNum + (_idx - mNumOfPerCell[9][0]) * 4;
		long long cellId[4] = { _id, _id + 1, _id + 2, _id + 3 };

        for(int _i = 0; _i < mConfigParam.weiDu; _i++)
        {
            cellValueArray->InsertNextValue((double)_idx);
        }

		cellArray->InsertNextCell(4, cellId);
		cellTypes->SetValue(_idx, VTK_QUAD);
	}
}

void GenerateFileThread::generateTetraCoor(vtkPoints *points, vtkDoubleArray *pointArray, double xspan, double yspan, double zspan)
{
    int _tempX = 0;
    int _tempY = 0;
    int _tempZ = 0;
    int _cellNum = 0;
    for(int x = mTempX; x < mConfigParam.xLength + mTempX; x += xspan)
    {
        _tempX = x;
        if(_cellNum > mConfigParam.cellNum)
            break;
        for(int y = mTempY; y < mConfigParam.yLength + mTempY; y += yspan)
        {
            _tempY = y;
            if(_cellNum > mConfigParam.cellNum)
                break;
            for(int z = mTempZ; z < mConfigParam.zLength + mTempZ; z += zspan)
            {
                _tempZ = z;
                if(_cellNum > mConfigParam.cellNum)
                    break;

                CellTetra _cell;
                _cell.setCoordinate(x, y, z);

                std::vector<std::array<double, 3>> p = _cell.p;
                for(int i = 0; i < p.size(); i++)
                {
                    points->InsertNextPoint((double)p[i][0], (double)p[i][1], (double)p[i][2]);
                    pointArray->InsertNextValue((double)_cellNum);
                }

                _cellNum++;
            }
        }
    }

    mCellTotalNum += _cellNum;
    mTempX = _tempX;
    mTempY = _tempY;
    mTempZ = _tempZ;

    mNumOfPerCell[10] = {mCellTotalNum - _cellNum, mCellTotalNum, 4};
}

void GenerateFileThread::generateTetraCell(vtkDoubleArray *cellValueArray, vtkCellArray *cellArray, vtkUnsignedCharArray *cellTypes)
{
	bool isExist = false;
	QMap<int, std::array<int, 3>>::iterator it1 = mNumOfPerCell.begin();
	while (it1 != mNumOfPerCell.end())
	{
		if (it1.key() == 10)
		{
			isExist = true;
			break;
		}
		it1++;
	}

	if (!isExist)
		return;

	QMap<int, std::array<int, 3>>::iterator it2 = mNumOfPerCell.begin();

	int pointNum = 0;
	while (it2 != it1)
	{
		pointNum += (it2.value()[1] - it2.value()[0]) * it2.value()[2];
		it2++;
	}

    for(int _idx = mNumOfPerCell[10][0]; _idx < mNumOfPerCell[10][1]; _idx++)
    {
        int _id = pointNum + (_idx - mNumOfPerCell[10][0]) * 4;
        long long cellId[4] = {_id, _id + 1, _id + 2, _id + 3};

        for(int _i = 0; _i < mConfigParam.weiDu; _i++)
        {
            cellValueArray->InsertNextValue((double)_idx);
        }

        cellArray->InsertNextCell(4, cellId);
        cellTypes->SetValue(_idx, VTK_TETRA);
    }
}

void GenerateFileThread::generateHexahedronCoor(vtkPoints* points, vtkDoubleArray* pointArray, double xspan, double yspan, double zspan)
{
	int _tempX = 0;
	int _tempY = 0;
	int _tempZ = 0;
	int _cellNum = 0;

	for (int x = mTempX; x < mConfigParam.xLength + mTempX; x += xspan)
	{
		_tempX = x;
		if (_cellNum > mConfigParam.cellNum)
			break;
		for (int y = mTempY; y < mConfigParam.yLength + mTempY; y += yspan)
		{
			_tempY = y;
			if (_cellNum > mConfigParam.cellNum)
				break;
			for (int z = mTempZ; z < mConfigParam.zLength + mTempZ; z += zspan)
			{
				_tempZ = z;
				if (_cellNum > mConfigParam.cellNum)
					break;

				CellHexahedron _cell(4.0, 5.0, 6.0);
				_cell.setCoordinate(x, y, z);

				std::vector<std::array<double, 3>> p = _cell.p;
				for (int i = 0; i < p.size(); i++)
				{
					points->InsertNextPoint((double)p[i][0], (double)p[i][1], (double)p[i][2]);
					pointArray->InsertNextValue((double)_cellNum);
				}

				_cellNum++;
			}
		}
	}

	mCellTotalNum += _cellNum;
	mTempX = _tempX;
	mTempY = _tempY;
	mTempZ = _tempZ;

	mNumOfPerCell[12] = { mCellTotalNum - _cellNum, mCellTotalNum, 8 };
}

void GenerateFileThread::generateHexahedronCell(vtkDoubleArray* cellValueArray, vtkCellArray* cellArray, vtkUnsignedCharArray* cellTypes)
{
	bool isExist = false;
	QMap<int, std::array<int, 3>>::iterator it1 = mNumOfPerCell.begin();
	while (it1 != mNumOfPerCell.end())
	{
		if (it1.key() == 12)
		{
			isExist = true;
			break;
		}
		it1++;
	}

	if (!isExist)
		return;

	QMap<int, std::array<int, 3>>::iterator it2 = mNumOfPerCell.begin();

	int pointNum = 0;
	while (it2 != it1)
	{
		pointNum += (it2.value()[1] - it2.value()[0]) * it2.value()[2];
		it2++;
	}

	for (int _idx = mNumOfPerCell[12][0]; _idx < mNumOfPerCell[12][1]; _idx++)
	{


		int _id = pointNum + (_idx - mNumOfPerCell[12][0]) * 8;
		long long cellId[8] = { _id, _id + 1, _id + 2, _id + 3, _id + 4, _id + 5, _id + 6, _id + 7 };

        if(_idx < mNumOfPerCell[12][1] / 3)
        {
            for(int _i = 0; _i < mConfigParam.weiDu; _i++)
            {
                cellValueArray->InsertNextValue((double)_idx);
            }

        }
        else if(_idx < mNumOfPerCell[12][1] / 2)
        {
            // std::random_device rd;  // 随机数引擎的种子源
            // std::mt19937 gen(rd()); // 以 rd() 播种的 mersenne_twister_engine
            // std::uniform_int_distribution<> distrib(10, 50);

            for(int _i = 0; _i < mConfigParam.weiDu; _i++)
            {
                cellValueArray->InsertNextValue((double)(_idx + 500));
            }
        }
        else
        {
            // std::random_device rd;  // 随机数引擎的种子源
            // std::mt19937 gen(rd()); // 以 rd() 播种的 mersenne_twister_engine
            // std::uniform_int_distribution<> distrib(50, 100);

            for(int _i = 0; _i < mConfigParam.weiDu; _i++)
            {
                cellValueArray->InsertNextValue((double)(_idx + 100));
            }
        }



		cellArray->InsertNextCell(8, cellId);
		cellTypes->SetValue(_idx, VTK_HEXAHEDRON);
	}
}

void GenerateFileThread::generateWedgeCoor(vtkPoints* points, vtkDoubleArray* pointArray, double xspan, double yspan, double zspan)
{
	int _tempX = 0;
	int _tempY = 0;
	int _tempZ = 0;
	int _cellNum = 0;
	for (int x = mTempX; x < mConfigParam.xLength + mTempX; x += xspan)
	{
		_tempX = x;
		if (_cellNum > mConfigParam.cellNum)
			break;
		for (int y = mTempY; y < mConfigParam.yLength + mTempY; y += yspan)
		{
			_tempY = y;
			if (_cellNum > mConfigParam.cellNum)
				break;
			for (int z = mTempZ; z < mConfigParam.zLength + mTempZ; z += zspan)
			{
				_tempZ = z;
				if (_cellNum > mConfigParam.cellNum)
					break;

				CellWedge _cell(4.0, 5.0, 6.0);
				_cell.setCoordinate(x, y, z);
				std::vector<std::array<double, 3>> p = _cell.p;
				for (int i = 0; i < p.size(); i++)
				{
					points->InsertNextPoint((double)p[i][0], (double)p[i][1], (double)p[i][2]);
					pointArray->InsertNextValue((double)_cellNum);
				}

				_cellNum++;
			}
		}
	}

	mCellTotalNum += _cellNum;
	mTempX = _tempX;
	mTempY = _tempY;
	mTempZ = _tempZ;

	mNumOfPerCell[13] = { mCellTotalNum - _cellNum, mCellTotalNum, 6 };
}

void GenerateFileThread::generateWedgeCell(vtkDoubleArray* cellValueArray, vtkCellArray* cellArray, vtkUnsignedCharArray* cellTypes)
{
	bool isExist = false;
	QMap<int, std::array<int, 3>>::iterator it1 = mNumOfPerCell.begin();
	while (it1 != mNumOfPerCell.end())
	{
		if (it1.key() == 13)
		{
			isExist = true;
			break;
		}
		it1++;
	}

	if (!isExist)
		return;

	QMap<int, std::array<int, 3>>::iterator it2 = mNumOfPerCell.begin();

	int pointNum = 0;
	while (it2 != it1)
	{
		pointNum += (it2.value()[1] - it2.value()[0]) * it2.value()[2];
		it2++;
	}

	for (int _idx = mNumOfPerCell[13][0]; _idx < mNumOfPerCell[13][1]; _idx++)
	{
		int _id = pointNum + (_idx - mNumOfPerCell[13][0]) * 6;
		long long cellId[6] = { _id, _id + 1, _id + 2, _id + 3, _id + 4, _id + 5 };

        for(int _i = 0; _i < mConfigParam.weiDu; _i++)
        {
            cellValueArray->InsertNextValue((double)_idx);
        }


		cellArray->InsertNextCell(6, cellId);
		cellTypes->SetValue(_idx, VTK_WEDGE);
	}

}

void GenerateFileThread::generatePyramidCoor(vtkPoints* points, vtkDoubleArray* pointArray, double xspan, double yspan, double zspan)
{
	int _tempX = 0;
	int _tempY = 0;
	int _tempZ = 0;
	int _cellNum = 0;
	for (int x = mTempX; x < mConfigParam.xLength + mTempX; x += xspan)
	{
		_tempX = x;
		if (_cellNum > mConfigParam.cellNum)
			break;
		for (int y = mTempY; y < mConfigParam.yLength + mTempY; y += yspan)
		{
			_tempY = y;
			if (_cellNum > mConfigParam.cellNum)
				break;
			for (int z = mTempZ; z < mConfigParam.zLength + mTempZ; z += zspan)
			{
				_tempZ = z;
				if (_cellNum > mConfigParam.cellNum)
					break;

				CellPyramid _cell(4.0, 5.0, 6.0);
				_cell.setCoordinate(x, y, z);
				std::vector<std::array<double, 3>> p = _cell.p;
				for (int i = 0; i < p.size(); i++)
				{
					points->InsertNextPoint((double)p[i][0], (double)p[i][1], (double)p[i][2]);
					pointArray->InsertNextValue((double)_cellNum);
				}

				_cellNum++;
			}
		}
	}

	mCellTotalNum += _cellNum;
	mTempX = _tempX;
	mTempY = _tempY;
	mTempZ = _tempZ;

	mNumOfPerCell[14] = { mCellTotalNum - _cellNum, mCellTotalNum, 5 };
}

void GenerateFileThread::generatePyramidCell(vtkDoubleArray* cellValueArray, vtkCellArray* cellArray, vtkUnsignedCharArray* cellTypes)
{
	bool isExist = false;
	QMap<int, std::array<int, 3>>::iterator it1 = mNumOfPerCell.begin();
	while (it1 != mNumOfPerCell.end())
	{
		if (it1.key() == 14)
		{
			isExist = true;
			break;
		}
		it1++;
	}

	if (!isExist)
		return;

	QMap<int, std::array<int, 3>>::iterator it2 = mNumOfPerCell.begin();

	int pointNum = 0;
	while (it2 != it1)
	{
		pointNum += (it2.value()[1] - it2.value()[0]) * it2.value()[2];
		it2++;
	}

	for (int _idx = mNumOfPerCell[14][0]; _idx < mNumOfPerCell[14][1]; _idx++)
	{
		int _id = pointNum + (_idx - mNumOfPerCell[14][0]) * 5;
		long long cellId[5] = { _id, _id + 1, _id + 2, _id + 3, _id + 4 };


        for(int _i = 0; _i < mConfigParam.weiDu; _i++)
        {
            cellValueArray->InsertNextValue((double)_idx);
        }

		cellArray->InsertNextCell(5, cellId);
		cellTypes->SetValue(_idx, VTK_PYRAMID);
	}

}

void GenerateFileThread::generatePentagonalPrismCoor(vtkPoints* points, vtkDoubleArray* pointArray, double xspan, double yspan, double zspan)
{
	int _tempX = 0;
	int _tempY = 0;
	int _tempZ = 0;
	int _cellNum = 0;
	for (int x = mTempX; x < mConfigParam.xLength + mTempX; x += xspan)
	{
		_tempX = x;
		if (_cellNum > mConfigParam.cellNum)
			break;
		for (int y = mTempY; y < mConfigParam.yLength + mTempY; y += yspan)
		{
			_tempY = y;
			if (_cellNum > mConfigParam.cellNum)
				break;
			for (int z = mTempZ; z < mConfigParam.zLength + mTempZ; z += zspan)
			{
				_tempZ = z;
				if (_cellNum > mConfigParam.cellNum)
					break;

				CellPentagonalPrism _cell(4.0, 5.0, 6.0);
				_cell.setCoordinate(x, y, z);
				std::vector<std::array<double, 3>> p = _cell.p;
				for (int i = 0; i < p.size(); i++)
				{
					points->InsertNextPoint((double)p[i][0], (double)p[i][1], (double)p[i][2]);
					pointArray->InsertNextValue((double)_cellNum);
				}

				_cellNum++;
			}
		}
	}

	mCellTotalNum += _cellNum;
	mTempX = _tempX;
	mTempY = _tempY;
	mTempZ = _tempZ;

	mNumOfPerCell[15] = { mCellTotalNum - _cellNum, mCellTotalNum, 10 };
}

void GenerateFileThread::generatePentagonalPrismCell(vtkDoubleArray* cellValueArray, vtkCellArray* cellArray, vtkUnsignedCharArray* cellTypes)
{
	bool isExist = false;
	QMap<int, std::array<int, 3>>::iterator it1 = mNumOfPerCell.begin();
	while (it1 != mNumOfPerCell.end())
	{
		if (it1.key() == 15)
		{
			isExist = true;
			break;
		}
		it1++;
	}

	if (!isExist)
		return;

	QMap<int, std::array<int, 3>>::iterator it2 = mNumOfPerCell.begin();

	int pointNum = 0;
	while (it2 != it1)
	{
		pointNum += (it2.value()[1] - it2.value()[0]) * it2.value()[2];
		it2++;
	}

	for (int _idx = mNumOfPerCell[15][0]; _idx < mNumOfPerCell[15][1]; _idx++)
	{	
		int _id = pointNum + (_idx - mNumOfPerCell[15][0]) * 10;
		long long cellId[10] = { _id, _id + 1, _id + 2, _id + 3, _id + 4, _id + 5, _id + 6, _id + 7, _id + 8, _id + 9 };

        for(int _i = 0; _i < mConfigParam.weiDu; _i++)
        {
            cellValueArray->InsertNextValue((double)_idx);
        }


		cellArray->InsertNextCell(10, cellId);
		cellTypes->SetValue(_idx, VTK_PENTAGONAL_PRISM);
	}

}

void GenerateFileThread::generateHexagonalPrismCoor(vtkPoints* points, vtkDoubleArray* pointArray, double xspan, double yspan, double zspan)
{
	int _tempX = 0;
	int _tempY = 0;
	int _tempZ = 0;
	int _cellNum = 0;
	for (int x = mTempX; x < mConfigParam.xLength + mTempX; x += xspan)
	{
		_tempX = x;
		if (_cellNum > mConfigParam.cellNum)
			break;
		for (int y = mTempY; y < mConfigParam.yLength + mTempY; y += yspan)
		{
			_tempY = y;
			if (_cellNum > mConfigParam.cellNum)
				break;
			for (int z = mTempZ; z < mConfigParam.zLength + mTempZ; z += zspan)
			{
				_tempZ = z;
				if (_cellNum > mConfigParam.cellNum)
					break;

				CellHexagonalPrism _cell(4.0, 5.0, 6.0);
				_cell.setCoordinate(x, y, z);
				std::vector<std::array<double, 3>> p = _cell.p;
				for (int i = 0; i < p.size(); i++)
				{
					points->InsertNextPoint((double)p[i][0], (double)p[i][1], (double)p[i][2]);
					pointArray->InsertNextValue((double)_cellNum);
				}
				_cellNum++;
			}
		}
	}

	mCellTotalNum += _cellNum;
	mTempX = _tempX;
	mTempY = _tempY;
	mTempZ = _tempZ;

	mNumOfPerCell[16] = { mCellTotalNum - _cellNum, mCellTotalNum, 12 };
}

void GenerateFileThread::generateHexagonalPrismCell(vtkDoubleArray* cellValueArray, vtkCellArray* cellArray, vtkUnsignedCharArray* cellTypes)
{
	bool isExist = false;
	QMap<int, std::array<int, 3>>::iterator it1 = mNumOfPerCell.begin();
	while (it1 != mNumOfPerCell.end())
	{
		if (it1.key() == 16)
		{
			isExist = true;
			break;
		}
		it1++;
	}

	if (!isExist)
		return;

	QMap<int, std::array<int, 3>>::iterator it2 = mNumOfPerCell.begin();

	int pointNum = 0;
	while (it2 != it1)
	{
		pointNum += (it2.value()[1] - it2.value()[0]) * it2.value()[2];
		it2++;
	}

	for (int _idx = mNumOfPerCell[16][0]; _idx < mNumOfPerCell[16][1]; _idx++)
	{
		int _id = pointNum + (_idx - mNumOfPerCell[16][0]) * 12;
		long long cellId[12] = { _id, _id + 1, _id + 2, _id + 3, _id + 4, _id + 5, _id + 6, _id + 7, _id + 8, _id + 9, _id + 10, _id + 11 };


        for(int _i = 0; _i < mConfigParam.weiDu; _i++)
        {
            cellValueArray->InsertNextValue((double)_idx);
        }

		cellArray->InsertNextCell(12, cellId);
		cellTypes->SetValue(_idx, VTK_HEXAGONAL_PRISM);
	}

}


// void GenerateFileThread::generateQuad(vtkUnstructuredGrid* dataset)
// {
//     vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
//     vtkNew<vtkDoubleArray> pointArray;
//     const char* pointArrayName = "point1";
//     pointArray->SetName(pointArrayName);
//     dataset->GetPointData()->AddArray(pointArray);

//     double xspan = 3.0;
//     double yspan = 4.0;
//     double zspan = 5.0;

//     mCellNum = 0;
//     for(int x = 0; x < mConfigParam.xLength; x += xspan)
//     {
//         if(mCellNum > mConfigParam.cellNum)
//             break;
//         for(int y = 0; y < mConfigParam.yLength; y += yspan)
//         {
//             if(mCellNum > mConfigParam.cellNum)
//                 break;
//             for(int z = 0; z < mConfigParam.zLength; z += zspan)
//             {
//                 if(mCellNum > mConfigParam.cellNum)
//                     break;

//                 CellQuad _cell;
//                 _cell.setCoordinate(x, y, z);

//                 std::vector<std::array<double, 3>> p = _cell.p;
//                 for(int i = 0; i < p.size(); i++)
//                 {
//                     points->InsertNextPoint((double)p[i][0], (double)p[i][1], (double)p[i][2]);
//                     pointArray->InsertNextValue((double)mCellNum);
//                 }


//                 mCellNum++;
//             }
//         }
//     }

//     dataset->SetPoints(points);


//     vtkNew<vtkDoubleArray> cellValueArray;
//     vtkNew<vtkCellArray> cellArray;
//     vtkNew<vtkUnsignedCharArray> cellTypes;
//     std::string cellArrayName = "Unknow";

//     cellValueArray->SetNumberOfComponents(1);
//     dataset->GetCellData()->AddArray(cellValueArray);

//     cellArrayName = "CellQuad";
//     cellTypes->SetNumberOfValues(mCellNum);

//     for(int _idx = 0; _idx < mCellNum; _idx++)
//     {
//         int _id = _idx * 4;
//         long long cellId[4] = {_id, _id + 1, _id + 2, _id + 3};
//         cellValueArray->InsertNextValue((double)_idx);
//         cellArray->InsertNextCell(4, cellId);
//         cellTypes->SetValue(_idx, VTK_QUAD);
//     }



//     cellValueArray->SetName(cellArrayName.c_str());
//     dataset->SetCells(cellTypes, cellArray);
//     dataset->GetCellData()->AddArray(cellValueArray);
// }


