public override MeshSelection SelectHoles() { MeshSelection selection = new MeshSelection(); foreach (ProBuilderMesh mesh in m_edgeSelection.Meshes) { HashSet <int> indexes = new HashSet <int>(); for (int i = 0; i < mesh.vertexCount; ++i) { indexes.Add(i); } List <List <Edge> > holes = PBElementSelection.FindHoles(mesh, indexes); selection.SelectedEdges.Add(mesh, m_edgeSelection.GetCoincidentEdges(holes.SelectMany(e => e).Where(e => !m_edgeSelection.IsSelected(mesh, e)))); m_edgeSelection.Add(mesh, selection.SelectedEdges[mesh]); } if (!selection.HasEdges) { return(null); } return(selection); }
public override void FillHoles() { int filled = 0; foreach (ProBuilderMesh mesh in m_edgeSelection.Meshes) { //MeshSelection selection = new MeshSelection(); //selection.SelectedEdges.Add(mesh, m_edgeSelection.GetEdges(mesh)); //selection.EdgesToVertices(false); HashSet <int> indexes = new HashSet <int>(); for (int i = 0; i < mesh.vertexCount; ++i) { indexes.Add(i); } List <List <Edge> > holes = PBElementSelection.FindHoles(mesh, indexes); mesh.ToMesh(); List <WingedEdge> wings = WingedEdge.GetWingedEdges(mesh); HashSet <Face> appendedFaces = new HashSet <Face>(); // const bool wholePath = false; foreach (List <Edge> hole in holes) { List <int> holeIndexes; Face face; if (!hole.All(e => m_edgeSelection.IsSelected(mesh, e))) { continue; } //if (wholePath) //{ // // if selecting whole path and in edge mode, make sure the path contains // // at least one complete edge from the selection. // if (!hole.Any(x => common.Contains(x.edge.common.a) && // common.Contains(x.edge.common.b))) // continue; // holeIndexes = hole.Select(x => x.edge.local.a).ToList(); // face = AppendElements.CreatePolygon(mesh, holeIndexes, false); //} //else { //IEnumerable<WingedEdge> selected = hole.Where(x => common.Contains(x.edge.common.a)); //holeIndexes = selected.Select(x => x.edge.local.a).ToList(); //holeIndexes = hole.Select(x => x.edge.local.a).ToList(); //face = AppendElements.CreatePolygon(mesh, holeIndexes, true); holeIndexes = hole.Select(x => x.a).ToList(); face = AppendElements.CreatePolygon(mesh, holeIndexes, true); } if (face != null) { filled++; appendedFaces.Add(face); } } mesh.SetSelectedFaces(appendedFaces); wings = WingedEdge.GetWingedEdges(mesh); // make sure the appended faces match the first adjacent face found // both in winding and face properties foreach (var appendedFace in appendedFaces) { var wing = wings.FirstOrDefault(x => x.face == appendedFace); if (wing == null) { continue; } using (var it = new WingedEdgeEnumerator(wing)) { while (it.MoveNext()) { if (it.Current == null) { continue; } var currentWing = it.Current; var oppositeFace = it.Current.opposite != null ? it.Current.opposite.face : null; if (oppositeFace != null && !appendedFaces.Contains(oppositeFace)) { currentWing.face.submeshIndex = oppositeFace.submeshIndex; currentWing.face.uv = new AutoUnwrapSettings(oppositeFace.uv); PBSurfaceTopology.ConformOppositeNormal(currentWing.opposite); break; } } } } mesh.ToMesh(); mesh.Refresh(); //mesh.Optimize(); } }