public static void ExportModel(string filename)
        {
            ExportStage      = 0;
            ExportPercentage = 0;
            ExportError      = (int)Error.WORK;
            IsExportingMesh  = true;
            IsScannedMeshPreviewCompleted = false;

            SRWorkModule_API.SetReconstructionParameterBool((int)ReconstructionParam.EXPORT_ADAPTIVE_MODEL, ExportAdaptiveMesh);
            if (ExportAdaptiveMesh)
            {
                SRWorkModule_API.SetReconstructionParameterFloat((int)ReconstructionParam.ADAPTIVE_MAX_GRID, ExportAdaptiveMaxGridSize * 0.01f);   // cm to m
                SRWorkModule_API.SetReconstructionParameterFloat((int)ReconstructionParam.ADAPTIVE_MIN_GRID, ExportAdaptiveMinGridSize * 0.01f);
                SRWorkModule_API.SetReconstructionParameterFloat((int)ReconstructionParam.ADAPTIVE_ERROR_THRES, ExportAdaptiveErrorThres);
            }

            //if ((int)Error.WORK != SRWorkModule_API.RegisterReconstructionCallback(Marshal.GetFunctionPointerForDelegate((ExportProgressCallback)UpdateExportProgress)))
            //    Debug.Log("[ViveSR] [ExportModel] Progress listener failed to register");
            //ViveSR_Framework.RegisterCallback(ViveSR_Framework.MODULE_ID_RIGID_RECONSTRUCTION, (int)ReconstructionCallback.EXPORT_PROGRESS, Marshal.GetFunctionPointerForDelegate((ExportProgressCallback)UpdateExportProgress));

            byte[] bytearray = System.Text.Encoding.ASCII.GetBytes(filename);
            IntPtr parameter = Marshal.AllocCoTaskMem(filename.Length);

            Marshal.Copy(bytearray, 0, parameter, filename.Length);

            SRWorkModule_API.SetReconstructionOutputFileName(parameter, filename.Length);
        }
        private bool UpdateRuntimeParameter()
        {
            bool result = true;
            int  ret    = (int)Error.FAILED;

            // check live mesh display mode
            if (ViveSR_SceneUnderstanding.IsEnabledSceneUnderstandingView || ViveSR_RigidReconstruction.IsDuringScannedMeshPreview)
            {
                LiveMeshDisplayMode = ReconstructionDisplayMode.ADAPTIVE_MESH; //support only in this mode
            }
            // update live mesh display mode
            if ((int)LiveMeshDisplayMode != LastLiveMeshDisplayMode)
            {
                HideAllLiveMeshes();
                result = SetMeshDisplayMode(LiveMeshDisplayMode) && result;
                LastLiveMeshDisplayMode = (int)LiveMeshDisplayMode;
                // refresh rate
                SRWorkModule_API.SetReconstructionParameterInt((int)ReconstructionParam.MESH_REFRESH_INTERVAL, RefreshIntervalMS);

                // full scene quality
                if (LiveMeshDisplayMode == ReconstructionDisplayMode.FULL_SCENE)
                {
                    ret = SRWorkModule_API.SetReconstructionParameterInt((int)(ReconstructionParam.CONFIG_QUALITY), (int)FullSceneQuality);
                    LiveMeshMaterial.SetFloat("_PointSizeScaler", (FullSceneQuality == ReconstructionQuality.LOW) ? 1.2f : 0.8f);
                    result = result && (ret == (int)Error.WORK);
                }
                // update live adaptive param
                if (LiveMeshDisplayMode == ReconstructionDisplayMode.ADAPTIVE_MESH)
                {
                    ret    = SRWorkModule_API.SetReconstructionParameterFloat((int)ReconstructionParam.ADAPTIVE_MAX_GRID, ViveSR_RigidReconstruction.LiveAdaptiveMaxGridSize * 0.01f); // cm to m
                    result = result && (ret == (int)Error.WORK);
                    ret    = SRWorkModule_API.SetReconstructionParameterFloat((int)ReconstructionParam.ADAPTIVE_MIN_GRID, ViveSR_RigidReconstruction.LiveAdaptiveMinGridSize * 0.01f);
                    result = result && (ret == (int)Error.WORK);
                    ret    = SRWorkModule_API.SetReconstructionParameterFloat((int)ReconstructionParam.ADAPTIVE_ERROR_THRES, ViveSR_RigidReconstruction.LiveAdaptiveErrorThres);
                    result = result && (ret == (int)Error.WORK);
                }
            }

            if (EnableSector != LastEnableSector)
            {
                HideAllLiveMeshes();
                SRWorkModule_API.SetReconstructionParameterBool((int)(ReconstructionParam.ENABLE_FRUSTUM_CULLING), EnableSector);
                SRWorkModule_API.SetReconstructionParameterBool((int)(ReconstructionParam.ENABLE_SECTOR_GROUPER), EnableSector);
                SRWorkModule_API.SetReconstructionParameterFloat((int)(ReconstructionParam.SECTOR_SIZE), SectorSizeInMeter);
                LastEnableSector = EnableSector;
            }

            if (SetWireFrameOpaque != LastSetWireFrameOpaque)
            {
                WireframeMaterial.SetFloat("_Opaque", SetWireFrameOpaque ? 1.0f : 0.0f);
                LastSetWireFrameOpaque = SetWireFrameOpaque;
            }
            return(result);
        }
        public static void ExtractModelPreviewData()
        {
            ExportStage                = 0;
            ScannedMeshPreview         = 0;
            IsDuringScannedMeshPreview = true;

            SRWorkModule_API.SetReconstructionParameterBool((int)ReconstructionParam.EXPORT_ADAPTIVE_MODEL, ExportAdaptiveMesh);
            if (ExportAdaptiveMesh)
            {
                SRWorkModule_API.SetReconstructionParameterFloat((int)ReconstructionParam.ADAPTIVE_MAX_GRID, ExportAdaptiveMaxGridSize * 0.01f);   // cm to m
                SRWorkModule_API.SetReconstructionParameterFloat((int)ReconstructionParam.ADAPTIVE_MIN_GRID, ExportAdaptiveMinGridSize * 0.01f);
                SRWorkModule_API.SetReconstructionParameterFloat((int)ReconstructionParam.ADAPTIVE_ERROR_THRES, ExportAdaptiveErrorThres);
            }
            SRWorkModule_API.SetReconstructionParameterBool((int)(ReconstructionCmd.MODEL_PREVIEW_START_FOR_UNITY), true);
        }