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() { 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); }
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")); }
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); }
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() { 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); }
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")); }
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); }
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")); }
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); }
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")); }
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")); }
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")); }
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")); }
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")); }
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")); }
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")); } }
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("Duplicate Face(s)"); if (m_DuplicateFaceSetting == DuplicateFaceSetting.GameObject) { return(DuplicateFacesToObject()); } return(DuplicateFacesToSubmesh()); }
public override ActionResult DoAction() { if (MeshSelection.selectedObjectCount < 1) { return(ActionResult.NoSelection); } UndoUtility.RecordSelection("Detach Face(s)"); if (m_DetachSetting == DetachSetting.GameObject) { return(DetachFacesToObject()); } return(DetachFacesToSubmesh()); }
public override ActionResult DoAction() { if (MeshSelection.selectedObjectCount < 1) { return(ActionResult.NoSelection); } UndoUtility.RecordSelection("Flip Face Normals"); int c = 0; int faceCount = MeshSelection.selectedFaceCount; foreach (ProBuilderMesh pb in MeshSelection.topInternal) { if (pb.selectedFaceCount < 1 && faceCount < 1) { foreach (var face in pb.facesInternal) { face.Reverse(); } c += pb.facesInternal.Length; } else { foreach (var face in pb.GetSelectedFaces()) { face.Reverse(); } c += pb.selectedFaceCount; } pb.ToMesh(); pb.Refresh(); pb.Optimize(); } if (c > 0) { return(new ActionResult(ActionResult.Status.Success, "Flip " + c + (c > 1 ? " Face Normals" : " Face Normal"))); } return(new ActionResult(ActionResult.Status.Canceled, "Flip Normals\nNo Faces Selected")); }
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")); }
protected override ActionResult PerformActionImplementation() { UndoUtility.RecordSelection("Conform Object Normals"); ActionResult res = ActionResult.NoSelection; foreach (ProBuilderMesh pb in MeshSelection.topInternal) { res = UnityEngine.ProBuilder.MeshOperations.SurfaceTopology.ConformNormals(pb, pb.faces); pb.ToMesh(); pb.Refresh(); pb.Optimize(); } ProBuilderEditor.Refresh(); return(res); }
protected override ActionResult PerformActionImplementation() { ActionResult res = ActionResult.NoSelection; UndoUtility.RecordSelection("Triangulate Faces"); foreach (ProBuilderMesh mesh in MeshSelection.topInternal) { mesh.ToMesh(); Face[] triangulatedFaces = mesh.ToTriangles(mesh.selectedFacesInternal); mesh.Refresh(); mesh.Optimize(); mesh.SetSelectedFaces(triangulatedFaces); res = new ActionResult(ActionResult.Status.Success, string.Format("Triangulated {0} {1}", triangulatedFaces.Length, triangulatedFaces.Length < 2 ? "Face" : "Faces")); } ProBuilderEditor.Refresh(); return res; }
public override ActionResult DoAction() { if (MeshSelection.selectedObjectCount < 1) { return(ActionResult.NoSelection); } bool success = false; bool collapseToFirst = m_CollapseToFirst; UndoUtility.RecordSelection("Collapse Vertices"); foreach (var mesh in MeshSelection.topInternal) { if (mesh.selectedIndexesInternal.Length > 1) { int newIndex = mesh.MergeVertices(mesh.selectedIndexesInternal, collapseToFirst); success = newIndex > -1; if (success) { mesh.SetSelectedVertices(new int[] { newIndex }); } mesh.ToMesh(); mesh.Refresh(); mesh.Optimize(); } } ProBuilderEditor.Refresh(); if (success) { return(new ActionResult(ActionResult.Status.Success, "Collapse Vertices")); } return(new ActionResult(ActionResult.Status.Failure, "Collapse Vertices\nNo Vertices Selected")); }
public override ActionResult DoAction() { if (MeshSelection.selectedObjectCount < 1) { return(ActionResult.NoSelection); } int success = 0; UndoUtility.RecordSelection("Subdivide Faces"); foreach (ProBuilderMesh pb in MeshSelection.topInternal) { Face[] faces = pb.Subdivide(pb.selectedFacesInternal); pb.ToMesh(); if (faces != null) { success += pb.selectedFacesInternal.Length; pb.SetSelectedFaces(faces); pb.Refresh(); pb.Optimize(); } } if (success > 0) { ProBuilderEditor.Refresh(); return(new ActionResult(ActionResult.Status.Success, "Subdivide " + success + ((success > 1) ? " faces" : " face"))); } else { Debug.LogWarning("Subdivide faces failed - did you not have any faces selected?"); return(new ActionResult(ActionResult.Status.Failure, "Subdivide Faces\nNo faces selected")); } }
protected override ActionResult PerformActionImplementation() { UndoUtility.RecordSelection("Select Hole"); ActionResult res = ActionResult.NoSelection; foreach (ProBuilderMesh pb in MeshSelection.topInternal) { bool selectAll = pb.selectedIndexesInternal == null || pb.selectedIndexesInternal.Length < 1; IEnumerable <int> indexes = selectAll ? pb.facesInternal.SelectMany(x => x.indexes) : pb.selectedIndexesInternal; List <List <Edge> > holes = ElementSelection.FindHoles(pb, indexes); res = new ActionResult(ActionResult.Status.Success, holes.Count > 0 ? string.Format("{0} holes found", holes.Count) : "No Holes in Selection"); pb.SetSelectedEdges(holes.SelectMany(x => x)); } ProBuilderEditor.Refresh(); return(res); }
public override ActionResult DoAction() { if (MeshSelection.selectedObjectCount < 1) { return(ActionResult.NoSelection); } UndoUtility.RecordSelection("Flip Object Normals"); foreach (ProBuilderMesh pb in MeshSelection.topInternal) { foreach (var face in pb.facesInternal) { face.Reverse(); } pb.ToMesh(); pb.Refresh(); pb.Optimize(); } return(new ActionResult(ActionResult.Status.Success, "Flip Object Normals")); }
public override ActionResult DoAction() { IEnumerable <ProBuilderMesh> selection; if (m_RestrictToSelectedObjects) { selection = MeshSelection.topInternal; } else { selection = Object.FindObjectsOfType <ProBuilderMesh>(); } UndoUtility.RecordSelection("Select Faces with Material"); HashSet <int> sel = new HashSet <int>( MeshSelection.topInternal .SelectMany(x => x.selectedFacesInternal.Select(y => y.submeshIndex))); List <GameObject> newSelection = new List <GameObject>(); foreach (var pb in selection) { IEnumerable <Face> matches = pb.facesInternal.Where(x => sel.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")); }