public override ActionResult DoAction()
        {
            if (MeshSelection.selectedObjectCount < 1)
                return ActionResult.NoSelection;

            UndoUtility.RecordSelection("Flip Face Edges");
            int success = 0;
            int attempts = 0;

            foreach (ProBuilderMesh pb in MeshSelection.topInternal)
            {
                foreach (Face face in pb.selectedFacesInternal)
                {
                    if (pb.FlipEdge(face))
                        success++;
                }

                attempts++;

                pb.ToMesh();
                pb.Refresh();
                pb.Optimize();
            }

            ProBuilderEditor.Refresh();

            if (success > 0)
                return new ActionResult(ActionResult.Status.Success, "Flipped " + success + " Edges");

            return new ActionResult(ActionResult.Status.Failure, string.Format("Flip Edges\n{0}", attempts > 0 ? "Faces Must Be Quads" : "No Faces Selected"));
        }
        public override ActionResult DoAction()
        {
            if (MeshSelection.selectedObjectCount < 1)
            {
                return(ActionResult.NoSelection);
            }

            Object[] objects = new Object[MeshSelection.selectedObjectCount * 2];

            for (int i = 0, c = MeshSelection.selectedObjectCount; i < c; i++)
            {
                objects[i]     = MeshSelection.topInternal[i];
                objects[i + c] = MeshSelection.topInternal[i].transform;
            }

            UndoUtility.RegisterCompleteObjectUndo(objects, "Set Pivot");

            foreach (var mesh in MeshSelection.topInternal)
            {
                TransformUtility.UnparentChildren(mesh.transform);
                mesh.CenterPivot(mesh.selectedIndexesInternal);
                mesh.Optimize();
                TransformUtility.ReparentChildren(mesh.transform);
            }

            ProBuilderEditor.Refresh();

            return(new ActionResult(ActionResult.Status.Success, "Set Pivot"));
        }
Exemple #3
0
        public override ActionResult DoAction()
        {
            ActionResult res = ActionResult.NoSelection;

            UndoUtility.RecordSelection("Bevel Edges");

            foreach (ProBuilderMesh pb in MeshSelection.topInternal)
            {
                pb.ToMesh();

                List <Face> faces = Bevel.BevelEdges(pb, pb.selectedEdges, m_BevelSize);
                res = faces != null ? new ActionResult(ActionResult.Status.Success, "Bevel Edges") : new ActionResult(ActionResult.Status.Failure, "Failed Bevel Edges");

                if (res)
                {
                    pb.SetSelectedFaces(faces);
                }

                pb.Refresh();
                pb.Optimize();
            }

            ProBuilderEditor.Refresh();

            return(res);
        }
Exemple #4
0
        public override ActionResult DoAction()
        {
            if (MeshSelection.selectedObjectCount < 1)
            {
                return(ActionResult.NoSelection);
            }

            UndoUtility.RecordSelection("Subdivide Selection");

            int success = 0;

            foreach (ProBuilderMesh pb in MeshSelection.topInternal)
            {
                pb.ToMesh();

                if (pb.Subdivide())
                {
                    success++;
                }
                else
                {
                    Debug.LogError($"Subidivision of [{pb.name}] failed, complex concave objects are not supported");
                }

                pb.Refresh();
                pb.Optimize();

                pb.SetSelectedVertices(new int[0]);
            }

            ProBuilderEditor.Refresh();

            return(new ActionResult(ActionResult.Status.Success, "Subdivide " + success + " Objects"));
        }
        public override ActionResult DoAction()
        {
            if (MeshSelection.selectedObjectCount < 1)
            {
                return(ActionResult.NoSelection);
            }

            int subdivisions = m_SubdivisionCount;

            UndoUtility.RecordSelection("Subdivide Edges");

            ActionResult result = ActionResult.NoSelection;

            foreach (ProBuilderMesh pb in MeshSelection.topInternal)
            {
                List <Edge> newEdgeSelection = AppendElements.AppendVerticesToEdge(pb, pb.selectedEdges, subdivisions);

                if (newEdgeSelection != null)
                {
                    pb.SetSelectedEdges(newEdgeSelection);
                    pb.ToMesh();
                    pb.Refresh();
                    pb.Optimize();
                    result = new ActionResult(ActionResult.Status.Success, "Subdivide Edge");
                }
                else
                {
                    result = new ActionResult(ActionResult.Status.Failure, "Failed Subdivide Edge");
                }
            }

            ProBuilderEditor.Refresh();

            return(result);
        }
        protected override ActionResult PerformActionImplementation()
        {
            if (MeshSelection.selectedObjectCount < 1)
            {
                return(ActionResult.NoSelection);
            }

            int splitCount = 0;

            UndoUtility.RecordSelection("Split Vertices");

            foreach (ProBuilderMesh mesh in MeshSelection.topInternal)
            {
                var coincident = mesh.selectedCoincidentVertices;
                splitCount += mesh.selectedSharedVerticesCount;
                mesh.SplitVertices(coincident);
            }

            ProBuilderEditor.Refresh();

            if (splitCount > 0)
            {
                return(new ActionResult(ActionResult.Status.Success, "Split " + splitCount + (splitCount > 1 ? " Vertices" : " Vertex")));
            }

            return(new ActionResult(ActionResult.Status.Failure, "Split Vertices\nInsuffient Vertices Selected"));
        }
Exemple #7
0
        public override ActionResult DoAction()
        {
            ActionResult res = ActionResult.NoSelection;

            UndoUtility.RecordSelection("Connect Edges");

            foreach (var mesh in MeshSelection.topInternal)
            {
                Edge[] connections;
                Face[] faces;

                res = ConnectElements.Connect(mesh, mesh.selectedEdges, out faces, out connections, true, true);

                if (connections != null)
                {
                    if (connections.Length != 0)
                    {
                        mesh.SetSelectedEdges(connections);
                    }
                    mesh.Refresh();
                    mesh.Optimize();
                }
            }

            ProBuilderEditor.Refresh();
            return(res);
        }
Exemple #8
0
        static ActionResult DuplicateFacesToSubmesh()
        {
            int count = 0;

            foreach (ProBuilderMesh pb in MeshSelection.topInternal)
            {
                pb.ToMesh();
                List <Face> res = pb.DetachFaces(pb.selectedFacesInternal, false);
                pb.Refresh();
                pb.Optimize();

                pb.SetSelectedFaces(res.ToArray());

                count += pb.selectedFaceCount;
            }

            ProBuilderEditor.Refresh();

            if (count > 0)
            {
                return(new ActionResult(ActionResult.Status.Success, "Duplicate " + count + (count > 1 ? " Faces" : " Face")));
            }

            return(new ActionResult(ActionResult.Status.Success, "Duplicate Faces"));
        }
Exemple #9
0
        public override ActionResult DoAction()
        {
            if (MeshSelection.selectedObjectCount < 1)
            {
                return(ActionResult.NoSelection);
            }

            int success = 0;

            UndoUtility.RecordSelection("Insert Edge Loop");

            foreach (ProBuilderMesh pb in MeshSelection.topInternal)
            {
                Edge[] edges = pb.Connect(ElementSelection.GetEdgeRing(pb, pb.selectedEdges)).item2;

                if (edges != null)
                {
                    pb.SetSelectedEdges(edges);
                    pb.ToMesh();
                    pb.Refresh();
                    pb.Optimize();
                    success++;
                }
            }

            ProBuilderEditor.Refresh();

            if (success > 0)
            {
                return(new ActionResult(ActionResult.Status.Success, "Insert Edge Loop"));
            }

            return(new ActionResult(ActionResult.Status.Success, "Insert Edge Loop"));
        }
        protected override ActionResult PerformActionImplementation()
        {
            UndoUtility.RecordSelection("Select Faces with Smoothing Group");

            HashSet <int> selectedSmoothGroups = new HashSet <int>(MeshSelection.topInternal.SelectMany(x => x.selectedFacesInternal.Select(y => y.smoothingGroup)));

            List <GameObject> newSelection = new List <GameObject>();

            foreach (ProBuilderMesh pb in MeshSelection.topInternal)
            {
                IEnumerable <Face> matches = pb.facesInternal.Where(x => selectedSmoothGroups.Contains(x.smoothingGroup));

                if (matches.Count() > 0)
                {
                    newSelection.Add(pb.gameObject);
                    pb.SetSelectedFaces(matches);
                }
            }

            Selection.objects = newSelection.ToArray();

            ProBuilderEditor.Refresh();

            return(new ActionResult(ActionResult.Status.Success, "Select Faces with Smoothing Group"));
        }
Exemple #11
0
        public override ActionResult DoAction()
        {
            ActionResult res = ActionResult.NoSelection;

            UndoUtility.RecordSelection("Connect Vertices");

            foreach (var mesh in MeshSelection.topInternal)
            {
                mesh.ToMesh();
                int[] splits = mesh.Connect(mesh.selectedIndexesInternal);

                if (splits != null)
                {
                    mesh.Refresh();
                    mesh.Optimize();
                    mesh.SetSelectedVertices(splits);
                    res = new ActionResult(ActionResult.Status.Success, "Connect Edges");
                }
                else
                {
                    res = new ActionResult(ActionResult.Status.Failure, "Failed Connecting Edges");
                }
            }
            ProBuilderEditor.Refresh();

            return(res);
        }
        public override ActionResult DoAction()
        {
            var selection = MeshSelection.topInternal;

            UndoUtility.RecordSelection("Conform " + (MeshSelection.selectedFaceCount > 0 ? "Face" : "Object") + " Normals.");

            ActionResult res = ActionResult.NoSelection;

            foreach (ProBuilderMesh pb in selection)
            {
                var faces = pb.GetSelectedFaces();

                if (faces == null)
                {
                    continue;
                }

                res = UnityEngine.ProBuilder.MeshOperations.SurfaceTopology.ConformNormals(pb, faces);

                pb.ToMesh();
                pb.Refresh();
                pb.Optimize();
            }

            ProBuilderEditor.Refresh();

            return(res);
        }
Exemple #13
0
        public override ActionResult DoAction()
        {
            if (MeshSelection.selectedObjectCount < 2)
            {
                return(new ActionResult(ActionResult.Status.Canceled, "Must Select 2+ Objects"));
            }

            var selected = MeshSelection.top.ToArray();
            List <ProBuilderMesh> res = InternalMeshUtility.CombineObjects(MeshSelection.topInternal);

            if (res != null)
            {
                foreach (var mesh in res)
                {
                    mesh.Optimize();
                    mesh.gameObject.name = "pb-MergedObject" + mesh.id;
                    UndoUtility.RegisterCreatedObjectUndo(mesh.gameObject, "Merge Objects");
                    Selection.objects = res.Select(x => x.gameObject).ToArray();
                }

                // Delete donor objects
                for (int i = 0; i < selected.Length; i++)
                {
                    if (selected[i] != null)
                    {
                        UndoUtility.DestroyImmediate(selected[i].gameObject);
                    }
                }
            }

            ProBuilderEditor.Refresh();

            return(new ActionResult(ActionResult.Status.Success, "Merged Objects"));
        }
        public override ActionResult DoAction()
        {
            if (MeshSelection.selectedObjectCount < 1)
            {
                return(ActionResult.NoSelection);
            }

            UndoUtility.RecordSelection("Select Edge Ring");

            bool success = false;

            foreach (var mesh in MeshSelection.topInternal)
            {
                Edge[] edges = ElementSelection.GetEdgeRing(mesh, mesh.selectedEdges).ToArray();

                if (edges.Length > mesh.selectedEdgeCount)
                {
                    success = true;
                }

                mesh.SetSelectedEdges(edges);
            }

            ProBuilderEditor.Refresh();

            SceneView.RepaintAll();

            if (success)
            {
                return(new ActionResult(ActionResult.Status.Success, "Select Edge Ring"));
            }

            return(new ActionResult(ActionResult.Status.Failure, "Nothing to Ring"));
        }
Exemple #15
0
        public override ActionResult DoAction()
        {
            if (MeshSelection.selectedObjectCount < 1)
            {
                return(ActionResult.NoSelection);
            }

            UndoUtility.RecordSelection("Subdivide Selection");

            int success = 0;

            foreach (ProBuilderMesh pb in MeshSelection.topInternal)
            {
                pb.ToMesh();

                if (pb.Subdivide())
                {
                    success++;
                }

                pb.Refresh();
                pb.Optimize();

                pb.SetSelectedVertices(new int[0]);
            }

            ProBuilderEditor.Refresh();

            return(new ActionResult(ActionResult.Status.Success, "Subdivide " + success + " Objects"));
        }
Exemple #16
0
        /// <summary>
        /// Export meshes to a Unity asset.
        /// </summary>
        /// <param name="meshes"></param>
        /// <returns></returns>
        public static string ExportWithFileDialog(IList <ProBuilderMesh> meshes, ExportAssetOptions options)
        {
            if (meshes == null || !meshes.Any())
            {
                return("");
            }

            string res = null;

            if (meshes.Count() < 2)
            {
                ProBuilderMesh first = meshes.FirstOrDefault();

                if (first == null)
                {
                    return(null);
                }

                res = options.makePrefab
                    ? ExportPrefab(first, options.replaceOriginal)
                    : ExportMesh(first, options.replaceOriginal);
            }
            else
            {
                string path = UnityEditor.EditorUtility.SaveFolderPanel("Export to Asset", "Assets", "");

                if (string.IsNullOrEmpty(path) || !Directory.Exists(path))
                {
                    return(null);
                }

                meshes = meshes.ToList();
                for (int i = 0, c = meshes.Count; i < c; i++)
                {
                    var pb        = meshes[i];
                    var assetPath = string.Format("{0}/{1}.asset", path, pb.name);

                    if (options.makePrefab)
                    {
                        res = ExportPrefab(assetPath, pb, options.replaceOriginal, true);
                    }
                    else
                    {
                        res = ExportMesh(assetPath, pb, options.replaceOriginal, true);

                        if (options.replaceOriginal)
                        {
                            pb.preserveMeshAssetOnDestroy = true;
                            Undo.DestroyObjectImmediate(pb);
                        }
                    }
                }
            }

            ProBuilderEditor.Refresh();
            AssetDatabase.Refresh();

            return(res);
        }
        public override ActionResult DoAction()
        {
            IEnumerable <ProBuilderMesh> selection;

            if (m_RestrictToSelectedObjects)
            {
                selection = MeshSelection.topInternal;
            }
            else
            {
                selection = Object.FindObjectsOfType <ProBuilderMesh>();
            }

            UndoUtility.RecordSelection("Select Faces with Material");

            //Need to go from submesh index to material
            HashSet <Material> selectedMaterials = new HashSet <Material>();

            foreach (var pb in MeshSelection.topInternal)
            {
                HashSet <int> submeshIndex = new HashSet <int>(pb.selectedFacesInternal.Select(y => y.submeshIndex));
                foreach (var index in submeshIndex)
                {
                    selectedMaterials.Add(pb.renderer.sharedMaterials[index]);
                }
            }

            List <GameObject> newSelection = new List <GameObject>();

            foreach (var pb in selection)
            {
                List <int> subMeshIndices = new List <int>();
                for (int matIndex = 0; matIndex < pb.renderer.sharedMaterials.Length; ++matIndex)
                {
                    if (selectedMaterials.Contains(pb.renderer.sharedMaterials[matIndex]))
                    {
                        subMeshIndices.Add(matIndex);
                    }
                }

                if (subMeshIndices.Count > 0)
                {
                    IEnumerable <Face> matches = pb.facesInternal.Where(x => subMeshIndices.Contains(x.submeshIndex));
                    if (matches.Any())
                    {
                        newSelection.Add(pb.gameObject);
                        pb.SetSelectedFaces(matches);
                    }
                }
            }

            Selection.objects = newSelection.ToArray();

            ProBuilderEditor.Refresh();

            return(new ActionResult(ActionResult.Status.Success, "Select Faces with Material"));
        }
        void Clear()
        {
            m_Tool = null;
            MenuAction.onPerformAction           -= ActionPerformed;
            ToolManager.activeToolChanging       -= OnActiveToolChanging;
            ProBuilderEditor.selectModeChanged   -= OnSelectModeChanged;
            MeshSelection.objectSelectionChanged -= OnObjectSelectionChanged;

            ProBuilderEditor.Refresh();
        }
Exemple #19
0
        public override ActionResult DoAction()
        {
            var selection      = MeshSelection.topInternal;
            var selectionCount = MeshSelection.selectedObjectCount;

            UndoUtility.RecordSelection("Shrink Selection");

            // find perimeter edges
            int rc = 0;

            for (int i = 0; i < selectionCount; i++)
            {
                ProBuilderMesh mesh = selection[i];

                switch (ProBuilderEditor.selectMode)
                {
                case SelectMode.Edge:
                {
                    int[] perimeter = ElementSelection.GetPerimeterEdges(mesh, mesh.selectedEdges);
                    mesh.SetSelectedEdges(mesh.selectedEdges.RemoveAt(perimeter));
                    rc += perimeter != null ? perimeter.Length : 0;
                    break;
                }

                case SelectMode.TextureFace:
                case SelectMode.Face:
                {
                    Face[] perimeter = ElementSelection.GetPerimeterFaces(mesh, mesh.selectedFacesInternal).ToArray();
                    mesh.SetSelectedFaces(mesh.selectedFacesInternal.Except(perimeter).ToArray());
                    rc += perimeter.Length;
                    break;
                }

                case SelectMode.Vertex:
                {
                    var   universalEdges = mesh.GetSharedVertexHandleEdges(mesh.facesInternal.SelectMany(x => x.edges)).ToArray();
                    int[] perimeter      = ElementSelection.GetPerimeterVertices(mesh, mesh.selectedIndexesInternal, universalEdges);
                    mesh.SetSelectedVertices(mesh.selectedIndexesInternal.RemoveAt(perimeter));
                    rc += perimeter != null ? perimeter.Length : 0;
                    break;
                }
                }
            }

            ProBuilderEditor.Refresh();

            if (rc > 0)
            {
                return(new ActionResult(ActionResult.Status.Success, "Shrink Selection"));
            }

            return(new ActionResult(ActionResult.Status.Canceled, "Nothing to Shrink"));
        }
        protected override ActionResult PerformActionImplementation()
        {
            if (MeshSelection.selectedObjectCount < 1)
            {
                return(ActionResult.NoSelection);
            }

            UndoUtility.RecordSelection("Extrude");

            int  extrudedFaceCount = 0;
            bool success           = false;

            foreach (ProBuilderMesh pb in MeshSelection.topInternal)
            {
                pb.ToMesh();
                pb.Refresh(RefreshMask.Normals);

                if (pb.selectedEdgeCount < 1)
                {
                    continue;
                }

                extrudedFaceCount += pb.selectedEdgeCount;

                Edge[] newEdges = pb.Extrude(pb.selectedEdges,
                                             m_ExtrudeEdgeDistance,
                                             VertexManipulationTool.s_ExtrudeEdgesAsGroup,
                                             ProBuilderEditor.s_AllowNonManifoldActions);

                success |= newEdges != null;

                if (success)
                {
                    pb.SetSelectedEdges(newEdges);
                }
                else
                {
                    extrudedFaceCount -= pb.selectedEdgeCount;
                }

                pb.Rebuild();
            }

            ProBuilderEditor.Refresh();

            if (extrudedFaceCount > 0)
            {
                return(new ActionResult(ActionResult.Status.Success, "Extrude"));
            }

            return(new ActionResult(ActionResult.Status.Canceled, "Extrude\nEmpty Selection"));
        }
Exemple #21
0
        /// <summary>
        /// Adds pb_Object component without duplicating the objcet. Is undo-able.
        /// </summary>
        /// <param name="selected"></param>
        /// <param name="settings"></param>
        /// <returns></returns>
        public static ActionResult DoProBuilderize(
            IEnumerable <MeshFilter> selected,
            MeshImportSettings settings)
        {
            int   i     = 0;
            float count = selected.Count();

            // Return immediately from the action so that the GUI can resolve. Displaying a progress bar interrupts the
            // event loop causing a layoutting error.
            EditorApplication.delayCall += () =>
            {
                foreach (var mf in selected)
                {
                    if (mf.sharedMesh == null)
                    {
                        continue;
                    }

                    GameObject go              = mf.gameObject;
                    Mesh       sourceMesh      = mf.sharedMesh;
                    Material[] sourceMaterials = go.GetComponent <MeshRenderer>()?.sharedMaterials;

                    try
                    {
                        var destination  = Undo.AddComponent <ProBuilderMesh>(go);
                        var meshImporter = new MeshImporter(sourceMesh, sourceMaterials, destination);
                        meshImporter.Import(settings);

                        destination.Rebuild();
                        destination.Optimize();

                        i++;
                    }
                    catch (System.Exception e)
                    {
                        Debug.LogWarning("Failed ProBuilderizing: " + go.name + "\n" + e.ToString());
                    }

                    UnityEditor.EditorUtility.DisplayProgressBar("ProBuilderizing", mf.gameObject.name, i / count);
                }

                UnityEditor.EditorUtility.ClearProgressBar();
                MeshSelection.OnObjectSelectionChanged();
                ProBuilderEditor.Refresh();
            };

            if (i < 1)
            {
                return(new ActionResult(ActionResult.Status.Canceled, "Nothing Selected"));
            }
            return(new ActionResult(ActionResult.Status.Success, "ProBuilderize " + i + (i > 1 ? " Objects" : " Object").ToString()));
        }
Exemple #22
0
        public override ActionResult DoAction()
        {
            if (MeshSelection.selectedObjectCount < 1)
            {
                return(ActionResult.NoSelection);
            }

            ActionResult res = ActionResult.NoSelection;

            UndoUtility.RecordSelection("Weld Vertices");

            int weldCount = 0;

            foreach (ProBuilderMesh mesh in MeshSelection.topInternal)
            {
                weldCount += mesh.sharedVerticesInternal.Length;

                if (mesh.selectedIndexesInternal.Length > 1)
                {
                    mesh.ToMesh();

                    int[] welds = mesh.WeldVertices(mesh.selectedIndexesInternal, m_WeldDistance);
                    res = welds != null ? new ActionResult(ActionResult.Status.Success, "Weld Vertices") : new ActionResult(ActionResult.Status.Failure, "Failed Weld Vertices");

                    if (res)
                    {
                        if (mesh.RemoveDegenerateTriangles() != null)
                        {
                            mesh.ToMesh();
                            welds = new int[0]; // @todo
                        }

                        mesh.SetSelectedVertices(welds ?? new int[0] {
                        });
                    }

                    mesh.Refresh();
                    mesh.Optimize();
                }

                weldCount -= mesh.sharedVerticesInternal.Length;
            }

            ProBuilderEditor.Refresh();

            if (res && weldCount > 0)
            {
                return(new ActionResult(ActionResult.Status.Success, "Weld " + weldCount + (weldCount > 1 ? " Vertices" : " Vertex")));
            }

            return(new ActionResult(ActionResult.Status.Failure, "Nothing to Weld"));
        }
        internal override ActionResult EndActivation()
        {
            MenuAction.onPerformAction         -= ActionPerformed;
            ToolManager.activeToolChanging     -= LeaveTool;
            ProBuilderEditor.selectModeChanged -= OnSelectModeChanged;

            Object.DestroyImmediate(m_Tool);

            ProBuilderEditor.Refresh();

            SceneView.RepaintAll();
            return(new ActionResult(ActionResult.Status.Success, "Draw Shape Tool Ends"));
        }
        public static ActionResult MenuRingAndLoopFaces(IEnumerable <ProBuilderMesh> selection)
        {
            UndoUtility.RecordSelection(selection.ToArray(), "Select Face Ring and Loop");

            foreach (ProBuilderMesh pb in selection)
            {
                HashSet <Face> loop = ElementSelection.GetFaceRingAndLoop(pb, pb.selectedFacesInternal);
                pb.SetSelectedFaces(loop);
            }

            ProBuilderEditor.Refresh();
            return(new ActionResult(ActionResult.Status.Success, "Select Face Ring and Loop"));
        }
Exemple #25
0
    public IEnumerator Preferences_IconWindowChanged()
    {
        Assert.That(ProBuilderEditor.s_EditorToolbar, Is.Not.Null);

        Assert.That(ProBuilderEditor.s_EditorToolbar, Is.Not.Null);
        Assert.That(ProBuilderEditor.s_EditorToolbar.isIconMode, Is.EqualTo(m_ShowIconsInitialValue));

        ProBuilderEditor.s_IsIconGui.value = !m_ShowIconsInitialValue;
        ProBuilderEditor.instance.Repaint();
        ProBuilderEditor.Refresh();
        yield return(null);

        Assert.That(ProBuilderEditor.s_EditorToolbar.isIconMode, Is.EqualTo(!m_ShowIconsInitialValue));
    }
        public override ActionResult DoAction()
        {
            if (MeshSelection.selectedObjectCount < 1)
            {
                return(ActionResult.NoSelection);
            }

            UndoUtility.RecordSelection("Select Edge Loop");

            bool foundLoop = false;

            foreach (ProBuilderMesh pb in MeshSelection.topInternal)
            {
                Edge[] loop;
                bool   success = false;

                if (m_SelectIterative)
                {
                    success = ElementSelection.GetEdgeLoopIterative(pb, pb.selectedEdges, out loop);
                }
                else
                {
                    success = ElementSelection.GetEdgeLoop(pb, pb.selectedEdges, out loop);
                }

                if (success)
                {
                    if (loop.Length > pb.selectedEdgeCount)
                    {
                        foundLoop = true;
                    }

                    pb.SetSelectedEdges(loop);
                }
            }

            ProBuilderEditor.Refresh();

            SceneView.RepaintAll();

            if (foundLoop)
            {
                return(new ActionResult(ActionResult.Status.Success, "Select Edge Loop"));
            }
            else
            {
                return(new ActionResult(ActionResult.Status.Failure, "Nothing to Loop"));
            }
        }
        protected override ActionResult PerformActionImplementation()
        {
            if (MeshSelection.selectedObjectCount < 1)
            {
                return(ActionResult.NoSelection);
            }

            UndoUtility.RecordMeshAndTransformSelection("Freeze Transforms");

            var selection = MeshSelection.topInternal;

            Vector3[][] positions = new Vector3[selection.Count][];

            for (int i = 0, c = selection.Count; i < c; i++)
            {
                positions[i] = selection[i].VerticesInWorldSpace();
            }

            for (int i = 0, c = selection.Count; i < c; i++)
            {
                ProBuilderMesh pb        = selection[i];
                bool           flipFaces = ShouldFlipFaces(pb.transform.localScale);

                pb.transform.position   = Vector3.zero;
                pb.transform.rotation   = Quaternion.identity;
                pb.transform.localScale = Vector3.one;

                foreach (Face face in pb.facesInternal)
                {
                    face.manualUV = true;
                    if (flipFaces)
                    {
                        face.Reverse();
                    }
                }

                pb.positions = positions[i];

                pb.ToMesh();
                pb.Refresh();
                pb.Optimize();
            }

            ProBuilderEditor.Refresh();

            SceneView.RepaintAll();

            return(new ActionResult(ActionResult.Status.Success, "Freeze Transforms"));
        }
        /// <summary>
        /// Perform the action.
        /// </summary>
        /// <returns>Return a pb_ActionResult indicating the success/failure of action.</returns>
        public override ActionResult DoAction()
        {
            ShadowCastingMode shadowMode      = (ShadowCastingMode)EditorPrefs.GetInt("pb_CreateShadowObject_shadowMode", (int)ShadowCastingMode.ShadowsOnly);
            float             extrudeDistance = EditorPrefs.GetFloat("pb_CreateShadowObject_volumeSize", .08f);
            ExtrudeMethod     extrudeMethod   = (ExtrudeMethod)EditorPrefs.GetInt("pb_CreateShadowObject_extrudeMethod", (int)ExtrudeMethod.FaceNormal);

            foreach (ProBuilderMesh mesh in MeshSelection.top)
            {
                ProBuilderMesh shadow = GetShadowObject(mesh);

                if (shadow == null)
                {
                    continue;
                }

                foreach (Face f in shadow.faces)
                {
                    f.SetIndexes(f.indexes.Reverse().ToArray());
                    f.manualUV = true;
                }
                shadow.Extrude(shadow.faces, extrudeMethod, extrudeDistance);
                shadow.ToMesh();
                shadow.Refresh();
                shadow.Optimize();

                                #if !UNITY_4_6 && !UNITY_4_7
                MeshRenderer mr = shadow.gameObject.GetComponent <MeshRenderer>();
                mr.shadowCastingMode = shadowMode;
                if (shadowMode == ShadowCastingMode.ShadowsOnly)
                {
                    mr.receiveShadows = false;
                }
                                #endif

                Collider collider = shadow.GetComponent <Collider>();

                while (collider != null)
                {
                    Object.DestroyImmediate(collider);
                    collider = shadow.GetComponent <Collider>();
                }
            }

            // Refresh the Editor wireframe and working caches.
            ProBuilderEditor.Refresh();

            return(new ActionResult(ActionResult.Status.Success, "Create Shadow Object"));
        }
        public override ActionResult DoAction()
        {
            var selection = MeshSelection.topInternal;

            UndoUtility.RecordSelection("Select Face Ring");

            foreach (ProBuilderMesh pb in selection)
            {
                HashSet <Face> loop = ElementSelection.GetFaceLoop(pb, pb.selectedFacesInternal, true);
                pb.SetSelectedFaces(loop);
            }

            ProBuilderEditor.Refresh();

            return(new ActionResult(ActionResult.Status.Success, "Select Face Ring"));
        }
        protected override ActionResult PerformActionImplementation()
        {
            if (MeshSelection.selectedObjectCount < 1)
            {
                return(ActionResult.NoSelection);
            }

            UndoUtility.RecordSelection("Extrude");

            int extrudedFaceCount = 0;

            foreach (ProBuilderMesh mesh in MeshSelection.topInternal)
            {
                mesh.ToMesh();
                mesh.Refresh(RefreshMask.Normals);

                if (mesh.selectedFaceCount < 1)
                {
                    continue;
                }

                extrudedFaceCount += mesh.selectedFaceCount;
                var selectedFaces = mesh.GetSelectedFaces();

                mesh.Extrude(selectedFaces,
                             VertexManipulationTool.s_ExtrudeMethod,
                             m_ExtrudeDistance);

                mesh.SetSelectedFaces(selectedFaces);

                mesh.Rebuild();
                mesh.Optimize();
            }

            ProBuilderEditor.Refresh();

            if (extrudedFaceCount > 0)
            {
                return(new ActionResult(ActionResult.Status.Success, "Extrude"));
            }

            return(new ActionResult(ActionResult.Status.Canceled, "Extrude\nEmpty Selection"));
        }