/// <summary>
    /// Pack data, store it in class and return a data
    /// </summary>
    /// <param name="Dictionary<string"></param>
    /// <param name="data"></param>
    /// <returns></returns>
    public bool PackData(out Dictionary <DOF, Dictionary <DataRange, float> > datasetPara)
    {
        datasetPara = new Dictionary <DOF, Dictionary <DataRange, float> >();

        if (!CheckValidation(out string msg))
        {
            WinFormTools.MessageBox(IntPtr.Zero, msg, "Invalid Input", 0);
            return(false);
        }

        foreach (var oneDOF in inputFieldObj)
        {
            Dictionary <DataRange, float> singleItem = new Dictionary <DataRange, float>();
            foreach (var oneInputField in oneDOF.Value)
            {
                string text = oneInputField.Value.text;
                float  value;
                float.TryParse(text, out value);
                singleItem[oneInputField.Key] = value;
            }
            datasetPara[oneDOF.Key] = singleItem;
        }

        return(true);
    }
    /// <summary>
    /// Save a single image and store the para in the .csv file
    /// </summary>
    public override void StartGeneratingDataset()
    {
        // Check whether can save this img currently
        if (!IsValid)
        {
            WinFormTools.MessageBox(IntPtr.Zero, "Finger not touched or overlapped", "Cannot Save Image", 0);
            return;
        }

        // Save the data into disk
        commonWriter = CreateOrOpenFolderFile(FolderName, CSVFileName, streamDataGenerator);

        SaveStreamDataToDisk();

        // Close the writer
        commonWriter.Flush();
        commonWriter.Close();
        commonWriter = null;

        WinFormTools.MessageBox(IntPtr.Zero, "Saved Image!", "Finish", 0);
        // LoadCSVFile(csvName);
    }
    IEnumerator DFSSearchGeneratingCore()
    {
        // Prepare the data file
        commonWriter = CreateOrOpenFolderFile(FolderName, CSVFileName, streamDataGenerator);

        _closedList = new HashSet <string>();
        _validCnt   = 0;

        // DFS Search
        _para = new float[] { 0, 0, 0, 0, 0, 0 };
        _closedList.Add(ConvertString(_para));

        yield return(StartCoroutine(DFS()));

        // Close the writer
        commonWriter.Flush();
        commonWriter.Close();
        commonWriter = null;

        WinFormTools.MessageBox(IntPtr.Zero, "Valid Image: " + _validCnt, "Finish", 0);

        Debug.Log("Finish Generaing!");
    }
    public bool PackData(
        out Dictionary <DOF, Dictionary <DataRange, float> > datasetPara)
    {
        datasetPara = new Dictionary <DOF, Dictionary <DataRange, float> >();

        if (!CheckValidation(out string msg))
        {
            WinFormTools.MessageBox(IntPtr.Zero, msg, "Invalid Input", 0);
            return(false);
        }

        string text = inputField.text;
        float  value;

        float.TryParse(text, out value);

        Dictionary <DataRange, float> singleItem = new Dictionary <DataRange, float>();

        singleItem[DataRange.step] = value;
        datasetPara[DOF.gamma1]    = singleItem;

        return(true);
    }
    IEnumerator BFSSearchGeneratingCore()
    {
        // Prepare the data file
        commonWriter = CreateOrOpenFolderFile(FolderName, CSVFileName, streamDataGenerator);

        _openList   = new Queue <string>();
        _closedList = new HashSet <string>();
        _validCnt   = 0;

        // BFS Search
        _para = new float[] { 0, 0, 0, 0, 0, 0 };
        _openList.Enqueue(ConvertString(_para));

        while (_openList.Count > 0)
        {
            _para = ConvertFloat(_openList.Dequeue());
            _closedList.Add(ConvertString(_para));

            // Check current para, set the joint value
            Processing = true;
            jointManager.SetJointsValues(_para);

            // After set the joint, need use yield return here,
            // otherwise the joints won't be updated in Unity
            yield return(new WaitWhile(() => Processing));

            if (IsValid)
            {
                // If valid, update frame
                _validCnt++;
                datasetPanel.UpdateCurrentSampleCnt(_validCnt);

                // Save data to disk
                yield return(StartCoroutine(SaveStreamDataToDisk()));

                // Generate next values and add to open list
                // Iterate 12 next steps.
                // If they are not in the closed list, add it to open list
                for (int i = 0; i < _para.Length; i++)
                {
                    _para[i]     += _stepLength;
                    _checkPattern = ConvertString(_para);
                    if (InBoundary(i, _para[i]) &&
                        !_closedList.Contains(_checkPattern) &&
                        !_openList.Contains(_checkPattern))
                    {
                        _openList.Enqueue(_checkPattern);
                    }
                    _para[i] -= _stepLength;

                    _para[i]     -= _stepLength;
                    _checkPattern = ConvertString(_para);
                    if (InBoundary(i, _para[i]) &&
                        !_closedList.Contains(_checkPattern) &&
                        !_openList.Contains(_checkPattern))
                    {
                        _openList.Enqueue(_checkPattern);
                    }
                    _para[i] += _stepLength;
                }
            }
        }

        // Close the writer
        commonWriter.Flush();
        commonWriter.Close();
        commonWriter = null;

        WinFormTools.MessageBox(IntPtr.Zero, "Valid Image: " + _validCnt, "Finish", 0);

        Debug.Log("Finish Generaing!");
    }
    /// <summary>
    /// Iterate the parameters and save image and data to disk
    /// </summary>
    IEnumerator GenerateDatasetCore(
        Dictionary <DOF, Dictionary <DataRange, float> > para)
    {
        Debug.Log("Start Generaing...");

        // Prepare the data file
        commonWriter = CreateOrOpenFolderFile(FolderName, CSVFileName, streamDataGenerator);

        // Calculate the total number
        long totalCnt = 1;

        foreach (var joint in para.Keys)
        {
            totalCnt *= (para[joint][DataRange.step] == 0) ?
                        1 : Convert.ToInt64((para[joint][DataRange.max] - para[joint][DataRange.min]) / para[joint][DataRange.step]);
        }
        datasetPanel.UpdateTotalSampleCnt(totalCnt);

        // Start iteration
        long currentCnt = 0;
        long validCnt   = 0;

        float[] DOFS = new float[6];
        for (float gamma1 = para[DOF.gamma1][DataRange.min];
             gamma1 <= para[DOF.gamma1][DataRange.max];
             gamma1 += Mathf.Max(para[DOF.gamma1][DataRange.step], 1e-8f))
        {
            DOFS[0] = gamma1;

            for (float gamma2 = para[DOF.gamma2][DataRange.min];
                 gamma2 <= para[DOF.gamma2][DataRange.max];
                 gamma2 += Mathf.Max(para[DOF.gamma2][DataRange.step], 1e-8f))
            {
                DOFS[1] = gamma2;

                for (float gamma3 = para[DOF.gamma3][DataRange.min];
                     gamma3 <= para[DOF.gamma3][DataRange.max];
                     gamma3 += Mathf.Max(para[DOF.gamma3][DataRange.step], 1e-8f))
                {
                    DOFS[2] = gamma3;

                    for (float alpha1 = para[DOF.alpha1][DataRange.min];
                         alpha1 <= para[DOF.alpha1][DataRange.max];
                         alpha1 += Mathf.Max(para[DOF.alpha1][DataRange.step], 1e-8f))
                    {
                        DOFS[3] = alpha1;

                        for (float alpha2 = para[DOF.alpha2][DataRange.min];
                             alpha2 <= para[DOF.alpha2][DataRange.max];
                             alpha2 += Mathf.Max(para[DOF.alpha2][DataRange.step], 1e-8f))
                        {
                            DOFS[4] = alpha2;

                            for (float beta = para[DOF.beta][DataRange.min];
                                 beta <= para[DOF.beta][DataRange.max];
                                 beta += Mathf.Max(para[DOF.beta][DataRange.step], 1e-8f))
                            {
                                DOFS[5] = beta;

                                // Check current para, set the joint value
                                Processing = true;
                                jointManager.SetJointsValues(DOFS);

                                // After set the joint, need use yield return here,
                                // otherwise the joints won't be updated in Unity
                                yield return(new WaitWhile(() => Processing));

                                currentCnt++;
                                datasetPanel.UpdateCurrentSampleCnt(currentCnt);
                                yield return(null);

                                // If could save, save image here
                                if (IsValid)
                                {
                                    validCnt++;
                                    yield return(StartCoroutine(SaveStreamDataToDisk()));
                                }
                            }
                        }
                    }
                }
            }
        }

        commonWriter.Flush();
        commonWriter.Close();
        commonWriter = null;

        WinFormTools.MessageBox(IntPtr.Zero, "Valid Image: " + validCnt, "Finish", 0);

        Debug.Log("Finish Generaing!");
    }