示例#1
0
        /// <summary>
        /// Enables the user to perform automatic retopology on the .OBJ mesh via Instant Meshes.
        /// </summary>
        /// <param name="serializedObject"></param> The serialized object to modify.
        public void SubsectionRunInstantMeshesOBJ(SerializedObject serializedObject)
        {
            EditorGUILayout.Space();
            string workspace      = dataHandler.dataDirectory;
            string inputFilePath  = Path.Combine(workspace, BlenderConnector.convertPLYtoOBJOutputFileName);
            string outputFilePath = inputFilePath;
            string label          = "Perform automatic retopology.";
            string tooltip        = "This will re-mesh the .OBJ file at \"" + GeneralToolkit.FormatPathForCommand(inputFilePath) + "\".";
            // Check if this option is available.
            bool isGUIEnabled = GUI.enabled;

            GUI.enabled = isGUIEnabled && File.Exists(inputFilePath) && Application.isPlaying;
            GeneralToolkit.EditorRequirePlayMode(ref tooltip);// Display a button to launch the helper method.
            bool hasPressed = GeneralToolkit.EditorWordWrapLeftButton(new GUIContent("Run", tooltip), new GUIContent(label, tooltip));

            // If the button is pressed, launch the method.
            if (hasPressed)
            {
                StartCoroutine(InstantMeshesConnector.RunInstantMeshesCoroutine(this, workspace, inputFilePath, outputFilePath, _reduceVertexCountToRecommended));
            }
            // Provide the option to reduce the face count to the value recommended by Instant Meshes, or to use the current vertex count.
            SerializedProperty propertyReduceVertexCountToRecommended = serializedObject.FindProperty(_propertyNameReduceVertexCountToRecommended);

            label    = "Reduce vertex count:";
            tooltip  = "If true, reduces the vertex count to the value recommended by Instant Meshes. Otherwise, aims to keep the same vertex count.";
            tooltip += " For scenes in which the region of interest is small compared to the bounds of the mesh, it is recommended to turn this off.";
            propertyReduceVertexCountToRecommended.boolValue = EditorGUILayout.Toggle(new GUIContent(label, tooltip), propertyReduceVertexCountToRecommended.boolValue);
            // Reset the GUI.
            GUI.enabled = isGUIEnabled;
            EditorGUILayout.Space();
        }
        /// <summary>
        /// Enables the user to launch dense 3D reconstruction and meshing via COLMAP.
        /// </summary>
        /// <param name="workspace"></param> The workspace from which to perform this method.
        private void SubsectionDenseReconstruction()
        {
            EditorGUILayout.Space();
            string workspace = dataHandler.dataDirectory;
            string label     = "Reconstruct 3D mesh (.PLY) from sparse camera setup.";
            string tooltip   = "Processed geometry will be stored at: \"" + COLMAPConnector.GetDelaunayFile(workspace) + "\".";
            // Check if this option is available.
            bool isGUIEnabled = GUI.enabled;

            GUI.enabled = isGUIEnabled && (cameraSetup != null && cameraSetup.cameraModels != null) && workspace.Contains(COLMAPConnector.dense0DirName) && Application.isPlaying;
            GeneralToolkit.EditorRequirePlayMode(ref tooltip);
            // Display a button to launch the helper method.
            bool hasPressed = GeneralToolkit.EditorWordWrapLeftButton(new GUIContent("Run", tooltip), new GUIContent(label, tooltip));

            // If the button is pressed, display a dialog to confirm.
            if (hasPressed)
            {
                label   = "Existing data will be erased. Are you ready to proceed?";
                tooltip = "Launching this process will erase data in the folder: \"" + workspace + "\". Are you ready to proceed?";
                // If the user confirms, update the workspace directory and launch the method.
                if (EditorUtility.DisplayDialog(label, tooltip, "Yes", "No"))
                {
                    StartCoroutine(COLMAPConnector.RunDenseReconstructionCoroutine(this, workspace));
                }
            }
            // Reset the GUI.
            GUI.enabled = isGUIEnabled;
            EditorGUILayout.Space();
        }
        /// <summary>
        /// Enables the user to launch dense 3D reconstruction and meshing via COLMAP.
        /// </summary>
        /// <param name="workspace"></param> The workspace from which to perform this method.
        private void SubsectionDenseReconstruction()
        {
            EditorGUILayout.Space();
            string workspace = dataHandler.dataDirectory;
            string label     = "Reconstruct 3D mesh (.PLY) from sparse camera setup.";
            string tooltip   = "Processed geometry will be stored at: \"" + COLMAPConnector.GetDelaunayFile(workspace) + "\".";
            // Check if this option is available.
            bool isGUIEnabled = GUI.enabled;

            GUI.enabled = isGUIEnabled && (cameraSetup != null && cameraSetup.cameraModels != null && cameraSetup.cameraModels.Length > 0) && (dataHandler != null && dataHandler.imagePointCorrespondencesExist) && Application.isPlaying;
            GeneralToolkit.EditorRequirePlayMode(ref tooltip);
            // Display a button to launch the helper method.
            bool hasPressed = GeneralToolkit.EditorWordWrapLeftButton(new GUIContent("Run", tooltip), new GUIContent(label, tooltip));

            // If the button is pressed, display a dialog to confirm.
            if (hasPressed)
            {
                label    = "Existing data will be erased. Are you ready to proceed?";
                tooltip  = "WARNING: Before launching this step, please check that you are using a CUDA-capable GPU. Your current GPU is a " + SystemInfo.graphicsDeviceName + ".";
                tooltip += "\n\nLaunching this process will erase data in the folder: \"" + workspace + "\". Are you ready to proceed?";
                // If the user confirms, update the workspace directory and launch the method.
                int chosenButton = EditorUtility.DisplayDialogComplex(label, tooltip, "Yes", "No", "Check whether my GPU is CUDA-capable");
                if (chosenButton == 0)
                {
                    StartCoroutine(COLMAPConnector.RunDenseReconstructionCoroutine(this, workspace, cameraSetup.cameraModels.Length));
                }
                else if (chosenButton == 2)
                {
                    Application.OpenURL("https://developer.nvidia.com/cuda-gpus");
                }
            }
            // Reset the GUI.
            GUI.enabled = isGUIEnabled;
            EditorGUILayout.Space();
        }
示例#4
0
        /// <summary>
        /// Enables the user to perform automatic retopology on the .OBJ mesh via Instant Meshes.
        /// </summary>
        /// <param name="serializedObject"></param> The serialized object to modify.
        public void SubsectionRunInstantMeshesOBJ(SerializedObject serializedObject)
        {
            EditorGUILayout.Space();
            string workspace      = dataHandler.dataDirectory;
            string inputFilePath  = Path.Combine(workspace, BlenderConnector.convertPLYtoOBJOutputFileName);
            string outputFilePath = inputFilePath;
            string label          = "Perform automatic retopology.";
            string tooltip        = "This will re-mesh the .OBJ file at \"" + GeneralToolkit.FormatPathForCommand(inputFilePath) + "\".";
            // Check if this option is available.
            bool isGUIEnabled = GUI.enabled;

            GUI.enabled = isGUIEnabled && File.Exists(inputFilePath) && Application.isPlaying;
            GeneralToolkit.EditorRequirePlayMode(ref tooltip);
            // Display a button to launch the helper method.
            bool hasPressed = GeneralToolkit.EditorWordWrapLeftButton(new GUIContent("Run", tooltip), new GUIContent(label, tooltip));

            // If the button is pressed, launch the method.
            if (hasPressed)
            {
                BlenderHelper blenderHelper = GetComponent <BlenderHelper>();
                StartCoroutine(InstantMeshesConnector.RunInstantMeshesCoroutine(this, workspace, inputFilePath, outputFilePath, blenderHelper));
            }
            // Reset the GUI.
            GUI.enabled = isGUIEnabled;
            EditorGUILayout.Space();
        }
        /// <summary>
        /// Enables the user to launch sparse 3D reconstruction via COLMAP.
        /// </summary>
        /// <param name="serializedObject"></param> The serialized object to modify.
        private void SubsectionSparseReconstruction(SerializedObject serializedObject)
        {
            EditorGUILayout.Space();
            string workspace = dataHandler.dataDirectory;
            string label     = "Recover sparse camera setup from images.";
            string tooltip   = "Images should be stored in the \"" + COLMAPConnector.GetImagesDir(workspace) + "\" folder.\n";

            tooltip += "Camera setup information will be stored at: \"" + COLMAPConnector.GetCamerasFile(workspace) + "\".";
            // Check if this option is available.
            bool isGUIEnabled = GUI.enabled;

            GUI.enabled = isGUIEnabled && (processingCaller.sourceColorCount > 1) && !(workspace.Contains(COLMAPConnector.dense0DirName)) && Application.isPlaying;
            GeneralToolkit.EditorRequirePlayMode(ref tooltip);
            // Display a button to launch the helper method.
            bool hasPressed = GeneralToolkit.EditorWordWrapLeftButton(new GUIContent("Run", tooltip), new GUIContent(label, tooltip));

            // Display additional parameters.
            EditorGUILayout.Space();
            if (GUI.enabled)
            {
                label   = "Camera type";
                tooltip = "COLMAP camera type of the camera(s) that acquired the source images.";
                SerializedProperty propertyCOLMAPCameraIndex = serializedObject.FindProperty(_propertyNameCOLMAPCameraIndex);
                propertyCOLMAPCameraIndex.intValue = EditorGUILayout.Popup(new GUIContent(label, tooltip), propertyCOLMAPCameraIndex.intValue, COLMAPConnector.COLMAPCameraTypes.ToArray());
                label   = "Is single camera";
                tooltip = "This value should be set to true if the source images were acquired by the same camera, false otherwise.";
                SerializedProperty propertyIsSingleCamera = serializedObject.FindProperty(_propertyNameIsSingleCamera);
                propertyIsSingleCamera.boolValue = EditorGUILayout.Toggle(new GUIContent(label, tooltip), propertyIsSingleCamera.boolValue);
                label   = "Max. image size: ";
                tooltip = "Maximum image size for the undistortion step. The resized images will be the ones used for rendering.";
                SerializedProperty propertyMaxImageSize = serializedObject.FindProperty(_propertyNameMaxImageSize);
                propertyMaxImageSize.intValue = EditorGUILayout.IntSlider(new GUIContent(label, tooltip), propertyMaxImageSize.intValue, 1, 8192);
            }
            // If the button is pressed, display a dialog to confirm.
            if (hasPressed)
            {
                label   = "Existing data will be erased. Are you ready to proceed?";
                tooltip = "Launching this process will erase data in the folder: \"" + workspace + "\". Are you ready to proceed?";
                // If the user confirms, launch the method.
                if (EditorUtility.DisplayDialog(label, tooltip, "Yes", "No"))
                {
                    StartCoroutine(COLMAPConnector.RunSparseReconstructionCoroutine(processingCaller, workspace, _COLMAPCameraIndex, _isSingleCamera, _maxImageSize));
                }
                hasPerformedSparseReconstruction = true;
                ChangeWorkspaceAfterSparseReconstruction();
            }
            // Reset the GUI.
            GUI.enabled = isGUIEnabled;
            EditorGUILayout.Space();
        }
        /// <summary>
        /// Enables the user to convert the .PLY mesh file to .OBJ via Blender.
        /// </summary>
        public void SubsectionConvertPLYtoOBJ()
        {
            EditorGUILayout.Space();
            string inputFilePath  = Path.Combine(_meshWorkspace, COLMAPConnector.delaunayFileName);
            string outputFilePath = Path.Combine(_meshWorkspace, BlenderConnector.convertPLYtoOBJOutputFileName);
            string label          = "Convert .PLY mesh to .OBJ file.";
            string tooltip        = "File " + GeneralToolkit.FormatPathForCommand(inputFilePath) + " will be converted to file " + GeneralToolkit.FormatPathForCommand(outputFilePath) + ".";
            // Check if this option is available.
            bool isGUIEnabled = GUI.enabled;

            GUI.enabled = isGUIEnabled && File.Exists(inputFilePath) && Application.isPlaying;
            GeneralToolkit.EditorRequirePlayMode(ref tooltip);
            // Display a button to launch the helper method.
            bool hasPressed = GeneralToolkit.EditorWordWrapLeftButton(new GUIContent("Run", tooltip), new GUIContent(label, tooltip));

            if (hasPressed)
            {
                StartCoroutine(BlenderConnector.RunConvertPLYtoOBJCoroutine(processingCaller, inputFilePath, outputFilePath, ReadMeshFaceCount));
            }
            // Reset the GUI.
            GUI.enabled = isGUIEnabled;
            EditorGUILayout.Space();
        }
        /// <summary>
        /// Enables the user to UV-map the given .OBJ mesh using Blender's Smart UV Project algorithm.
        /// </summary>
        public void SubsectionSmartUVProjectOBJ()
        {
            EditorGUILayout.Space();
            string inputFilePath  = Path.Combine(_meshWorkspace, BlenderConnector.convertPLYtoOBJOutputFileName);
            string outputFilePath = inputFilePath;
            string label          = "UV-map .OBJ file.";
            string tooltip        = "Mesh in file " + GeneralToolkit.FormatPathForCommand(inputFilePath) + " will be UV-mapped using Blender's Smart UV Project algorithm.";
            // Check if this option is available.
            bool isGUIEnabled = GUI.enabled;

            GUI.enabled = isGUIEnabled && File.Exists(inputFilePath) && Application.isPlaying;
            GeneralToolkit.EditorRequirePlayMode(ref tooltip);
            // Display a button to launch the helper method.
            bool hasPressed = GeneralToolkit.EditorWordWrapLeftButton(new GUIContent("Run", tooltip), new GUIContent(label, tooltip));

            if (hasPressed)
            {
                StartCoroutine(BlenderConnector.RunSmartUVProjectOBJCoroutine(this, inputFilePath, outputFilePath));
            }
            // Reset the GUI.
            GUI.enabled = isGUIEnabled;
            EditorGUILayout.Space();
        }
        /// <summary>
        /// Enables the user to check the mesh information contained in the .OBJ file via Blender.
        /// </summary>
        public void SubsectionCheckOBJMeshInfo()
        {
            EditorGUILayout.Space();
            string inputFilePath = Path.Combine(_meshWorkspace, BlenderConnector.convertPLYtoOBJOutputFileName);
            string label         = "Check .OBJ mesh information.";
            string tooltip       = "File " + GeneralToolkit.FormatPathForCommand(inputFilePath) + " will be read from, to check its number of triangle faces.";
            // Check if this option is available.
            bool isGUIEnabled = GUI.enabled;

            GUI.enabled = isGUIEnabled && File.Exists(inputFilePath) && Application.isPlaying;
            GeneralToolkit.EditorRequirePlayMode(ref tooltip);
            // Display a button to launch the helper method.
            bool hasPressed = GeneralToolkit.EditorWordWrapLeftButton(new GUIContent("Run", tooltip), new GUIContent(label, tooltip));

            if (hasPressed)
            {
                CheckOBJMeshInfo(_meshWorkspace);
            }
            // Display the current face count.
            GUIStyle grey = GeneralToolkit.wordWrapStyle;

            grey.normal.textColor = Color.grey;
            label = "Mesh face count: ";
            if (meshFaceCount == -1)
            {
                label += "not determined.";
            }
            else
            {
                label += GeneralToolkit.ToString(meshFaceCount) + ".";
            }
            tooltip = "Number of faces on the mesh.";
            EditorGUILayout.LabelField(new GUIContent(label, tooltip), grey);
            // Reset the GUI.
            GUI.enabled = isGUIEnabled;
            EditorGUILayout.Space();
        }
        /// <summary>
        /// Enables the user to simplify the .OBJ mesh via Blender.
        /// </summary>
        /// <param name="serializedObject"></param> The serialized object to modify.
        public void SubsectionSimplifyOBJ(SerializedObject serializedObject)
        {
            EditorGUILayout.Space();
            string inputFilePath  = Path.Combine(_meshWorkspace, BlenderConnector.convertPLYtoOBJOutputFileName);
            string outputFilePath = inputFilePath;
            string label          = "Simplify .OBJ mesh.";
            string tooltip        = "Mesh in file " + GeneralToolkit.FormatPathForCommand(inputFilePath) + " will be simplified, reducing its face count.";
            // Check if this option is available.
            bool isGUIEnabled = GUI.enabled;

            GUI.enabled = isGUIEnabled && File.Exists(inputFilePath) && Application.isPlaying;
            GeneralToolkit.EditorRequirePlayMode(ref tooltip);
            // Display a button to launch the helper method.
            bool hasPressed = GeneralToolkit.EditorWordWrapLeftButton(new GUIContent("Run", tooltip), new GUIContent(label, tooltip));

            // If the button is pressed, launch the method.
            if (hasPressed)
            {
                StartCoroutine(BlenderConnector.RunSimplifyOBJCoroutine(this, inputFilePath, outputFilePath, ReadMeshFaceCount));
            }
            // Reset the GUI.
            GUI.enabled = isGUIEnabled;
            EditorGUILayout.Space();
        }