internal override void DrawGizmos(BrushTarget target, BrushSettings settings)
        {
            if (Util.IsValid(target) && paintMode == PaintMode.Fill)
            {
                Vector3[] vertices = target.editableObject.editMesh.vertices;
                int[]     indices  = target.editableObject.editMesh.GetTriangles();

                PolyHandles.PushMatrix();
                PolyHandles.PushHandleColor();

                Handles.matrix = target.transform.localToWorldMatrix;

                int index = 0;

                foreach (PolyRaycastHit hit in target.raycastHits)
                {
                    if (hit.triangle > -1)
                    {
                        Handles.color = m_MeshVertexColors.TargetColors[indices[index]];

                        index = hit.triangle * 3;

                        Handles.DrawLine(vertices[indices[index + 0]] + hit.normal * .1f, vertices[indices[index + 1]] + hit.normal * .1f);
                        Handles.DrawLine(vertices[indices[index + 1]] + hit.normal * .1f, vertices[indices[index + 2]] + hit.normal * .1f);
                        Handles.DrawLine(vertices[indices[index + 2]] + hit.normal * .1f, vertices[indices[index + 0]] + hit.normal * .1f);

                        m_FillModeEdges[0].x = indices[index + 0];
                        m_FillModeEdges[0].y = indices[index + 1];

                        m_FillModeEdges[1].x = indices[index + 1];
                        m_FillModeEdges[1].y = indices[index + 2];

                        m_FillModeEdges[2].x = indices[index + 2];
                        m_FillModeEdges[2].y = indices[index + 0];

                        for (int i = 0; i < 3; i++)
                        {
                            if (m_TriangleLookup.TryGetValue(m_FillModeEdges[i], out m_FillModeAdjacentTriangles))
                            {
                                for (int n = 0; n < m_FillModeAdjacentTriangles.Count; n++)
                                {
                                    index = m_FillModeAdjacentTriangles[n] * 3;

                                    Handles.DrawLine(vertices[indices[index + 0]] + hit.normal * .1f, vertices[indices[index + 1]] + hit.normal * .1f);
                                    Handles.DrawLine(vertices[indices[index + 1]] + hit.normal * .1f, vertices[indices[index + 2]] + hit.normal * .1f);
                                    Handles.DrawLine(vertices[indices[index + 2]] + hit.normal * .1f, vertices[indices[index + 0]] + hit.normal * .1f);
                                }
                            }
                        }
                    }
                }

                PolyHandles.PopHandleColor();
                PolyHandles.PopMatrix();
            }
            else
            {
                base.DrawGizmos(target, settings);
            }
        }
        /// <summary>
        /// Draw gizmos taking into account handling of normal by raiser lower brush mode.
        /// </summary>
        /// <param name="target">Current target Object</param>
        /// <param name="settings">Current brush settings</param>
        internal override void DrawGizmos(BrushTarget target, BrushSettings settings)
        {
            if (!m_EditableObjectsData.ContainsKey(target.editableObject))
            {
                return;
            }

            EditableObjectData data = m_EditableObjectsData[target.editableObject];

            UpdateBrushGizmosColor();
            int            rayCount = target.raycastHits.Count;
            List <Vector3> brushNormalOnBeginApply = BrushNormalsOnBeginApply(target.editableObject);

            for (int ri = 0; ri < rayCount; ri++)
            {
                PolyRaycastHit hit = target.raycastHits[ri];

                Vector3 normal = hit.normal;
                switch (s_RaiseLowerDirection.value)
                {
                case PolyDirection.BrushNormal:
                case PolyDirection.VertexNormal:
                {
                    if (s_UseFirstNormalVector && brushNormalOnBeginApply.Count > ri)
                    {
                        normal = brushNormalOnBeginApply[ri];
                    }
                }
                break;

                case PolyDirection.Up:
                case PolyDirection.Right:
                case PolyDirection.Forward:
                {
                    normal = DirectionUtil.ToVector3(s_RaiseLowerDirection);
                }
                break;
                }
                ;

                normal = settings.isUserHoldingControl ? normal * -1f : normal;

                PolyHandles.DrawBrush(hit.position,
                                      normal,
                                      settings,
                                      target.localToWorldMatrix,
                                      innerColor,
                                      outerColor);
            }
        }
        /// <summary>
        /// Draw gizmos taking into account handling of normal by raiser lower brush mode.
        /// </summary>
        /// <param name="target">Current target Object</param>
        /// <param name="settings">Current brush settings</param>
        internal override void DrawGizmos(BrushTarget target, BrushSettings settings)
        {
            if (!m_EditableObjectsData.ContainsKey(target.editableObject))
            {
                return;
            }

            EditableObjectData data = m_EditableObjectsData[target.editableObject];

            UpdateBrushGizmosColor();
            int            rayCount = target.raycastHits.Count;
            List <Vector3> brushNormalOnBeginApply = BrushNormalsOnBeginApply(target.editableObject);

            for (int ri = 0; ri < rayCount; ri++)
            {
                PolyRaycastHit hit = target.raycastHits[ri];

                Vector3 normal = hit.normal;
                switch (s_RaiseLowerDirection.value)
                {
                case PolyDirection.BrushNormal:
                {
                    if (s_UseFirstNormalVector && brushNormalOnBeginApply.Count > ri)
                    {
                        normal = brushNormalOnBeginApply[ri];
                    }
                }
                break;

                case PolyDirection.Up:
                case PolyDirection.Right:
                case PolyDirection.Forward:
                {
                    normal = DirectionUtil.ToVector3(s_RaiseLowerDirection);
                }
                break;

                case PolyDirection.VertexNormal:
                {
                    //For vertex normal mode we take the vertex with the highest weight to compute the normal
                    //if non has enough we take the hit normal.
                    float highestWeight = .0001f;
                    int   highestIndex  = -1;
                    for (int i = 0; i < data.CommonVertexCount; i++)
                    {
                        int index = data.CommonVertices[i][0];

                        if (hit.weights[index] < .0001f || (s_IgnoreOpenEdges && ContainsIndexInNonManifoldIndices(target.editableObject, index)))
                        {
                            continue;
                        }

                        if (hit.weights[index] > highestWeight)
                        {
                            highestIndex = index;
                        }
                    }

                    if (highestIndex != -1)
                    {
                        normal = data.NormalLookup[highestIndex];
                    }
                }
                break;
                }
                ;

                normal = settings.isUserHoldingControl ? normal * -1f : normal;
                PolyHandles.DrawBrush(hit.position, normal, settings, target.localToWorldMatrix, innerColor, outerColor);
            }
        }
        /// <summary>
        /// Draw scene gizmos. Base implementation draws the brush preview.
        /// </summary>
        /// <param name="target">Current target Object</param>
        /// <param name="settings">Current brush settings</param>
        internal virtual void DrawGizmos(BrushTarget target, BrushSettings settings)
        {
            UpdateBrushGizmosColor();
            foreach (PolyRaycastHit hit in target.raycastHits)
            {
                PolyHandles.DrawBrush(hit.position, hit.normal, settings, target.localToWorldMatrix, innerColor, outerColor);
            }

#if Z_DEBUG
#if Z_DRAW_WEIGHTS || DRAW_PER_VERTEX_ATTRIBUTES
            float[] w = target.GetAllWeights();
#endif

#if Z_DRAW_WEIGHTS
            Mesh       m       = target.mesh;
            Vector3[]  v       = m.vertices;
            GUIContent content = new GUIContent("", "");

            Handles.BeginGUI();
            for (int i = 0; i < v.Length; i++)
            {
                if (w[i] < .0001f)
                {
                    continue;
                }

                content.text = w[i].ToString("F2");
                GUI.Label(HandleUtility.WorldPointToSizedRect(target.transform.TransformPoint(v[i]), content, EditorStyles.label), content);
            }
            Handles.EndGUI();
#endif

#if DRAW_PER_VERTEX_ATTRIBUTES
            Mesh           m        = target.editableObject.editMesh;
            Color32[]      colors   = m.colors;
            Vector4[]      tangents = m.tangents;
            List <Vector4> uv0      = m.uv0;
            List <Vector4> uv1      = m.uv1;
            List <Vector4> uv2      = m.uv2;
            List <Vector4> uv3      = m.uv3;

            int vertexCount = m.vertexCount;

            Vector3[]  verts = m.vertices;
            GUIContent gc    = new GUIContent("");

            List <List <int> >        common = MeshUtility.GetCommonVertices(m);
            System.Text.StringBuilder sb     = new System.Text.StringBuilder();

            Handles.BeginGUI();
            foreach (List <int> l in common)
            {
                if (w[l[0]] < .001)
                {
                    continue;
                }

                Vector3 v = target.transform.TransformPoint(verts[l[0]]);

                if (colors != null)
                {
                    sb.AppendLine("color: " + colors[l[0]].ToString("F2"));
                }
                if (tangents != null)
                {
                    sb.AppendLine("tangent: " + tangents[l[0]].ToString("F2"));
                }
                if (uv0 != null && uv0.Count == vertexCount)
                {
                    sb.AppendLine("uv0: " + uv0[l[0]].ToString("F2"));
                }
                if (uv1 != null && uv1.Count == vertexCount)
                {
                    sb.AppendLine("uv1: " + uv1[l[0]].ToString("F2"));
                }
                if (uv2 != null && uv2.Count == vertexCount)
                {
                    sb.AppendLine("uv2: " + uv2[l[0]].ToString("F2"));
                }
                if (uv3 != null && uv3.Count == vertexCount)
                {
                    sb.AppendLine("uv3: " + uv3[l[0]].ToString("F2"));
                }

                gc.text = sb.ToString();
                sb.Remove(0, sb.Length);                        // @todo .NET 4.0
                GUI.Label(HandleUtility.WorldPointToSizedRect(v, gc, EditorStyles.label), gc);
            }
            Handles.EndGUI();
#endif
#endif
        }
        /// <summary>
        /// Draw gizmos taking into account handling of normal by smooth brush mode.
        /// </summary>
        /// <param name="target">Current target Object</param>
        ///// <param name="settings">Current brush settings</param>
        internal override void DrawGizmos(BrushTarget target, BrushSettings settings)
        {
            UpdateBrushGizmosColor();
            Vector3 normal = s_SmoothDirection.value.ToVector3();

            int      rayCount    = target.raycastHits.Count;
            PolyMesh mesh        = target.editableObject.editMesh;
            int      vertexCount = mesh.vertexCount;

            Vector3[] normals = (s_SmoothDirection == PolyDirection.BrushNormal) ? mesh.normals : null;

            List <Vector3> brushNormalOnBeginApply = BrushNormalsOnBeginApply(target.editableObject);
            var            data = m_EditableObjectsData[target.editableObject];

            // don't use target.GetAllWeights because brush normal needs
            // to know which ray to use for normal
            for (int ri = 0; ri < rayCount; ri++)
            {
                PolyRaycastHit hit = target.raycastHits[ri];

                if (hit.weights == null || hit.weights.Length < vertexCount)
                {
                    continue;
                }

                if (s_SmoothDirection == PolyDirection.BrushNormal)
                {
                    if (s_UseFirstNormalVector && brushNormalOnBeginApply.Count > ri)
                    {
                        normal = brushNormalOnBeginApply[ri];
                    }
                    else
                    {
                        // get the highest weighted vertex to use its direction computation
                        float highestWeight = .0001f;
                        int   highestIndex  = -1;
                        for (int i = 0; i < data.commonVertexCount; i++)
                        {
                            int index = data.commonVertices[i][0];
                            if (hit.weights[index] < .0001f || (s_IgnoreOpenEdges && ContainsIndexInNonManifoldIndices(target.editableObject, index)))
                            {
                                continue;
                            }

                            if (hit.weights[index] > highestWeight)
                            {
                                highestIndex = index;
                            }
                        }

                        normal = highestIndex != -1 ?
                                 Math.WeightedAverage(normals, data.neighborLookup[highestIndex], hit.weights).normalized :
                                 hit.normal;
                    }
                }
                else if (s_SmoothDirection == PolyDirection.VertexNormal)
                {
                    normal = hit.normal;
                }

                PolyHandles.DrawBrush(hit.position,
                                      normal,
                                      settings,
                                      target.localToWorldMatrix,
                                      innerColor,
                                      outerColor);
            }
        }