Esempio n. 1
0
        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]);
                    }
                }
            }
        }
        public override void OnInspectorGUI()
        {
            float drawableWidth = EditorGUIUtility.currentViewWidth;

            drawableWidth -= 42;             // Take some off for scroll bars and padding

            PrimitiveBrushType[] selectedTypes = BrushTargets.Select(item => ((PrimitiveBrush)item).BrushType).ToArray();

            PrimitiveBrushType?activeType = (selectedTypes.Length == 1) ? (PrimitiveBrushType?)selectedTypes[0] : null;

            using (new NamedVerticalScope("Type"))
            {
                GUILayout.BeginHorizontal();

                float areaWidth          = drawableWidth - 18;
                int   buttonWidth        = Mathf.RoundToInt(areaWidth / 5f);
                int   stretchButtonWidth = Mathf.RoundToInt(areaWidth - buttonWidth * 4); // To ensure a justified alignment one button must be stretched slightly
                int   buttonHeight       = 50;

                GUIStyle brushButtonStyle = new GUIStyle(GUI.skin.button);
                brushButtonStyle.imagePosition = ImagePosition.ImageAbove;
                brushButtonStyle.fontSize      = 10;

                GUIStyle labelStyle = new GUIStyle(GUI.skin.label);
                labelStyle.alignment = TextAnchor.LowerCenter;
                labelStyle.fontSize  = brushButtonStyle.fontSize;

                bool shortMode = (areaWidth < 260); // Whether certain words need to be abbreviated to fit in the box

                DrawBrushButton(PrimitiveBrushType.Cube, activeType, brushButtonStyle, labelStyle, buttonWidth, buttonHeight, shortMode);
                DrawBrushButton(PrimitiveBrushType.Prism, activeType, brushButtonStyle, labelStyle, buttonWidth, buttonHeight, shortMode);
                DrawBrushButton(PrimitiveBrushType.Cylinder, activeType, brushButtonStyle, labelStyle, stretchButtonWidth, buttonHeight, shortMode);
                DrawBrushButton(PrimitiveBrushType.Sphere, activeType, brushButtonStyle, labelStyle, buttonWidth, buttonHeight, shortMode);
                DrawBrushButton(PrimitiveBrushType.IcoSphere, activeType, brushButtonStyle, labelStyle, buttonWidth, buttonHeight, shortMode);

                GUILayout.EndHorizontal();
                GUILayout.BeginHorizontal();

                DrawBrushButton(PrimitiveBrushType.Cone, activeType, brushButtonStyle, labelStyle, buttonWidth, buttonHeight, shortMode);

                GUI.enabled = true; // Reset GUI enabled so that the next items aren't disabled
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();

                if (activeType.HasValue)
                {
                    GUILayout.Label("Active: " + selectedTypes[0]);
                }
                else
                {
                    GUILayout.Label("Active: Mixed");
                }

                if (activeType.HasValue)
                {
                    EditorGUIUtility.labelWidth = 60;
                    EditorGUIUtility.fieldWidth = 50;
                    EditorGUI.BeginChangeCheck();
                    if (activeType.Value == PrimitiveBrushType.Prism)
                    {
                        EditorGUILayout.PropertyField(prismSideCountProp, new GUIContent("Sides"));
                    }
                    else if (activeType.Value == PrimitiveBrushType.Cylinder)
                    {
                        EditorGUILayout.PropertyField(cylinderSideCountProp, new GUIContent("Sides"));
                    }
                    else if (activeType.Value == PrimitiveBrushType.Sphere)
                    {
                        EditorGUILayout.PropertyField(sphereSideCountProp, new GUIContent("Sides"));
                    }
                    else if (activeType.Value == PrimitiveBrushType.IcoSphere)
                    {
                        EditorGUILayout.PropertyField(icoSphereIterationCountProp, new GUIContent("Iterations"));
                    }
                    else if (activeType.Value == PrimitiveBrushType.Cone)
                    {
                        EditorGUILayout.PropertyField(coneSideCountProp, new GUIContent("Sides"));
                    }
                    if (EditorGUI.EndChangeCheck())
                    {
                        // One of the properties has changed
                        serializedObject.ApplyModifiedProperties();
                        ResetPolygonsKeepScale();
                    }
                }

                GUILayout.EndHorizontal();
            }

            using (new NamedVerticalScope("Size"))
            {
                if (GUILayout.Button(new GUIContent("Reset Bounds", "Resets the bounds of the brush to [2,2,2]")))
                {
                    ResetBounds();
                }

                GUILayout.BeginHorizontal();

                GUI.SetNextControlName("rescaleTextbox");

                scaleString = EditorGUILayout.TextField(scaleString);

                bool keyboardEnter = Event.current.isKey &&
                                     Event.current.keyCode == KeyCode.Return &&
                                     Event.current.type == EventType.KeyUp &&
                                     GUI.GetNameOfFocusedControl() == "rescaleTextbox";

                if (GUILayout.Button("Scale", GUILayout.MaxWidth(drawableWidth / 3f)) || keyboardEnter)
                {
                    // Try to parse a Vector3 scale from the input string
                    Vector3 scaleVector3;
                    if (StringHelper.TryParseScale(scaleString, out scaleVector3))
                    {
                        // None of the scale components can be zero
                        if (scaleVector3.x != 0 && scaleVector3.y != 0 && scaleVector3.z != 0)
                        {
                            // Rescale all the brushes
                            Undo.RecordObjects(targets, "Scale Polygons");
                            foreach (var thisBrush in targets)
                            {
                                BrushUtility.Scale((PrimitiveBrush)thisBrush, scaleVector3);
                            }
                        }
                    }
                }

                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();

                GUI.SetNextControlName("resizeTextbox");

                resizeString = EditorGUILayout.TextField(resizeString);

                keyboardEnter = Event.current.isKey &&
                                Event.current.keyCode == KeyCode.Return &&
                                Event.current.type == EventType.KeyUp &&
                                GUI.GetNameOfFocusedControl() == "resizeTextbox";

                if (GUILayout.Button("Resize", GUILayout.MaxWidth(drawableWidth / 3f)) || keyboardEnter)
                {
                    // Try to parse a Vector3 scale from the input string
                    Vector3 resizeVector3;
                    if (StringHelper.TryParseScale(resizeString, out resizeVector3))
                    {
                        // None of the size components can be zero
                        if (resizeVector3.x != 0 && resizeVector3.y != 0 && resizeVector3.z != 0)
                        {
                            // Rescale all the brushes so that the local bounds is the same size as the resize vector
                            Undo.RecordObjects(targets, "Resize Polygons");
                            PrimitiveBrush[] brushes = BrushTargets.Cast <PrimitiveBrush>().ToArray();
                            foreach (PrimitiveBrush brush in brushes)
                            {
                                BrushUtility.Resize(brush, resizeVector3);
                            }
                        }
                    }
                }

                GUILayout.EndHorizontal();
            }

            using (new NamedVerticalScope("Rotation"))
            {
                GUILayout.Label("Align up direction", EditorStyles.boldLabel);
                GUILayout.BeginHorizontal();
                if (GUILayout.Button("X"))
                {
                    AlignUpToAxis(new Vector3(1, 0, 0), false);
                }
                if (GUILayout.Button("Y"))
                {
                    AlignUpToAxis(new Vector3(0, 1, 0), false);
                }
                if (GUILayout.Button("Z"))
                {
                    AlignUpToAxis(new Vector3(0, 0, 1), false);
                }
                GUILayout.EndHorizontal();

                GUILayout.Label("Align up direction (keep positions)", EditorStyles.boldLabel);

                GUILayout.BeginHorizontal();
                if (GUILayout.Button("X"))
                {
                    AlignUpToAxis(new Vector3(1, 0, 0), true);
                }
                if (GUILayout.Button("Y"))
                {
                    AlignUpToAxis(new Vector3(0, 1, 0), true);
                }
                if (GUILayout.Button("Z"))
                {
                    AlignUpToAxis(new Vector3(0, 0, 1), true);
                }
                GUILayout.EndHorizontal();
            }

            using (new NamedVerticalScope("Misc"))
            {
                // Import Row
                GUILayout.BeginHorizontal();
                sourceMesh = EditorGUILayout.ObjectField(sourceMesh, typeof(Mesh), false) as Mesh;

                if (GUILayout.Button("Import", GUILayout.MaxWidth(drawableWidth / 3f)))
                {
                    if (sourceMesh != null)
                    {
                        Undo.RecordObjects(targets, "Import Polygons From Mesh");

                        Polygon[] polygons = BrushFactory.GeneratePolygonsFromMesh(sourceMesh).ToArray();
                        bool      convex   = GeometryHelper.IsBrushConvex(polygons);
                        if (!convex)
                        {
                            Debug.LogError("Concavities detected in imported mesh. This may result in issues during CSG, please change the source geometry so that it is convex");
                        }
                        foreach (var thisBrush in targets)
                        {
                            ((PrimitiveBrush)thisBrush).SetPolygons(polygons, true);
                        }
                    }
                }

                GUILayout.EndHorizontal();

                // Shell Row
                GUILayout.BeginHorizontal();

                if (shellDistance == 0)
                {
                    shellDistance = CurrentSettings.PositionSnapDistance;
                }

                shellDistance = EditorGUILayout.FloatField("Distance", shellDistance);

                if (GUILayout.Button("Shell", GUILayout.MaxWidth(drawableWidth / 3f)))
                {
                    List <GameObject> newSelection = new List <GameObject>();
                    foreach (var thisBrush in targets)
                    {
                        GameObject newObject = ((PrimitiveBrush)thisBrush).Duplicate();
                        Polygon[]  polygons  = newObject.GetComponent <PrimitiveBrush>().GetPolygons();
                        VertexUtility.DisplacePolygons(polygons, -shellDistance);
                        Bounds newBounds = newObject.GetComponent <PrimitiveBrush>().GetBounds();
                        // Verify the new geometry
                        if (GeometryHelper.IsBrushConvex(polygons) &&
                            newBounds.GetSmallestExtent() > 0)
                        {
                            Undo.RegisterCreatedObjectUndo(newObject, "Shell");
                            newSelection.Add(newObject);
                        }
                        else
                        {
                            // Produced a concave brush, delete it and pretend nothing happened
                            GameObject.DestroyImmediate(newObject);
                            Debug.LogWarning("Could not shell " + thisBrush.name + " as shelled geometry would not be valid. Try lowering the shell distance and attempt Shell again.");
                        }
                    }

                    if (newSelection.Count > 0)
                    {
                        Selection.objects = newSelection.ToArray();
                    }
                }

                GUILayout.EndHorizontal();

                // Split Intersecting Row
                if (GUILayout.Button("Split Intersecting Brushes"))
                {
                    // Chop up the intersecting brushes by the brush planes, ideally into as few new brushes as possible

                    PrimitiveBrush[] brushes = BrushTargets.Cast <PrimitiveBrush>().ToArray();

                    BrushUtility.SplitIntersecting(brushes);
                }


                //			BrushOrder brushOrder = BrushTarget.GetBrushOrder();
                //			string positionString = string.Join(",", brushOrder.Position.Select(item => item.ToString()).ToArray());
                //            GUILayout.Label(positionString, EditorStyles.boldLabel);

                //List<BrushCache> intersections = ((PrimitiveBrush)BrushTarget).BrushCache.IntersectingVisualBrushCaches;
                //GUILayout.Label("Intersecting brushes " + intersections.Count, EditorStyles.boldLabel);

                //for (int i = 0; i < intersections.Count; i++)
                //{
                //    GUILayout.Label(intersections[i].Mode.ToString(), EditorStyles.boldLabel);
                //}
            }

            base.OnInspectorGUI();
        }
Esempio n. 3
0
        public void DrawBrushTypeField()
        {
            GUILayout.BeginHorizontal();
            PrimitiveBrushType[] selectedTypes = BrushTargets.Select(item => item.BrushType).ToArray();

            if (overridenBrushType.HasValue)
            {
                selectedTypes = new PrimitiveBrushType[] { overridenBrushType.Value };
            }

            PrimitiveBrushType?newType = SabreGUILayout.EnumPopupMixed("Brush Type", selectedTypes);

            if (newType.HasValue)
            {
                overridenBrushType = newType;

                if (newType.Value == PrimitiveBrushType.Prism)
                {
                    GUILayout.Label("Sides", SabreGUILayout.GetForeStyle(), GUILayout.Width(30));
                    EditorGUILayout.PropertyField(prismSideCountProp, new GUIContent(""));
                    GUILayout.EndHorizontal();

                    GUILayout.BeginHorizontal();
                }
                else if (newType.Value == PrimitiveBrushType.Cylinder)
                {
                    GUILayout.Label("Sides", SabreGUILayout.GetForeStyle(), GUILayout.Width(30));
                    EditorGUILayout.PropertyField(cylinderSideCountProp, new GUIContent(""));
                    GUILayout.EndHorizontal();

                    GUILayout.BeginHorizontal();
                }

                else if (newType.Value == PrimitiveBrushType.Sphere)
                {
                    GUILayout.Label("Sides", SabreGUILayout.GetForeStyle(), GUILayout.Width(30));
                    EditorGUILayout.PropertyField(sphereSideCountProp, new GUIContent(""));
                    GUILayout.EndHorizontal();

                    GUILayout.BeginHorizontal();
                }
            }

            if (GUILayout.Button("Reset Polygons"))
            {
                Undo.RecordObjects(targets, "Reset Polygons");
                foreach (var thisBrush in targets)
                {
                    if (overridenBrushType.HasValue)
                    {
                        ((PrimitiveBrush)thisBrush).BrushType = overridenBrushType.Value;
                    }
                    ((PrimitiveBrush)thisBrush).ResetPolygons();
                    ((PrimitiveBrush)thisBrush).Invalidate(true);
                }

                overridenBrushType = null;
            }
            GUILayout.EndHorizontal();

            if (GUILayout.Button("Shell"))
            {
                List <GameObject> newSelection = new List <GameObject>();
                foreach (var thisBrush in targets)
                {
                    GameObject newObject = ((PrimitiveBrush)thisBrush).Duplicate();
                    Polygon[]  polygons  = newObject.GetComponent <PrimitiveBrush>().GetPolygons();
                    VertexUtility.DisplacePolygons(polygons, -CurrentSettings.PositionSnapDistance);
                    Bounds newBounds = newObject.GetComponent <PrimitiveBrush>().GetBounds();
                    // Verify the new geometry
                    if (GeometryHelper.IsBrushConvex(polygons) &&
                        newBounds.GetSmallestExtent() > 0)
                    {
                        Undo.RegisterCreatedObjectUndo(newObject, "Shell");
                        newSelection.Add(newObject);
                    }
                    else
                    {
                        // Produced a concave brush, delete it and pretend nothing happened
                        GameObject.DestroyImmediate(newObject);
                        Debug.LogWarning("Could not shell " + thisBrush.name + " as shelled geometry would not be valid. Try lowering Pos Snapping and attempt Shell again.");
                    }
                }

                if (newSelection.Count > 0)
                {
                    Selection.objects = newSelection.ToArray();
                }
            }
        }
Esempio n. 4
0
        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
                        });
                    }
                }
            }
        }
Esempio n. 5
0
        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);
        }