public static List <ElementGroup> GetElementGroups(ProBuilderMesh mesh, bool collectCoincident)
        {
            var groups     = new List <ElementGroup>();
            var selectMode = ProBuilderEditor.selectMode;

            if (selectMode.ContainsFlag(SelectMode.Vertex | SelectMode.TextureVertex))
            {
                foreach (var list in GetVertexSelectionGroups(mesh, collectCoincident))
                {
                    var pos = PHandleUtility.GetActiveElementPosition(mesh, list);
                    var rot = PHandleUtility.GetVertexRotation(mesh, HandleOrientation.ActiveElement, list);
                    groups.Add(new ElementGroup(list, pos, rot));
                }
            }
            else if (selectMode.ContainsFlag(SelectMode.Edge | SelectMode.TextureEdge))
            {
                foreach (var list in GetEdgeSelectionGroups(mesh))
                {
                    var pos = PHandleUtility.GetActiveElementPosition(mesh, list);
                    var rot = PHandleUtility.GetEdgeRotation(mesh, HandleOrientation.ActiveElement, list);

                    List <int> indices;

                    if (collectCoincident)
                    {
                        indices = new List <int>();
                        mesh.GetCoincidentVertices(list, indices);
                    }
                    else
                    {
                        indices = list.SelectMany(x => new int[] { x.a, x.b }).ToList();
                    }

                    groups.Add(new ElementGroup(indices, pos, rot));
                }
            }
            else if (selectMode.ContainsFlag(SelectMode.Face | SelectMode.TextureFace))
            {
                foreach (var list in GetFaceSelectionGroups(mesh))
                {
                    var        pos = PHandleUtility.GetActiveElementPosition(mesh, list);
                    var        rot = PHandleUtility.GetFaceRotation(mesh, HandleOrientation.ActiveElement, list);
                    List <int> indices;

                    if (collectCoincident)
                    {
                        indices = new List <int>();
                        mesh.GetCoincidentVertices(list, indices);
                    }
                    else
                    {
                        indices = list.SelectMany(x => x.distinctIndexesInternal).ToList();
                    }

                    groups.Add(new ElementGroup(indices, pos, rot));
                }
            }

            return(groups);
        }
        /// <summary>
        /// Called from ProGrids.
        /// </summary>
        /// <param name="snapVal"></param>
        void PushToGrid(float snapVal)
        {
            UndoUtility.RecordSelection(selection.ToArray(), "Push elements to Grid");

            if (selectMode == SelectMode.Object || selectMode == SelectMode.None)
            {
                return;
            }

            for (int i = 0, c = MeshSelection.selectedObjectCount; i < c; i++)
            {
                ProBuilderMesh mesh = selection[i];
                if (mesh.selectedVertexCount < 1)
                {
                    continue;
                }

                var indexes = mesh.GetCoincidentVertices(mesh.selectedIndexesInternal);
                ProGridsSnapping.SnapVertices(mesh, indexes, Vector3.one * snapVal);

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

            UpdateSelection();
        }
Exemple #3
0
        private void VerticesToEdges(bool invert, bool partial)
        {
            SelectedEdges.Clear();
            UnselectedEdges.Clear();

            foreach (KeyValuePair <GameObject, IList <int> > kvp in invert ? UnselectedIndices : SelectedIndices)
            {
                ProBuilderMesh mesh      = kvp.Key.GetComponent <ProBuilderMesh>();
                HashSet <int>  indicesHs = new HashSet <int>(mesh.GetCoincidentVertices(kvp.Value));
                List <Edge>    edges     = GetEdges(mesh, indicesHs, !partial);

                if (edges.Count > 0)
                {
                    SelectedEdges.Add(mesh.gameObject, edges);
                }
            }

            foreach (KeyValuePair <GameObject, IList <int> > kvp in invert ? SelectedIndices : UnselectedIndices)
            {
                ProBuilderMesh mesh      = kvp.Key.GetComponent <ProBuilderMesh>();
                HashSet <int>  indicesHs = new HashSet <int>(mesh.GetCoincidentVertices(kvp.Value));
                List <Edge>    edges     = GetEdges(mesh, indicesHs, !partial);

                if (edges.Count > 0)
                {
                    UnselectedEdges.Add(mesh.gameObject, edges);
                }
            }

            SelectedIndices.Clear();
            UnselectedIndices.Clear();
            SelectedFaces.Clear();
            UnselectedFaces.Clear();
        }
Exemple #4
0
        public void VerticesToFaces(bool invert, bool partial)
        {
            SelectedFaces.Clear();
            UnselectedFaces.Clear();

            foreach (KeyValuePair <ProBuilderMesh, IList <int> > kvp in invert ? UnselectedIndices : SelectedIndices)
            {
                ProBuilderMesh mesh      = kvp.Key;
                HashSet <int>  indicesHs = new HashSet <int>(mesh.GetCoincidentVertices(kvp.Value));
                List <int>     faces     = GetFaces(mesh, indicesHs, !partial);

                if (faces.Count > 0)
                {
                    SelectedFaces.Add(mesh, faces);
                }
            }

            foreach (KeyValuePair <ProBuilderMesh, IList <int> > kvp in invert ? SelectedIndices : UnselectedIndices)
            {
                ProBuilderMesh mesh      = kvp.Key;
                HashSet <int>  indicesHs = new HashSet <int>(mesh.GetCoincidentVertices(kvp.Value));
                List <int>     faces     = GetFaces(mesh, indicesHs, !partial);

                if (faces.Count > 0)
                {
                    UnselectedFaces.Add(mesh, faces);
                }
            }
        }
        public void VerticesToEdges(bool invert)
        {
            SelectedEdges.Clear();
            UnselectedEdges.Clear();

            foreach (KeyValuePair <ProBuilderMesh, IList <int> > kvp in invert ? UnselectedIndices : SelectedIndices)
            {
                ProBuilderMesh mesh      = kvp.Key;
                HashSet <int>  indicesHs = new HashSet <int>(mesh.GetCoincidentVertices(kvp.Value));
                List <Edge>    edges     = GetEdges(mesh, indicesHs);

                if (edges.Count > 0)
                {
                    SelectedEdges.Add(mesh, edges);
                }
            }

            foreach (KeyValuePair <ProBuilderMesh, IList <int> > kvp in invert ? SelectedIndices : UnselectedIndices)
            {
                ProBuilderMesh mesh      = kvp.Key;
                HashSet <int>  indicesHs = new HashSet <int>(mesh.GetCoincidentVertices(kvp.Value));
                List <Edge>    edges     = GetEdges(mesh, indicesHs);

                if (edges.Count > 0)
                {
                    UnselectedEdges.Add(mesh, edges);
                }
            }
        }
        public override MeshSelection Select(Camera camera, Rect rect, Rect uiRootRect, GameObject[] gameObjects, bool depthTest, MeshEditorSelectionMode mode)
        {
            Dictionary <ProBuilderMesh, HashSet <int> > pickResult = PBUtility.PickVertices(camera, rect, uiRootRect, gameObjects, depthTest);

            if (pickResult.Count == 0)
            {
                return(null);
            }

            MeshSelection selection = new MeshSelection();

            foreach (KeyValuePair <ProBuilderMesh, HashSet <int> > kvp in pickResult)
            {
                ProBuilderMesh       mesh           = kvp.Key;
                HashSet <int>        sharedIndexes  = kvp.Value;
                IList <SharedVertex> sharedVertices = mesh.sharedVertices;

                HashSet <int> indices = new HashSet <int>();
                foreach (int sharedIndex in sharedIndexes)
                {
                    SharedVertex sharedVertex = sharedVertices[sharedIndex];
                    for (int j = 0; j < sharedVertex.Count; ++j)
                    {
                        if (!indices.Contains(sharedVertex[j]))
                        {
                            indices.Add(sharedVertex[j]);
                        }
                    }
                }

                if (mode == MeshEditorSelectionMode.Substract || mode == MeshEditorSelectionMode.Difference)
                {
                    IList <int> selected = mesh.GetCoincidentVertices(indices).Where(index => m_vertexSelection.IsSelected(mesh, index)).ToArray();
                    selection.UnselectedIndices.Add(mesh.gameObject, selected);
                    m_vertexSelection.Remove(mesh, selected);
                }

                if (mode == MeshEditorSelectionMode.Add || mode == MeshEditorSelectionMode.Difference)
                {
                    IList <int> notSelected = mesh.GetCoincidentVertices(indices).Where(index => !m_vertexSelection.IsSelected(mesh, index)).ToArray();
                    selection.SelectedIndices.Add(mesh.gameObject, notSelected);
                    m_vertexSelection.Add(mesh, notSelected);
                }
            }
            return(selection);
        }
Exemple #7
0
        private static void GetCoindicentIndices(KeyValuePair <GameObject, IList <Edge> > kvp, out ProBuilderMesh mesh, out List <int> indices)
        {
            mesh = kvp.Key.GetComponent <ProBuilderMesh>();
            IList <Edge> edges = kvp.Value;

            indices = new List <int>();
            mesh.GetCoincidentVertices(edges, indices);
        }
        private static void GetCoindicentIndices(KeyValuePair <ProBuilderMesh, IList <Face> > kvp, out ProBuilderMesh mesh, out List <int> indices)
        {
            mesh = kvp.Key;
            IList <Face> faces = kvp.Value;

            indices = new List <int>();
            mesh.GetCoincidentVertices(faces, indices);
        }
Exemple #9
0
            public MeshState(ProBuilderMesh mesh, IList <int> selectedIndices)
            {
                vertices = mesh.positions.ToArray();
                indices  = mesh.GetCoincidentVertices(selectedIndices);
                origins  = new Vector3[indices.Count];

                for (int i = 0, c = indices.Count; i < c; i++)
                {
                    origins[i] = vertices[indices[i]];
                }
            }
        internal static List <int> GetSelectedIndicesForSelectMode(ProBuilderMesh mesh, SelectMode mode, bool collectCoincident)
        {
            if (mode.ContainsFlag(SelectMode.Face | SelectMode.TextureFace))
            {
                List <int> indices = new List <int>();

                if (collectCoincident)
                {
                    mesh.GetCoincidentVertices(mesh.selectedFacesInternal, indices);
                }
                else
                {
                    Face.GetDistinctIndices(mesh.selectedFacesInternal, indices);
                }

                return(indices);
            }
            else if (mode.ContainsFlag(SelectMode.Edge | SelectMode.TextureEdge))
            {
                List <int> indices = new List <int>();

                if (collectCoincident)
                {
                    mesh.GetCoincidentVertices(mesh.selectedEdgesInternal, indices);
                }
                else
                {
                    Edge.GetIndices(mesh.selectedEdgesInternal, indices);
                }

                return(indices);
            }

            return(collectCoincident
                ? mesh.GetCoincidentVertices(mesh.selectedIndexesInternal)
                : new List <int>(mesh.selectedIndexesInternal));
        }
 private void SetVerticesColor(ProBuilderMesh mesh, MeshFilter vertices, Color color, IEnumerable <int> indices)
 {
     if (IsGeometryShadersSupported)
     {
         List <int> coincident = new List <int>();
         foreach (int index in indices)
         {
             mesh.GetCoincidentVertices(index, coincident);
             Color[] colors = vertices.sharedMesh.colors;
             for (int i = 0; i < coincident.Count; ++i)
             {
                 colors[coincident[i]] = color;
             }
             vertices.sharedMesh.colors = colors;
             coincident.Clear();
         }
     }
     else
     {
         List <int> coincident = new List <int>();
         foreach (int index in indices)
         {
             mesh.GetCoincidentVertices(index, coincident);
             Color[] colors = vertices.sharedMesh.colors;
             for (int i = 0; i < coincident.Count; ++i)
             {
                 colors[coincident[i] * 4]     = color;
                 colors[coincident[i] * 4 + 1] = color;
                 colors[coincident[i] * 4 + 2] = color;
                 colors[coincident[i] * 4 + 3] = color;
             }
             vertices.sharedMesh.colors = colors;
             coincident.Clear();
         }
     }
 }
        static IEnumerable <List <int> > GetVertexSelectionGroups(ProBuilderMesh mesh, bool collectCoincident)
        {
            if (!collectCoincident)
            {
                return(mesh.selectedIndexesInternal.Select(x => new List <int>()
                {
                    x
                }).ToList());
            }

            var shared = mesh.selectedSharedVertices;

            var groups   = new List <List <int> >();
            var groupIdx = -1;
            var i        = -1;

            foreach (var index in shared)
            {
                var coincident = new List <int>();
                mesh.GetCoincidentVertices(mesh.sharedVerticesInternal[index][0], coincident);
                groups.Add(coincident);
                i++;
                // Make sure the last selected vertic is the last in the group
                var idx = coincident.IndexOf(mesh.selectedIndexesInternal[mesh.selectedIndexesInternal.Length - 1]);
                if (idx != -1 && idx < coincident.Count)
                {
                    var item = coincident[idx];
                    groupIdx        = i;
                    coincident[idx] = coincident[coincident.Count - 1];
                    coincident[coincident.Count - 1] = item;
                }
            }

            // Make sure the last selected vertic's group is the last in the groups
            if (groupIdx != -1 && groupIdx < groups.Count)
            {
                var item = groups[groupIdx];
                groups[groupIdx]         = groups[groups.Count - 1];
                groups[groups.Count - 1] = item;
            }

            return(groups);
        }
        static IEnumerable <List <int> > GetVertexSelectionGroups(ProBuilderMesh mesh, bool collectCoincident)
        {
            if (!collectCoincident)
            {
                return(mesh.selectedIndexesInternal.Select(x => new List <int>()
                {
                    x
                }).ToList());
            }

            var shared = mesh.selectedSharedVertices;

            var groups = new List <List <int> >();

            foreach (var index in shared)
            {
                var coincident = new List <int>();
                mesh.GetCoincidentVertices(mesh.sharedVerticesInternal[index][0], coincident);
                groups.Add(coincident);
            }

            return(groups);
        }
        public static List <ElementGroup> GetElementGroups(ProBuilderMesh mesh, PivotPoint pivot, HandleOrientation orientation, bool collectCoincident)
        {
            var groups     = new List <ElementGroup>();
            var trs        = mesh.transform.localToWorldMatrix;
            var selectMode = ProBuilderEditor.selectMode;

            switch (pivot)
            {
            case PivotPoint.IndividualOrigins:
            {
                if (selectMode.ContainsFlag(SelectMode.Vertex | SelectMode.TextureVertex))
                {
                    foreach (var list in GetVertexSelectionGroups(mesh, collectCoincident))
                    {
                        var bounds = Math.GetBounds(mesh.positionsInternal, list);
                        var rot    = UnityEngine.ProBuilder.HandleUtility.GetVertexRotation(mesh, orientation, list);
                        groups.Add(new ElementGroup(list, trs.MultiplyPoint3x4(bounds.center), rot));
                    }
                }
                else if (selectMode.ContainsFlag(SelectMode.Edge | SelectMode.TextureEdge))
                {
                    foreach (var list in GetEdgeSelectionGroups(mesh))
                    {
                        var bounds = Math.GetBounds(mesh.positionsInternal, list);
                        var rot    = UnityEngine.ProBuilder.HandleUtility.GetEdgeRotation(mesh, orientation, list);

                        List <int> indices;

                        if (collectCoincident)
                        {
                            indices = new List <int>();
                            mesh.GetCoincidentVertices(list, indices);
                        }
                        else
                        {
                            indices = list.SelectMany(x => new int[] { x.a, x.b }).ToList();
                        }

                        groups.Add(new ElementGroup(indices, trs.MultiplyPoint3x4(bounds.center), rot));
                    }
                }
                else if (selectMode.ContainsFlag(SelectMode.Face | SelectMode.TextureFace))
                {
                    foreach (var list in GetFaceSelectionGroups(mesh))
                    {
                        var        bounds = Math.GetBounds(mesh.positionsInternal, list);
                        var        rot    = UnityEngine.ProBuilder.HandleUtility.GetFaceRotation(mesh, orientation, list);
                        List <int> indices;

                        if (collectCoincident)
                        {
                            indices = new List <int>();
                            mesh.GetCoincidentVertices(list, indices);
                        }
                        else
                        {
                            indices = list.SelectMany(x => x.distinctIndexesInternal).ToList();
                        }

                        groups.Add(new ElementGroup(indices, trs.MultiplyPoint3x4(bounds.center), rot));
                    }
                }
                break;
            }

            case PivotPoint.ActiveElement:
            {
                var indices  = GetSelectedIndicesForSelectMode(mesh, selectMode, collectCoincident);
                var position = mesh.transform.position;
                var rotation = mesh.transform.rotation;

                if (selectMode.ContainsFlag(SelectMode.Face | SelectMode.TextureFace))
                {
                    var face = mesh.GetActiveFace();

                    if (face != null)
                    {
                        position = trs.MultiplyPoint3x4(Math.GetBounds(mesh.positionsInternal, face.distinctIndexesInternal).center);
                        rotation = UnityEngine.ProBuilder.HandleUtility.GetFaceRotation(mesh, orientation, new Face[] { face });
                    }
                }
                else if (selectMode.ContainsFlag(SelectMode.Edge | SelectMode.TextureEdge))
                {
                    var edge = mesh.GetActiveEdge();

                    if (edge != Edge.Empty)
                    {
                        position = trs.MultiplyPoint3x4(Math.GetBounds(mesh.positionsInternal, new int [] { edge.a, edge.b }).center);
                        rotation = UnityEngine.ProBuilder.HandleUtility.GetEdgeRotation(mesh, orientation, new Edge[] { edge });
                    }
                }
                else if (selectMode.ContainsFlag(SelectMode.Vertex | SelectMode.TextureVertex))
                {
                    var vertex = mesh.GetActiveVertex();

                    if (vertex > -1)
                    {
                        position = trs.MultiplyPoint3x4(mesh.positionsInternal[vertex]);
                        rotation = UnityEngine.ProBuilder.HandleUtility.GetVertexRotation(mesh, orientation, new int[] { vertex });
                    }
                }

                groups.Add(new ElementGroup(indices, position, rotation));
                break;
            }

            default:
            {
                var indices  = GetSelectedIndicesForSelectMode(mesh, selectMode, collectCoincident);
                var position = MeshSelection.bounds.center;
                var rotation = Quaternion.identity;

                if (selectMode.ContainsFlag(SelectMode.Face | SelectMode.TextureFace))
                {
                    var face = mesh.GetActiveFace();

                    if (face != null)
                    {
                        rotation = UnityEngine.ProBuilder.HandleUtility.GetFaceRotation(mesh, orientation, new Face[] { face });
                    }
                }
                else if (selectMode.ContainsFlag(SelectMode.Edge | SelectMode.TextureEdge))
                {
                    var edge = mesh.GetActiveEdge();

                    if (edge != Edge.Empty)
                    {
                        rotation = UnityEngine.ProBuilder.HandleUtility.GetEdgeRotation(mesh, orientation, new Edge[] { edge });
                    }
                }
                else if (selectMode.ContainsFlag(SelectMode.Vertex | SelectMode.TextureVertex))
                {
                    var vertex = mesh.GetActiveVertex();

                    if (vertex > -1)
                    {
                        rotation = UnityEngine.ProBuilder.HandleUtility.GetVertexRotation(mesh, orientation, new int[] { vertex });
                    }
                }

                groups.Add(new ElementGroup(indices, position, rotation));
                break;
            }
            }

            return(groups);
        }
Exemple #15
0
 public ExtrudedSelection(ProBuilderMesh mesh, Face face)
 {
     indices = mesh.GetCoincidentVertices(face.distinctIndexes);
     normal  = Math.Normal(mesh, face);
 }