void AutoWeld() { // Automatically weld any vertices that have been brought too close together if (primaryTargetBrush != null && selectedVertices.Count > 0) { float autoWeldTolerance = 0.001f; Dictionary <Brush, List <Vertex> > refinedSelections = new Dictionary <Brush, List <Vertex> >(); foreach (PrimitiveBrush brush in targetBrushes) { refinedSelections.Add(brush, SelectedVerticesOfBrush(brush)); } bool selectionCleared = false; foreach (PrimitiveBrush brush in targetBrushes) { Polygon[] sourcePolygons = brush.GetPolygons().DeepCopy(); List <Vertex> allVertices = new List <Vertex>(); for (int i = 0; i < sourcePolygons.Length; i++) { allVertices.AddRange(sourcePolygons[i].Vertices); } Polygon[] newPolygons = VertexUtility.WeldNearbyVertices(autoWeldTolerance, sourcePolygons, allVertices); if (newPolygons != null && newPolygons.Length != sourcePolygons.Length) { Undo.RecordObject(brush.transform, "Auto Weld Vertices"); Undo.RecordObject(brush, "Auto Weld Vertices"); if (!selectionCleared) { ClearSelection(); selectionCleared = true; } brush.SetPolygons(newPolygons); SelectVertices(brush, newPolygons, refinedSelections[brush]); } } } }
void OnToolbarGUI(int windowID) { GUILayout.Label("Vertex", SabreGUILayout.GetTitleStyle()); // Button should only be enabled if there are any vertices selected GUI.enabled = selectedVertices.Count > 0; if (GUILayout.Button("Connect", EditorStyles.miniButton)) { if (selectedVertices != null) { // Cache selection Dictionary <Brush, List <Vertex> > refinedSelections = new Dictionary <Brush, List <Vertex> >(); foreach (PrimitiveBrush brush in targetBrushes) { refinedSelections.Add(brush, SelectedVerticesOfBrush(brush)); } ClearSelection(); foreach (PrimitiveBrush brush in targetBrushes) { Undo.RecordObject(brush.transform, "Connect Vertices"); Undo.RecordObject(brush, "Connect Vertices"); List <Edge> newEdges; // Polygon[] newPolygons = VertexUtility.ConnectVertices(brush.GetPolygons(), refinedSelections[brush], out newEdge); Polygon[] newPolygons = VertexUtility.ConnectVertices(brush.GetPolygons(), refinedSelections[brush], out newEdges); if (newPolygons != null) { brush.SetPolygons(newPolygons); for (int i = 0; i < newEdges.Count; i++) { SelectEdges(brush, newPolygons, newEdges[i]); } } } } } if (GUILayout.Button("Weld Selection To Mid-Point", EditorStyles.miniButton)) { if (selectedVertices != null) { Dictionary <Brush, List <Vertex> > refinedSelections = new Dictionary <Brush, List <Vertex> >(); foreach (PrimitiveBrush brush in targetBrushes) { refinedSelections.Add(brush, SelectedVerticesOfBrush(brush)); } ClearSelection(); foreach (PrimitiveBrush brush in targetBrushes) { Undo.RecordObject(brush.transform, "Weld Vertices"); Undo.RecordObject(brush, "Weld Vertices"); Polygon[] newPolygons = VertexUtility.WeldVerticesToCenter(brush.GetPolygons(), refinedSelections[brush]); if (newPolygons != null) { brush.SetPolygons(newPolygons); } SelectVertices(brush, newPolygons, refinedSelections[brush]); } } } EditorGUILayout.BeginHorizontal(); weldTolerance = EditorGUILayout.FloatField(weldTolerance); if (GUILayout.Button("Weld with Tolerance", EditorStyles.miniButton)) { if (selectedVertices != null) { Dictionary <Brush, List <Vertex> > refinedSelections = new Dictionary <Brush, List <Vertex> >(); foreach (PrimitiveBrush brush in targetBrushes) { refinedSelections.Add(brush, SelectedVerticesOfBrush(brush)); } ClearSelection(); foreach (PrimitiveBrush brush in targetBrushes) { Undo.RecordObject(brush.transform, "Weld Vertices"); Undo.RecordObject(brush, "Weld Vertices"); Polygon[] newPolygons = VertexUtility.WeldNearbyVertices(weldTolerance, brush.GetPolygons(), refinedSelections[brush]); if (newPolygons != null) { brush.SetPolygons(newPolygons); } SelectVertices(brush, newPolygons, refinedSelections[brush]); } } } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Global Snap", EditorStyles.miniButton)) { foreach (PrimitiveBrush brush in targetBrushes) { Undo.RecordObject(brush.transform, "Snap Vertices"); Undo.RecordObject(brush, "Snap Vertices"); } SnapSelectedVertices(true); } if (GUILayout.Button("Local Snap", EditorStyles.miniButton)) { foreach (PrimitiveBrush brush in targetBrushes) { Undo.RecordObject(brush.transform, "Snap Vertices"); Undo.RecordObject(brush, "Snap Vertices"); } SnapSelectedVertices(false); } EditorGUILayout.EndHorizontal(); GUILayout.Label("Edge", SabreGUILayout.GetTitleStyle()); GUI.enabled = selectedEdges.Count > 0; if (GUILayout.Button("Connect Mid-Points", EditorStyles.miniButton)) { if (selectedEdges != null) { List <Edge> selectedEdgesCopy = new List <Edge>(selectedEdges); ClearSelection(); foreach (PrimitiveBrush brush in targetBrushes) { Undo.RecordObject(brush.transform, "Connect Mid-Points"); Undo.RecordObject(brush, "Connect Mid-Points"); Polygon[] newPolygons; List <Edge> newEdges; if (EdgeUtility.SplitPolygonsByEdges(brush.GetPolygons(), selectedEdgesCopy, out newPolygons, out newEdges)) { brush.SetPolygons(newPolygons); for (int i = 0; i < newEdges.Count; i++) { SelectEdges(brush, newPolygons, newEdges[i]); } } } } } if (GUILayout.Button("Split", EditorStyles.miniButton)) { if (selectedEdges != null) { List <KeyValuePair <Vertex, Brush> > newSelectedVertices = new List <KeyValuePair <Vertex, Brush> >(); foreach (PrimitiveBrush brush in targetBrushes) { Undo.RecordObject(brush.transform, "Split Edge"); Undo.RecordObject(brush, "Split Edge"); Polygon[] polygons = brush.GetPolygons(); for (int j = 0; j < selectedEdges.Count; j++) { // First check if this edge actually belongs to the brush Brush parentBrush = selectedVertices[selectedEdges[j].Vertex1]; if (parentBrush == brush) { for (int i = 0; i < polygons.Length; i++) { Vertex newVertex; if (EdgeUtility.SplitPolygonAtEdge(polygons[i], selectedEdges[j], out newVertex)) { newSelectedVertices.Add(new KeyValuePair <Vertex, Brush>(newVertex, brush)); } } } } brush.Invalidate(true); } ClearSelection(); for (int i = 0; i < newSelectedVertices.Count; i++) { Brush brush = newSelectedVertices[i].Value; Vertex vertex = newSelectedVertices[i].Key; SelectVertices(brush, brush.GetPolygons(), new List <Vertex>() { vertex }); } } } }
List <PrimitiveBrush> AutoWeld() { // Track the brushes that welding has changed List <PrimitiveBrush> changedBrushes = new List <PrimitiveBrush>(); // Automatically weld any vertices that have been brought too close together if (primaryTargetBrush != null && selectedVertices.Count > 0) { float autoWeldTolerance = 0.001f; Dictionary <Brush, List <Vertex> > refinedSelections = new Dictionary <Brush, List <Vertex> >(); foreach (PrimitiveBrush brush in targetBrushes) { refinedSelections.Add(brush, SelectedVerticesOfBrush(brush)); } bool selectionCleared = false; foreach (PrimitiveBrush brush in targetBrushes) { Polygon[] sourcePolygons = brush.GetPolygons(); // Make a copy so that we can differentiate newPolygons from the original, since welding updates affected polygons in place Polygon[] sourcePolygonsCopy = sourcePolygons.DeepCopy(); List <Vertex> allVertices = new List <Vertex>(); for (int i = 0; i < sourcePolygonsCopy.Length; i++) { allVertices.AddRange(sourcePolygonsCopy[i].Vertices); } Polygon[] newPolygons = VertexUtility.WeldNearbyVertices(autoWeldTolerance, sourcePolygonsCopy, allVertices); bool hasChanged = false; if (newPolygons.Length != sourcePolygons.Length) { hasChanged = true; } if (!hasChanged) { for (int i = 0; i < sourcePolygons.Length; i++) { if (sourcePolygons[i].Vertices.Length != newPolygons[i].Vertices.Length) { hasChanged = true; break; } } } if (hasChanged) { Undo.RecordObject(brush.transform, "Auto Weld Vertices"); Undo.RecordObject(brush, "Auto Weld Vertices"); if (!selectionCleared) { ClearSelection(); selectionCleared = true; } brush.SetPolygons(newPolygons); SelectVertices(brush, newPolygons, refinedSelections[brush]); // Brush has changed so mark it to be returned changedBrushes.Add(brush); } } } // Return the brushes that welding has changed return(changedBrushes); }