void Prepare()
    {
#if UNITY_EDITOR
        mPerfWatch.Reset();
        mPerfWatch.Start();
#endif
        if (Spline && StartMesh && ExtrusionParameter > 0) {
            StartMeshInfo = new MeshInfo(StartMesh, true, false);
            if (EndMesh)
                EndMeshInfo = new MeshInfo(EndMesh, false, true);
            else
                EndMeshInfo = new MeshInfo(StartMesh, false, true);

            

            // Calculate Steps
            float tf = FromTF;
            mSegmentInfo.Clear();
            FromTF = Mathf.Clamp01(FromTF);
            ToTF = Mathf.Max(FromTF, Mathf.Clamp01(ToTF));
            Vector3 scale;
            if (FromTF != ToTF) {
                switch (Extrusion) {
                    case MeshExtrusion.FixedF:
                        while (tf < ToTF) {
                            scale = getScale(tf);
                            mSegmentInfo.Add(new CurvyMeshSegmentInfo(this, tf,scale));
                            tf += ExtrusionParameter;
                        }
                        break;
                    case MeshExtrusion.FixedDistance:
                        float d = Spline.TFToDistance(FromTF);
                        tf = Spline.DistanceToTF(d);
                        while (tf < ToTF) {
                            scale = getScale(tf);
                            mSegmentInfo.Add(new CurvyMeshSegmentInfo(this, tf, d, scale));
                            d += ExtrusionParameter;
                            tf = Spline.DistanceToTF(d);
                        }
                        break;
                    case MeshExtrusion.Adaptive:
                        while (tf < ToTF) {
                            scale = getScale(tf);
                            mSegmentInfo.Add(new CurvyMeshSegmentInfo(this, tf, scale));
                            int dir = 1;
                            Spline.MoveByAngle(ref tf, ref dir, ExtrusionParameter, CurvyClamping.Clamp, 0.005f);
                        }
                 
                        break;
                }
                if (!Mathf.Approximately(tf, ToTF))
                    tf = ToTF;
                scale = getScale(tf);
                mSegmentInfo.Add(new CurvyMeshSegmentInfo(this, tf, scale));
            }
        }
#if UNITY_EDITOR
        mPerfWatch.Stop();
        DebugPerfPrepare = mPerfWatch.ElapsedTicks / (double)System.TimeSpan.TicksPerMillisecond;
        mPerfWatch.Reset();
#endif
    }
    /// <summary>
    /// Rebuilds the mesh
    /// </summary>
    public void Refresh()
    {
        StartMeshInfo = null;
        EndMeshInfo = null;
        if (mMesh)
            mMesh.Clear();
        
        if (!mMesh || !Spline || !Spline.IsInitialized || Spline.Length==0) return;
        
        BuildCaps();
        Prepare();
        if (StartMesh && StartMeshInfo!=null && ToTF - FromTF != 0) {
            mVerts = new Vector3[getTotalVertexCount()];
            mUV = new Vector2[mVerts.Length];
            mTris = new int[getTotalTriIndexCount()];
            Extrude();

            mMesh.vertices = mVerts;
            mMesh.uv = mUV;
            mMesh.triangles = mTris;
            mMesh.RecalculateNormals();
            if (CalculateTangents)
                MeshHelper.CalculateMeshTangents(mMesh);
        }
    }