public void OnSceneGUI()
    {
        Undo.RegisterUndo(target, "Move Shape Points");

        MegaShape shape = (MegaShape)target;
        float     ksize = shape.KnotSize * 0.01f;

        float ringratio   = 1.3f;
        float borderratio = 1.15f;
        float knotsize    = ksize;
        //float ringsize = knotsize1.1f;
        float handlesize = knotsize * 0.75f;

        //float outdiscsize = ksize * 1.0f * 0.5f;

        Handles.matrix = shape.transform.localToWorldMatrix;

        bool recalc = false;

        Vector3 dragplane = Vector3.one;
        Vector3 camfwd    = Camera.current.transform.forward;

        if (Mathf.Abs(camfwd.x) > Mathf.Abs(camfwd.y))
        {
            if (Mathf.Abs(camfwd.x) > Mathf.Abs(camfwd.z))
            {
                dragplane.x = 0.0f;
            }
            else
            {
                dragplane.z = 0.0f;
            }
        }
        else
        {
            if (Mathf.Abs(camfwd.y) > Mathf.Abs(camfwd.z))
            {
                dragplane.y = 0.0f;
            }
            else
            {
                dragplane.z = 0.0f;
            }
        }
        //Debug.Log("Dragplane " + dragplane);

        Color nocol = new Color(0, 0, 0, 0);

        for (int s = 0; s < shape.splines.Count; s++)
        {
            for (int p = 0; p < shape.splines[s].knots.Count; p++)
            {
                Vector3 pp = shape.transform.TransformPoint(shape.splines[s].knots[p].p);

                Vector3 normal = Camera.current.transform.forward;
                if (shape.drawKnots)                    //&& recalc == false )
                {
                    pm = shape.splines[s].knots[p].p;

                    Handles.color = Color.black;
                    Handles.color = shape.VecCol;

                    //Vector3 normal = (pp - Camera.current.transform.position).normalized;
                    Handles.DrawSolidDisc(pp, normal, knotsize * borderratio);                          //ksize * 0.55f);

                    if (p == selected)
                    {
                        Handles.color = Color.white;
                        Handles.Label(pm, " Selected\n" + pm.ToString("0.000"));
                    }
                    else
                    {
                        Handles.color = shape.KnotCol;
                        Handles.Label(pm, " " + p);
                    }

                    //if ( p == selected )
                    //shape.splines[s].knots[p].p = Handles.PositionHandle(pm, Quaternion.identity);
                    //else
                    //{

                    Handles.color = shape.KnotCol;
                    Handles.DrawSolidDisc(pp, normal, knotsize);

                    //shape.splines[s].knots[p].p = Handles.FreeMoveHandle(pm, Quaternion.identity, ksize, Vector3.zero, Handles.SphereCap);	//CubeCap);
                    Handles.color = nocol;                                                                                                 //shape.VecCol;
                    Vector3 newp = Handles.FreeMoveHandle(pm, Quaternion.identity, knotsize * ringratio, Vector3.zero, Handles.CircleCap); //SphereCap);	//CubeCap);
                    shape.splines[s].knots[p].p += Vector3.Scale(newp - pm, dragplane);


                    //if ( shape.splines[s].knots[p].p != pm )
                    //selected = p;
                    //}

                    delta = shape.splines[s].knots[p].p - pm;

                    shape.splines[s].knots[p].invec  += delta;
                    shape.splines[s].knots[p].outvec += delta;

                    if (shape.splines[s].knots[p].p != pm)
                    {
                        selected = p;
                        recalc   = true;
                    }

                    pm = shape.transform.TransformPoint(shape.splines[s].knots[p].p);

                    //Handles.CubeCap(0, pm, Quaternion.identity, shape.KnotSize);
                }

                if (shape.drawHandles)                          //&& recalc == false )
                {
                    Handles.color = shape.VecCol;
                    pm            = shape.transform.TransformPoint(shape.splines[s].knots[p].p);

                    Vector3 ip = shape.transform.TransformPoint(shape.splines[s].knots[p].invec);
                    Vector3 op = shape.transform.TransformPoint(shape.splines[s].knots[p].outvec);
                    Handles.DrawLine(pm, shape.transform.TransformPoint(shape.splines[s].knots[p].invec));
                    Handles.DrawLine(pm, shape.transform.TransformPoint(shape.splines[s].knots[p].outvec));


                    //Handles.color = Color.black;
                    //Vector3 normal = (op - Camera.current.transform.position).normalized;
                    Handles.DrawSolidDisc(op, normal, handlesize * borderratio);                        //ksize * 0.55f * ringratio);
                    //normal = Camera.current.transform.forward;	//(ip - Camera.current.transform.position).normalized;
                    Handles.DrawSolidDisc(ip, normal, handlesize * borderratio);                        //ksize * 0.55f * ringratio);

                    Handles.color = shape.HandleCol;

                    //Handles.DrawSolidDisc(op, normal, ksize * 0.5f * ringratio);
                    //Handles.DrawSolidDisc(ip, normal, ksize * 0.5f * ringratio);
                    Handles.DrawSolidDisc(op, normal, handlesize);
                    Handles.DrawSolidDisc(ip, normal, handlesize);

                    //shape.splines[s].knots[p].invec = Handles.PositionHandle(shape.splines[s].knots[p].invec, Quaternion.identity);	//shape.hsize);
                    //shape.splines[s].knots[p].outvec = Handles.PositionHandle(shape.splines[s].knots[p].outvec, Quaternion.identity);	//shape.hsize);

                    Vector3 invec = shape.splines[s].knots[p].invec;
                    //if ( p == selected )
                    //invec = Handles.PositionHandle(shape.splines[s].knots[p].invec, Quaternion.identity);	//shape.hsize);
                    //else
                    Handles.color = nocol;
                    Vector3 newinvec = Handles.FreeMoveHandle(shape.splines[s].knots[p].invec, Quaternion.identity, handlesize * ringratio, Vector3.zero, Handles.CircleCap);                           //SphereCap);	//CubeCap);

                    invec += Vector3.Scale(newinvec - invec, dragplane);
                    //Debug.Log("sel " + selected + " new " + invec.ToString("0.0000") + " old " + shape.splines[s].knots[p].invec.ToString("0.0000"));
                    if (invec != shape.splines[s].knots[p].invec)
                    {
                        if (shape.lockhandles)
                        {
                            Vector3 d = invec - shape.splines[s].knots[p].invec;
                            shape.splines[s].knots[p].outvec -= d;
                        }

                        shape.splines[s].knots[p].invec = invec;
                        selected = p;
                        recalc   = true;
                    }
                    Vector3 outvec = shape.splines[s].knots[p].outvec;                          // = Handles.PositionHandle(shape.splines[s].knots[p].outvec, Quaternion.identity);	//shape.hsize);

                    //if ( p == selected )
                    //outvec = Handles.PositionHandle(shape.splines[s].knots[p].outvec, Quaternion.identity);	//shape.hsize);
                    //else
                    Vector3 newoutvec = Handles.FreeMoveHandle(shape.splines[s].knots[p].outvec, Quaternion.identity, handlesize * ringratio, Vector3.zero, Handles.CircleCap);                         //SphereCap);	//CubeCap);
                    outvec += Vector3.Scale(newoutvec - outvec, dragplane);

                    if (outvec != shape.splines[s].knots[p].outvec)
                    {
                        if (shape.lockhandles)
                        {
                            Vector3 d = outvec - shape.splines[s].knots[p].outvec;
                            shape.splines[s].knots[p].invec -= d;
                        }

                        shape.splines[s].knots[p].outvec = outvec;
                        selected = p;
                        recalc   = true;
                    }
                    Vector3 hp = shape.transform.TransformPoint(shape.splines[s].knots[p].invec);
                    //Handles.CubeCap(0, hp, Quaternion.identity, shape.KnotSize);
                    if (selected == p)
                    {
                        Handles.Label(hp, " " + p);
                    }

                    hp = shape.transform.TransformPoint(shape.splines[s].knots[p].outvec);
                    //Handles.CubeCap(0, hp, Quaternion.identity, shape.KnotSize);

                    if (selected == p)
                    {
                        Handles.Label(hp, " " + p);
                    }
                }

                // Draw nearest point (use for adding knot)
                //CursorPos = Handles.PositionHandle(CursorPos, Quaternion.identity);
#if false
                if (shape.drawKnots)
                {
                    pm = shape.splines[s].knots[p].p;

                    if (p == selected)
                    {
                        Handles.color = Color.white;
                        Handles.Label(pm, " Selected\n" + pm.ToString("0.000"));
                    }
                    else
                    {
                        Handles.color = shape.KnotCol;
                        Handles.Label(pm, " " + p);
                    }

                    //if ( p == selected )
                    shape.splines[s].knots[p].p = Handles.PositionHandle(pm, Quaternion.identity);
                    //else
                    //{
                    //shape.splines[s].knots[p].p = Handles.FreeMoveHandle(pm, Quaternion.identity, shape.KnotSize, Vector3.zero, Handles.CubeCap);

                    //if ( shape.splines[s].knots[p].p != pm )
                    //selected = p;
                    //}

                    delta = shape.splines[s].knots[p].p - pm;

                    shape.splines[s].knots[p].invec  += delta;
                    shape.splines[s].knots[p].outvec += delta;

                    if (shape.splines[s].knots[p].p != pm)
                    {
                        selected = p;
                        recalc   = true;
                    }

                    pm = shape.transform.TransformPoint(shape.splines[s].knots[p].p);

                    Handles.CubeCap(0, pm, Quaternion.identity, shape.KnotSize);
                }
#endif
            }
        }

        if (recalc)
        {
            shape.CalcLength(10);
            shape.BuildMesh();
        }

        Handles.matrix = Matrix4x4.identity;
    }
    public override void OnInspectorGUI()
    {
        bool      buildmesh = false;
        MegaShape shape     = (MegaShape)target;

        EditorGUILayout.BeginHorizontal();

        if (GUILayout.Button("Add Knot"))
        {
            if (shape.splines == null || shape.splines.Count == 0)
            {
                MegaSpline spline = new MegaSpline();                   // Have methods for these
                shape.splines.Add(spline);
            }

            //Undo.RegisterUndo(target, "Add Knot");

            MegaKnot knot = new MegaKnot();
#if true
            // Add a point at CursorPos

            //sp = selected + 1;
            //Debug.Log("CursorPos " + CursorPos + " CursorKnot " + CursorKnot);
            float per = CursorPercent * 0.01f;

            CursorTangent = shape.splines[0].Interpolate(per + 0.01f, true, ref CursorKnot);    //this.GetPositionOnSpline(i) - p;
            CursorPos     = shape.splines[0].Interpolate(per, true, ref CursorKnot);            //this.GetPositionOnSpline(i) - p;

            knot.p = CursorPos;
            //CursorTangent =
            //Vector3 t = shape.splines[0].knots[selected].Interpolate(0.51f, shape.splines[0].knots[0]);
            knot.outvec = (CursorTangent - knot.p);
            knot.outvec.Normalize();
            knot.outvec *= shape.splines[0].knots[CursorKnot].seglength * 0.25f;
            knot.invec   = -knot.outvec;
            knot.invec  += knot.p;
            knot.outvec += knot.p;

            shape.splines[0].knots.Insert(CursorKnot + 1, knot);
#else
            int sp = 0;

            if (selected == -1 || shape.splines[0].knots.Count == 1)
            {
                shape.splines[0].knots.Add(knot);
                selected = shape.splines[0].knots.Count - 1;
            }
            else
            {
                if (selected < shape.splines[0].knots.Count - 1)
                {
                    sp     = selected + 1;
                    knot.p = shape.splines[0].knots[selected].Interpolate(0.5f, shape.splines[0].knots[selected + 1]);
                    Vector3 t = shape.splines[0].knots[selected].Interpolate(0.51f, shape.splines[0].knots[selected + 1]);
                    knot.outvec = (t - knot.p);                         //.Normalize();
                    knot.outvec.Normalize();
                    knot.outvec *= shape.splines[0].knots[selected].seglength * 0.25f;
                    knot.invec   = -knot.outvec;
                    knot.invec  += knot.p;
                    knot.outvec += knot.p;
                }
                else
                {
                    if (shape.splines[0].closed)
                    {
                        sp     = selected + 1;
                        knot.p = shape.splines[0].knots[selected].Interpolate(0.5f, shape.splines[0].knots[0]);
                        Vector3 t = shape.splines[0].knots[selected].Interpolate(0.51f, shape.splines[0].knots[0]);
                        knot.outvec = (t - knot.p);                             //.Normalize();
                        knot.outvec.Normalize();
                        knot.outvec *= shape.splines[0].knots[selected].seglength * 0.25f;
                        knot.invec   = -knot.outvec;
                        knot.invec  += knot.p;
                        knot.outvec += knot.p;
                    }
                    else
                    {
                        sp = selected - 1;

                        //Debug.Log("selected " + selected + " count " + shape.splines[0].knots.Count + " sp " + sp);
                        knot.p = shape.splines[0].knots[sp].Interpolate(0.5f, shape.splines[0].knots[sp + 1]);
                        Vector3 t = shape.splines[0].knots[sp].Interpolate(0.51f, shape.splines[0].knots[sp + 1]);
                        knot.outvec = (t - knot.p);                             //.Normalize();
                        knot.outvec.Normalize();
                        knot.outvec *= shape.splines[0].knots[sp].seglength * 0.25f;
                        knot.invec   = -knot.outvec;
                        knot.invec  += knot.p;
                        knot.outvec += knot.p;
                        sp++;
                    }
                }

                shape.splines[0].knots.Insert(sp, knot);
                selected = sp;                  //++;
            }
#endif
            shape.CalcLength(10);
            EditorUtility.SetDirty(target);
            buildmesh = true;
        }

        if (GUILayout.Button("Delete Knot"))
        {
            if (selected != -1)
            {
                //Undo.RegisterUndo(target, "Delete Knot");
                shape.splines[0].knots.RemoveAt(selected);
                selected--;
                shape.CalcLength(10);
            }
            EditorUtility.SetDirty(target);
            buildmesh = true;
        }

        EditorGUILayout.EndHorizontal();
        EditorGUILayout.BeginHorizontal();

        if (GUILayout.Button("Match Handles"))
        {
            if (selected != -1)
            {
                //Undo.RegisterUndo(target, "Match Handles");

                Vector3 p = shape.splines[0].knots[selected].p;
                Vector3 d = shape.splines[0].knots[selected].outvec - p;
                shape.splines[0].knots[selected].invec = p - d;
                shape.CalcLength(10);
            }
            EditorUtility.SetDirty(target);
            buildmesh = true;
        }

        if (GUILayout.Button("Load"))
        {
            // Load a spl file from max, so delete everything and replace
            LoadShape(ImportScale);
            buildmesh = true;
        }

        EditorGUILayout.EndHorizontal();

        showcommon = EditorGUILayout.Foldout(showcommon, "Common Params");

        bool rebuild = false;           //Params();

        if (showcommon)
        {
            //CursorPos = EditorGUILayout.Vector3Field("Cursor", CursorPos);
            CursorPercent = EditorGUILayout.FloatField("Cursor", CursorPercent);
            CursorPercent = Mathf.Repeat(CursorPercent, 100.0f);

            ImportScale = EditorGUILayout.FloatField("Import Scale", ImportScale);

            MegaAxis av = (MegaAxis)EditorGUILayout.EnumPopup("Axis", shape.axis);
            if (av != shape.axis)
            {
                shape.axis = av;
                rebuild    = true;
            }

            shape.col1 = EditorGUILayout.ColorField("Col 1", shape.col1);
            shape.col2 = EditorGUILayout.ColorField("Col 2", shape.col2);

            shape.KnotCol   = EditorGUILayout.ColorField("Knot Col", shape.KnotCol);
            shape.HandleCol = EditorGUILayout.ColorField("Handle Col", shape.HandleCol);
            shape.VecCol    = EditorGUILayout.ColorField("Vec Col", shape.VecCol);

            shape.KnotSize = EditorGUILayout.FloatField("Knot Size", shape.KnotSize);
            shape.stepdist = EditorGUILayout.FloatField("Step Dist", shape.stepdist);

            if (shape.stepdist < 0.01f)
            {
                shape.stepdist = 0.01f;
            }

            shape.normalizedInterp = EditorGUILayout.Toggle("Normalized Interp", shape.normalizedInterp);
            shape.drawHandles      = EditorGUILayout.Toggle("Draw Handles", shape.drawHandles);
            shape.drawKnots        = EditorGUILayout.Toggle("Draw Knots", shape.drawKnots);
            shape.drawspline       = EditorGUILayout.Toggle("Draw Spline", shape.drawspline);
            shape.lockhandles      = EditorGUILayout.Toggle("Lock Handles", shape.lockhandles);

            shape.animate = EditorGUILayout.Toggle("Animate", shape.animate);
            if (shape.animate)
            {
                shape.time     = EditorGUILayout.FloatField("Time", shape.time);
                shape.MaxTime  = EditorGUILayout.FloatField("Loop Time", shape.MaxTime);
                shape.speed    = EditorGUILayout.FloatField("Speed", shape.speed);
                shape.LoopMode = (MegaRepeatMode)EditorGUILayout.EnumPopup("Loop Mode", shape.LoopMode);
            }

            // Mesher
            shape.makeMesh = EditorGUILayout.Toggle("Make Mesh", shape.makeMesh);

            if (shape.makeMesh)
            {
                shape.meshType = (MeshShapeType)EditorGUILayout.EnumPopup("Mesh Type", shape.meshType);

                shape.Pivot = EditorGUILayout.Vector3Field("Pivot", shape.Pivot);

                shape.CalcTangents = EditorGUILayout.Toggle("Calc Tangents", shape.CalcTangents);
                shape.GenUV        = EditorGUILayout.Toggle("Gen UV", shape.GenUV);
                shape.PhysUV       = EditorGUILayout.Toggle("Physical UV", shape.PhysUV);
                shape.UVOffset     = EditorGUILayout.Vector2Field("UV Offset", shape.UVOffset);
                shape.UVRotate     = EditorGUILayout.Vector2Field("UV Rotate", shape.UVRotate);
                shape.UVScale      = EditorGUILayout.Vector2Field("UV Scale", shape.UVScale);
                shape.UVOffset1    = EditorGUILayout.Vector2Field("UV Offset1", shape.UVOffset1);
                shape.UVRotate1    = EditorGUILayout.Vector2Field("UV Rotate1", shape.UVRotate1);
                shape.UVScale1     = EditorGUILayout.Vector2Field("UV Scale1", shape.UVScale1);

                switch (shape.meshType)
                {
                case MeshShapeType.Fill:
                    shape.DoubleSided    = EditorGUILayout.Toggle("Double Sided", shape.DoubleSided);
                    shape.Height         = EditorGUILayout.FloatField("Height", shape.Height);
                    shape.HeightSegs     = EditorGUILayout.IntField("HeightSegs", shape.HeightSegs);
                    shape.UseHeightCurve = EditorGUILayout.Toggle("Use Height Crv", shape.UseHeightCurve);
                    if (shape.UseHeightCurve)
                    {
                        shape.heightCrv = EditorGUILayout.CurveField("Height Curve", shape.heightCrv);
                    }
                    break;

                case MeshShapeType.Line:
                    shape.DoubleSided = EditorGUILayout.Toggle("Double Sided", shape.DoubleSided);
                    shape.Height      = EditorGUILayout.FloatField("Height", shape.Height);
                    shape.HeightSegs  = EditorGUILayout.IntField("HeightSegs", shape.HeightSegs);
                    shape.heightCrv   = EditorGUILayout.CurveField("Height Curve", shape.heightCrv);
                    shape.Start       = EditorGUILayout.FloatField("Start", shape.Start);
                    shape.End         = EditorGUILayout.FloatField("End", shape.End);
                    shape.Rotate      = EditorGUILayout.FloatField("Rotate", shape.Rotate);
                    break;

                case MeshShapeType.Tube:
                    shape.Sides    = EditorGUILayout.IntField("Sides", shape.Sides);
                    shape.TubeStep = EditorGUILayout.FloatField("TubeStep", shape.TubeStep);
                    shape.Start    = EditorGUILayout.FloatField("Start", shape.Start);
                    shape.End      = EditorGUILayout.FloatField("End", shape.End);
                    break;
                }
            }

            showsplines = EditorGUILayout.Foldout(showsplines, "Splines");

            if (showsplines)
            {
                for (int i = 0; i < shape.splines.Count; i++)
                {
                    DisplaySpline(shape, shape.splines[i]);
                }
            }
        }

        if (Params())
        {
            rebuild = true;
        }

        if (GUI.changed)
        {
            EditorUtility.SetDirty(target);
            //shape.CalcLength(10);
            buildmesh = true;
        }

        if (rebuild)
        {
            shape.MakeShape();
            EditorUtility.SetDirty(target);
            buildmesh = true;
        }

        if (buildmesh)
        {
            shape.BuildMesh();
        }
    }
	public void OnSceneGUI()
	{
		MegaShape shape = (MegaShape)target;

		bool mouseup = false;
		bool recalc = false;

		if ( Event.current.type == EventType.KeyDown )
		{
			if ( Event.current.keyCode == KeyCode.LeftAlt || Event.current.keyCode == KeyCode.RightAlt )
			{
				editmode = false;
			}
		}

		if ( Event.current.type == EventType.KeyUp )
		{
			if ( Event.current.keyCode == KeyCode.LeftAlt || Event.current.keyCode == KeyCode.RightAlt )
			{
				editmode = true;
			}
		}

		if ( !editmode )
		{
			return;
		}

		if ( Event.current.type == EventType.mouseUp )
		{
			mouseup = true;
			recalc = true;

			if ( addingknot )
			{
				addingknot = false;
				MegaKnot knot = new MegaKnot();

				knot.p = addpos;
				knot.id = shape.splines[snum].knots[knum].id;
				knot.twist = shape.splines[snum].knots[knum].twist;

				shape.splines[snum].knots.Insert(knum + 1, knot);

				if ( shape.smoothonaddknot )
					shape.AutoCurve(shape.splines[snum]);	//, knum, knum + 2);
				shape.CalcLength();	//10);
				EditorUtility.SetDirty(target);
				if ( shape.makeMesh )
				{
					shape.SetMats();
					shape.BuildMesh();
				}
			}
		}

		Handles.matrix = shape.transform.localToWorldMatrix;

		if ( shape.selcurve > shape.splines.Count - 1 )
			shape.selcurve = 0;

		Vector3 dragplane = Vector3.one;

		Color nocol = new Color(0, 0, 0, 0);

		bounds.size = Vector3.zero;

		Color twistcol = new Color(0.5f, 0.5f, 1.0f, 0.25f);

		for ( int s = 0; s < shape.splines.Count; s++ )
		{
			for ( int p = 0; p < shape.splines[s].knots.Count; p++ )
			{
				if ( s == shape.selcurve )
				{
					bounds.Encapsulate(shape.splines[s].knots[p].p);
				}

				if ( shape.drawKnots && s == shape.selcurve )
				{
					pm = shape.splines[s].knots[p].p;

					if ( showlabels )
					{
						if ( p == selected && s == shape.selcurve )
						{
							Handles.color = Color.white;
							Handles.Label(pm, " Selected\n" + pm.ToString("0.000"));
						}
						else
						{
							Handles.color = shape.KnotCol;
							Handles.Label(pm, " " + p);
						}
					}

					Handles.color = nocol;
					Vector3 newp = Vector3.zero;
					
					if ( shape.usesnap )
						newp = PosHandlesSnap(shape, pm, Quaternion.identity);
					else
						newp = PosHandles(shape, pm, Quaternion.identity);

					if ( newp != pm )
					{
						MegaUndo.SetSnapshotTarget(shape, "Knot Move");
					}

					Vector3 dl = Vector3.Scale(newp - pm, dragplane);

					shape.splines[s].knots[p].p += dl;	//Vector3.Scale(newp - pm, dragplane);

					shape.splines[s].knots[p].invec += dl;	//delta;
					shape.splines[s].knots[p].outvec += dl;	//delta;

					if ( newp != pm )
					{
						selected = p;
						recalc = true;
					}
				}

				if ( shape.drawHandles && s == shape.selcurve )
				{
					Handles.color = shape.VecCol;
					pm = shape.splines[s].knots[p].p;

					Vector3 ip = shape.splines[s].knots[p].invec;
					Vector3 op = shape.splines[s].knots[p].outvec;
					Handles.DrawLine(pm, ip);
					Handles.DrawLine(pm, op);

					Handles.color = shape.HandleCol;

					Vector3 invec = shape.splines[s].knots[p].invec;
					Handles.color = nocol;
					Vector3 newinvec = Vector3.zero;
					
					if ( shape.usesnaphandles )
						newinvec = PosHandlesSnap(shape, invec, Quaternion.identity);
					else
						newinvec = PosHandles(shape, invec, Quaternion.identity);

					if ( newinvec != invec )	//shape.splines[s].knots[p].invec )
					{
						MegaUndo.SetSnapshotTarget(shape, "Handle Move");
					}
					Vector3 dl = Vector3.Scale(newinvec - invec, dragplane);
					shape.splines[s].knots[p].invec += dl;	//Vector3.Scale(newinvec - invec, dragplane);
					if ( invec != newinvec )	//shape.splines[s].knots[p].invec )
					{
						if ( shape.lockhandles )
						{
							shape.splines[s].knots[p].outvec -= dl;
						}

						selected = p;
						recalc = true;
					}
					Vector3 outvec = shape.splines[s].knots[p].outvec;

					Vector3 newoutvec = Vector3.zero;
					if ( shape.usesnaphandles )
						newoutvec = PosHandlesSnap(shape, outvec, Quaternion.identity);
					else
						newoutvec = PosHandles(shape, outvec, Quaternion.identity);

					if ( newoutvec != outvec )	//shape.splines[s].knots[p].outvec )
					{
						MegaUndo.SetSnapshotTarget(shape, "Handle Move");
					}
					dl = Vector3.Scale(newoutvec - outvec, dragplane);
					shape.splines[s].knots[p].outvec += dl;
					if ( outvec != newoutvec )	//shape.splines[s].knots[p].outvec )
					{
						if ( shape.lockhandles )
						{
							shape.splines[s].knots[p].invec -= dl;
						}

						selected = p;
						recalc = true;
					}
					Vector3 hp = shape.splines[s].knots[p].invec;
					if ( selected == p )
						Handles.Label(hp, " " + p);

					hp = shape.splines[s].knots[p].outvec;

					if ( selected == p )
						Handles.Label(hp, " " + p);
				}

				// TODO: Draw a wedge to show the twist angle
				// Twist handles
				if ( shape.drawTwist && s == shape.selcurve )
				{
					Vector3 np = Vector3.zero;

					if ( p == 0 || p < shape.splines[s].knots.Count - 2 )
					{
						np = shape.splines[s].knots[p].Interpolate(0.002f, shape.splines[s].knots[p + 1]);
						np = np - shape.splines[s].knots[p].p;
						//np = shape.splines[s].knots[p].outvec;	//(0.0f, shape.splines[s].knots[p + 1]);

						//Debug.Log("np " + np);
					}
					else
					{
						if ( shape.splines[s].closed )
						{
							np = shape.splines[s].knots[p].Interpolate(0.002f, shape.splines[s].knots[0]);
							np = np - shape.splines[s].knots[p].p;
							//np = shape.splines[s].knots[p].outvec;	//Tangent(0.0f, shape.splines[s].knots[0]);
							//Debug.Log("np " + np);
						}
						else
						{
							np = shape.splines[s].knots[p - 1].Interpolate(0.998f, shape.splines[s].knots[p]);
							np = shape.splines[s].knots[p].p - np;
							//np = shape.splines[s].knots[p - 1].outvec;	//Tangent(0.9999f, shape.splines[s].knots[p]);
							//Debug.Log("np " + np);
						}
					}

					if ( np == Vector3.zero )
						np = Vector3.forward;

					np = np.normalized;
					// np holds the tangent so we can align the arc
					Quaternion fwd = Quaternion.LookRotation(np);

					Vector3 rg = Vector3.Cross(np, Vector3.up);
					//Vector3 up = Vector3.Cross(np, rg);

					Handles.color = twistcol;
					float twist = shape.splines[s].knots[p].twist;

					Handles.DrawSolidArc(shape.splines[s].knots[p].p, np, rg, twist, shape.KnotSize * 0.1f);

					Vector3 tang = new Vector3(0.0f, 0.0f, shape.splines[s].knots[p].twist);
					Quaternion inrot = fwd * Quaternion.Euler(tang);
					//Quaternion rot = Handles.RotationHandle(inrot, shape.splines[s].knots[p].p);
					Handles.color = Color.white;
					Quaternion rot = Handles.Disc(inrot, shape.splines[s].knots[p].p, np, shape.KnotSize * 0.1f, false, 0.0f);
					
					if ( rot != inrot )
					{
						tang = rot.eulerAngles;
						float diff = (tang.z - shape.splines[s].knots[p].twist);
						if ( Mathf.Abs(diff) > 0.0001f  )
						{
							while ( diff > 180.0f )
								diff -= 360.0f;

							while ( diff < -180.0f )
								diff += 360.0f;

							shape.splines[s].knots[p].twist += diff;
							recalc = true;
						}
					}
				}

				// Midpoint add knot code
				if ( s == shape.selcurve )
				{
					if ( p < shape.splines[s].knots.Count - 1 )
					{
						Handles.color = Color.white;

						Vector3 mp = shape.splines[s].knots[p].InterpolateCS(0.5f, shape.splines[s].knots[p + 1]);

						Vector3 mp1 = Handles.FreeMoveHandle(mp, Quaternion.identity, shape.KnotSize * 0.01f, Vector3.zero, Handles.CircleCap);
						if ( mp1 != mp )
						{
							if ( !addingknot )
							{
								addingknot = true;
								addpos = mp;
								knum = p;
								snum = s;
							}
						}
					}
				}
			}
		}

		// Draw nearest point (use for adding knot)
		Vector3 wcp = CursorPos;
		Vector3 newCursorPos = PosHandles(shape, wcp, Quaternion.identity);
		
		if ( newCursorPos != wcp )
		{
			Vector3 cd = newCursorPos - wcp;

			CursorPos += cd;

			float calpha = 0.0f;
			CursorPos = shape.FindNearestPoint(CursorPos, 5, ref CursorKnot, ref CursorTangent, ref calpha);
			shape.CursorPercent = calpha * 100.0f;
		}

		Handles.Label(CursorPos, "Cursor " + shape.CursorPercent.ToString("0.00") + "% - " + CursorPos);

		// Move whole spline handle
		if ( shape.showorigin )
		{
			Handles.Label(bounds.min, "Origin");
			Vector3 spos = Handles.PositionHandle(bounds.min, Quaternion.identity);
			if ( spos != bounds.min )
			{
				if ( shape.usesnap )
				{
					if ( shape.snap.x != 0.0f )
						spos.x = (int)(spos.x / shape.snap.x) * shape.snap.x;

					if ( shape.snap.y != 0.0f )
						spos.y = (int)(spos.y / shape.snap.y) * shape.snap.y;

					if ( shape.snap.z != 0.0f )
						spos.z = (int)(spos.z / shape.snap.z) * shape.snap.z;
				}

				// Move the spline
				shape.MoveSpline(spos - bounds.min, shape.selcurve, false);
				recalc = true;
			}
		}

		if ( recalc )
		{
			shape.CalcLength();	//10);

			if ( shape.updateondrag || (!shape.updateondrag && mouseup) )
			{
				shape.BuildMesh();

				//MegaLoftLayerSimple[] layers = (MegaLoftLayerSimple[])FindObjectsOfType(typeof(MegaLoftLayerSimple));

				//for ( int i = 0; i < layers.Length; i++ )
				//{
					//layers[i].Notify(shape.splines[shape.selcurve], 0);
				//}

				EditorUtility.SetDirty(shape);
			}
		}

		Handles.matrix = Matrix4x4.identity;
		//undoManager.CheckDirty(target);

		// This is wrong gui not changing here
		if ( GUI.changed )
		{
			MegaUndo.CreateSnapshot();
			MegaUndo.RegisterSnapshot();
		}

		MegaUndo.ClearSnapshotTarget();
	}
	public override void OnInspectorGUI()
	{
		//undoManager.CheckUndo();
		bool buildmesh = false;
		bool recalc = false;
		MegaShape shape = (MegaShape)target;

		EditorGUILayout.BeginHorizontal();

		int curve = shape.selcurve;

		if ( GUILayout.Button("Add Knot") )
		{
			if ( shape.splines == null || shape.splines.Count == 0 )
			{
				MegaSpline spline = new MegaSpline();	// Have methods for these
				shape.splines.Add(spline);
			}

			MegaKnot knot = new MegaKnot();
			float per = shape.CursorPercent * 0.01f;

			CursorTangent = shape.splines[curve].Interpolate(per + 0.01f, true, ref CursorKnot);	//this.GetPositionOnSpline(i) - p;
			CursorPos = shape.splines[curve].Interpolate(per, true, ref CursorKnot);	//this.GetPositionOnSpline(i) - p;

			knot.p = CursorPos;
			knot.outvec = (CursorTangent - knot.p);
			knot.outvec.Normalize();
			knot.outvec *= shape.splines[curve].knots[CursorKnot].seglength * 0.25f;
			knot.invec = -knot.outvec;
			knot.invec += knot.p;
			knot.outvec += knot.p;
			knot.twist = shape.splines[curve].knots[CursorKnot].twist;
			knot.id = shape.splines[curve].knots[CursorKnot].id;

			shape.splines[curve].knots.Insert(CursorKnot + 1, knot);

			if ( shape.smoothonaddknot )
				shape.AutoCurve(shape.splines[snum]);	//, knum, knum + 2);

			shape.CalcLength();	//10);
			EditorUtility.SetDirty(target);
			buildmesh = true;
		}

		if ( GUILayout.Button("Delete Knot") )
		{
			if ( selected != -1 )
			{
				shape.splines[curve].knots.RemoveAt(selected);
				selected--;
				shape.CalcLength();	//10);
			}
			EditorUtility.SetDirty(target);
			buildmesh = true;
		}
		
		EditorGUILayout.EndHorizontal();
		EditorGUILayout.BeginHorizontal();

		if ( GUILayout.Button("Match Handles") )
		{
			if ( selected != -1 )
			{
				Vector3 p = shape.splines[curve].knots[selected].p;
				Vector3 d = shape.splines[curve].knots[selected].outvec - p;
				shape.splines[curve].knots[selected].invec = p - d;
				shape.CalcLength();	//10);
			}
			EditorUtility.SetDirty(target);
			buildmesh = true;
		}

		if ( GUILayout.Button("Load") )
		{
			LoadShape(ImportScale);
			buildmesh = true;
		}

		if ( GUILayout.Button("Load SXL") )
		{
			LoadSXL(ImportScale);
			buildmesh = true;
		}

		if ( GUILayout.Button("Load KML") )
		{
			LoadKML(ImportScale);
			buildmesh = true;
		}

		EditorGUILayout.EndHorizontal();

		EditorGUILayout.BeginHorizontal();
		if ( GUILayout.Button("AutoCurve") )
		{
			shape.AutoCurve();
			EditorUtility.SetDirty(target);
			buildmesh = true;
		}

		if ( GUILayout.Button("Reverse") )
		{
			shape.Reverse(curve);
			//shape.CalcLength();
			EditorUtility.SetDirty(target);
			buildmesh = true;
		}

		EditorGUILayout.EndHorizontal();

		if ( GUILayout.Button("Centre Shape") )
		{
			shape.Centre(1.0f, Vector3.one);
		}

		if ( GUILayout.Button("Apply Scaling") )
		{
			shape.Scale(shape.transform.localScale);
			EditorUtility.SetDirty(target);
			shape.transform.localScale = Vector3.one;
			buildmesh = true;
		}

		if ( GUILayout.Button("Import SVG") )
		{
			LoadSVG(ImportScale);
			buildmesh = true;
		}

		showcommon = EditorGUILayout.Foldout(showcommon, "Common Params");

		bool rebuild = false;	//Params();

		if ( showcommon )
		{
			shape.CursorPercent = EditorGUILayout.FloatField("Cursor", shape.CursorPercent);
			shape.CursorPercent = Mathf.Repeat(shape.CursorPercent, 100.0f);

			ImportScale = EditorGUILayout.FloatField("Import Scale", ImportScale);

			MegaAxis av = (MegaAxis)EditorGUILayout.EnumPopup("Axis", shape.axis);
			if ( av != shape.axis )
			{
				shape.axis = av;
				rebuild = true;
			}

			if ( shape.splines.Count > 1 )
				shape.selcurve = EditorGUILayout.IntSlider("Curve", shape.selcurve, 0, shape.splines.Count - 1);

			if ( shape.selcurve < 0 )
				shape.selcurve = 0;

			if ( shape.selcurve > shape.splines.Count - 1 )
				shape.selcurve = shape.splines.Count - 1;

			EditorGUILayout.BeginHorizontal();
			EditorGUILayout.LabelField("Colors");
			shape.col1 = EditorGUILayout.ColorField(shape.col1);
			shape.col2 = EditorGUILayout.ColorField(shape.col2);
			EditorGUILayout.EndHorizontal();

			shape.VecCol = EditorGUILayout.ColorField("Vec Col", shape.VecCol);

			shape.KnotSize = EditorGUILayout.FloatField("Knot Size", shape.KnotSize);
			shape.stepdist = EditorGUILayout.FloatField("Step Dist", shape.stepdist);

			MegaSpline spline = shape.splines[shape.selcurve];

			if ( shape.stepdist < 0.01f )
				shape.stepdist = 0.01f;

			shape.dolateupdate = EditorGUILayout.Toggle("Do Late Update", shape.dolateupdate);
			shape.normalizedInterp = EditorGUILayout.Toggle("Normalized Interp", shape.normalizedInterp);

			spline.constantSpeed = EditorGUILayout.Toggle("Constant Speed", spline.constantSpeed);
			int subdivs = EditorGUILayout.IntField("Calc Subdivs", spline.subdivs);

			if ( subdivs < 2 )
				subdivs = 2;
			if ( subdivs != spline.subdivs )
				spline.CalcLength(subdivs);

			shape.drawHandles = EditorGUILayout.Toggle("Draw Handles", shape.drawHandles);
			shape.drawKnots = EditorGUILayout.Toggle("Draw Knots", shape.drawKnots);
			shape.drawTwist = EditorGUILayout.Toggle("Draw Twist", shape.drawTwist);
			shape.drawspline = EditorGUILayout.Toggle("Draw Spline", shape.drawspline);
			shape.showorigin = EditorGUILayout.Toggle("Origin Handle", shape.showorigin);
			shape.lockhandles = EditorGUILayout.Toggle("Lock Handles", shape.lockhandles);
			shape.updateondrag = EditorGUILayout.Toggle("Update On Drag", shape.updateondrag);

			shape.usesnap = EditorGUILayout.BeginToggleGroup("Use Snap", shape.usesnap);
			shape.usesnaphandles = EditorGUILayout.Toggle("Snap Handles", shape.usesnaphandles);
			shape.snap = EditorGUILayout.Vector3Field("Snap", shape.snap);
			if ( shape.snap.x < 0.0f ) shape.snap.x = 0.0f;
			if ( shape.snap.y < 0.0f ) shape.snap.y = 0.0f;
			if ( shape.snap.z < 0.0f ) shape.snap.z = 0.0f;
			EditorGUILayout.EndToggleGroup();

			//shape.autosmooth = EditorGUILayout.Toggle("Auto Smooth", shape.autosmooth);
			//shape.smoothness = EditorGUILayout.FloatField("Smoothness", shape.smoothness);
			float smoothness = EditorGUILayout.Slider("Smoothness", shape.smoothness, 0.0f, 1.5f);
			if ( smoothness != shape.smoothness )
			{
				shape.smoothness = smoothness;
				shape.AutoCurve();
				recalc = true;
			}
			shape.smoothonaddknot = EditorGUILayout.Toggle("Smooth on Add Knot", shape.smoothonaddknot);

			shape.handleType = (MegaHandleType)EditorGUILayout.EnumPopup("Handle Type", shape.handleType);

			showlabels = EditorGUILayout.Toggle("Labels", showlabels);

			bool hidewire1 = EditorGUILayout.Toggle("Hide Wire", hidewire);

			if ( hidewire1 != hidewire )
			{
				hidewire = hidewire1;
				EditorUtility.SetSelectedWireframeHidden(shape.GetComponent<Renderer>(), hidewire);
			}

			shape.animate = EditorGUILayout.Toggle("Animate", shape.animate);
			if ( shape.animate )
			{
				shape.time = EditorGUILayout.FloatField("Time", shape.time);
				shape.MaxTime = EditorGUILayout.FloatField("Loop Time", shape.MaxTime);
				shape.speed = EditorGUILayout.FloatField("Speed", shape.speed);
				shape.LoopMode = (MegaRepeatMode)EditorGUILayout.EnumPopup("Loop Mode", shape.LoopMode);
			}

			AnimationKeyFrames(shape);

			if ( shape.splines.Count > 0 )
			{
				if ( spline.outlineSpline != -1 )
				{
					int outlineSpline = EditorGUILayout.IntSlider("Outline Spl", spline.outlineSpline, 0, shape.splines.Count - 1);
					float outline = EditorGUILayout.FloatField("Outline", spline.outline);

					if ( outline != spline.outline || outlineSpline != spline.outlineSpline )
					{
						spline.outlineSpline = outlineSpline;
						spline.outline = outline;
						if ( outlineSpline != shape.selcurve )
						{
							shape.OutlineSpline(shape.splines[spline.outlineSpline], spline, spline.outline, true);
							spline.CalcLength();	//10);
							EditorUtility.SetDirty(target);
							buildmesh = true;
						}
					}
				}
				else
				{
					outline = EditorGUILayout.FloatField("Outline", outline);

					if ( GUILayout.Button("Outline") )
					{
						shape.OutlineSpline(shape, shape.selcurve, outline, true);
						shape.splines[shape.splines.Count - 1].outline = outline;
						shape.splines[shape.splines.Count - 1].outlineSpline = shape.selcurve;
						shape.selcurve = shape.splines.Count - 1;
						EditorUtility.SetDirty(target);
						buildmesh = true;
					}
				}
			}

			// Mesher
			shape.makeMesh = EditorGUILayout.Toggle("Make Mesh", shape.makeMesh);

			if ( shape.makeMesh )
			{
				shape.meshType = (MeshShapeType)EditorGUILayout.EnumPopup("Mesh Type", shape.meshType);
				shape.Pivot = EditorGUILayout.Vector3Field("Pivot", shape.Pivot);

				shape.CalcTangents = EditorGUILayout.Toggle("Calc Tangents", shape.CalcTangents);
				shape.GenUV = EditorGUILayout.Toggle("Gen UV", shape.GenUV);

				if ( GUILayout.Button("Build LightMap") )
				{
					MegaShapeLightMapWindow.Init();
				}

				EditorGUILayout.BeginVertical("Box");
				switch ( shape.meshType )
				{
					case MeshShapeType.Fill:
						shape.DoubleSided = EditorGUILayout.Toggle("Double Sided", shape.DoubleSided);
						shape.Height = EditorGUILayout.FloatField("Height", shape.Height);
						shape.UseHeightCurve = EditorGUILayout.Toggle("Use Height Crv", shape.UseHeightCurve);
						if ( shape.UseHeightCurve )
						{
							shape.heightCrv = EditorGUILayout.CurveField("Height Curve", shape.heightCrv);
							shape.heightOff = EditorGUILayout.Slider("Height Off", shape.heightOff, -1.0f, 1.0f);
						}
						shape.mat1 = (Material)EditorGUILayout.ObjectField("Top Mat", shape.mat1, typeof(Material), true);
						shape.mat2 = (Material)EditorGUILayout.ObjectField("Bot Mat", shape.mat2, typeof(Material), true);
						shape.mat3 = (Material)EditorGUILayout.ObjectField("Side Mat", shape.mat3, typeof(Material), true);

						shape.PhysUV = EditorGUILayout.Toggle("Physical UV", shape.PhysUV);
						shape.UVOffset = EditorGUILayout.Vector2Field("UV Offset", shape.UVOffset);
						shape.UVRotate = EditorGUILayout.Vector2Field("UV Rotate", shape.UVRotate);
						shape.UVScale = EditorGUILayout.Vector2Field("UV Scale", shape.UVScale);
						shape.UVOffset1 = EditorGUILayout.Vector2Field("UV Offset1", shape.UVOffset1);
						shape.UVRotate1 = EditorGUILayout.Vector2Field("UV Rotate1", shape.UVRotate1);
						shape.UVScale1 = EditorGUILayout.Vector2Field("UV Scale1", shape.UVScale1);
						break;

					case MeshShapeType.Tube:
						shape.TubeStart = EditorGUILayout.Slider("Start", shape.TubeStart, -1.0f, 2.0f);
						shape.TubeLength = EditorGUILayout.Slider("Length", shape.TubeLength, 0.0f, 1.0f);
						shape.rotate = EditorGUILayout.FloatField("Rotate", shape.rotate);
						shape.tsides = EditorGUILayout.IntField("Sides", shape.tsides);
						shape.tradius = EditorGUILayout.FloatField("Radius", shape.tradius);
						shape.offset = EditorGUILayout.FloatField("Offset", shape.offset);

						shape.scaleX = EditorGUILayout.CurveField("Scale X", shape.scaleX);
						shape.unlinkScale = EditorGUILayout.BeginToggleGroup("unlink Scale", shape.unlinkScale);
						shape.scaleY = EditorGUILayout.CurveField("Scale Y", shape.scaleY);
						EditorGUILayout.EndToggleGroup();

						shape.strands = EditorGUILayout.IntField("Strands", shape.strands);
						if ( shape.strands > 1 )
						{
							shape.strandRadius = EditorGUILayout.FloatField("Strand Radius", shape.strandRadius);
							shape.TwistPerUnit = EditorGUILayout.FloatField("Twist", shape.TwistPerUnit);
							shape.startAng = EditorGUILayout.FloatField("Start Twist", shape.startAng);
						}
						shape.UVOffset = EditorGUILayout.Vector2Field("UV Offset", shape.UVOffset);
						shape.uvtilex = EditorGUILayout.FloatField("UV Tile X", shape.uvtilex);
						shape.uvtiley = EditorGUILayout.FloatField("UV Tile Y", shape.uvtiley);

						shape.cap = EditorGUILayout.Toggle("Cap", shape.cap);
						shape.RopeUp = (MegaAxis)EditorGUILayout.EnumPopup("Up", shape.RopeUp);
						shape.mat1 = (Material)EditorGUILayout.ObjectField("Mat", shape.mat1, typeof(Material), true);
						shape.flipNormals = EditorGUILayout.Toggle("Flip Normals", shape.flipNormals);
						break;

					case MeshShapeType.Ribbon:
						shape.TubeStart = EditorGUILayout.Slider("Start", shape.TubeStart, -1.0f, 2.0f);
						shape.TubeLength = EditorGUILayout.Slider("Length", shape.TubeLength, 0.0f, 1.0f);
						shape.boxwidth = EditorGUILayout.FloatField("Width", shape.boxwidth);
						shape.raxis = (MegaAxis)EditorGUILayout.EnumPopup("Axis", shape.raxis);
						shape.rotate = EditorGUILayout.FloatField("Rotate", shape.rotate);
						shape.ribsegs = EditorGUILayout.IntField("Segs", shape.ribsegs);
						if ( shape.ribsegs < 1 )
							shape.ribsegs = 1;
						shape.offset = EditorGUILayout.FloatField("Offset", shape.offset);

						shape.scaleX = EditorGUILayout.CurveField("Scale X", shape.scaleX);

						shape.strands = EditorGUILayout.IntField("Strands", shape.strands);
						if ( shape.strands > 1 )
						{
							shape.strandRadius = EditorGUILayout.FloatField("Strand Radius", shape.strandRadius);
							shape.TwistPerUnit = EditorGUILayout.FloatField("Twist", shape.TwistPerUnit);
							shape.startAng = EditorGUILayout.FloatField("Start Twist", shape.startAng);
						}

						shape.UVOffset = EditorGUILayout.Vector2Field("UV Offset", shape.UVOffset);
						shape.uvtilex = EditorGUILayout.FloatField("UV Tile X", shape.uvtilex);
						shape.uvtiley = EditorGUILayout.FloatField("UV Tile Y", shape.uvtiley);

						shape.RopeUp = (MegaAxis)EditorGUILayout.EnumPopup("Up", shape.RopeUp);
						shape.mat1 = (Material)EditorGUILayout.ObjectField("Mat", shape.mat1, typeof(Material), true);
						shape.flipNormals = EditorGUILayout.Toggle("Flip Normals", shape.flipNormals);
						break;

					case MeshShapeType.Box:
						shape.TubeStart = EditorGUILayout.Slider("Start", shape.TubeStart, -1.0f, 2.0f);
						shape.TubeLength = EditorGUILayout.Slider("Length", shape.TubeLength, 0.0f, 1.0f);
						shape.rotate = EditorGUILayout.FloatField("Rotate", shape.rotate);
						shape.boxwidth = EditorGUILayout.FloatField("Box Width", shape.boxwidth);
						shape.boxheight = EditorGUILayout.FloatField("Box Height", shape.boxheight);
						shape.offset = EditorGUILayout.FloatField("Offset", shape.offset);

						shape.scaleX = EditorGUILayout.CurveField("Scale X", shape.scaleX);
						shape.unlinkScale = EditorGUILayout.BeginToggleGroup("unlink Scale", shape.unlinkScale);
						shape.scaleY = EditorGUILayout.CurveField("Scale Y", shape.scaleY);
						EditorGUILayout.EndToggleGroup();

						shape.strands = EditorGUILayout.IntField("Strands", shape.strands);
						if ( shape.strands > 1 )
						{
							shape.tradius = EditorGUILayout.FloatField("Radius", shape.tradius);
							shape.TwistPerUnit = EditorGUILayout.FloatField("Twist", shape.TwistPerUnit);
							shape.startAng = EditorGUILayout.FloatField("Start Twist", shape.startAng);
						}

						shape.UVOffset = EditorGUILayout.Vector2Field("UV Offset", shape.UVOffset);
						shape.uvtilex = EditorGUILayout.FloatField("UV Tile X", shape.uvtilex);
						shape.uvtiley = EditorGUILayout.FloatField("UV Tile Y", shape.uvtiley);

						shape.cap = EditorGUILayout.Toggle("Cap", shape.cap);
						shape.RopeUp = (MegaAxis)EditorGUILayout.EnumPopup("Up", shape.RopeUp);
						shape.mat1 = (Material)EditorGUILayout.ObjectField("Mat", shape.mat1, typeof(Material), true);
						shape.flipNormals = EditorGUILayout.Toggle("Flip Normals", shape.flipNormals);
						break;
				}

				if ( shape.strands < 1 )
					shape.strands = 1;

				EditorGUILayout.EndVertical();

				// Conform
				shape.conform = EditorGUILayout.BeginToggleGroup("Conform", shape.conform);

				GameObject contarget = (GameObject)EditorGUILayout.ObjectField("Target", shape.target, typeof(GameObject), true);

				if ( contarget != shape.target )
					shape.SetTarget(contarget);
				shape.conformAmount = EditorGUILayout.Slider("Amount", shape.conformAmount, 0.0f, 1.0f);
				shape.raystartoff = EditorGUILayout.FloatField("Ray Start Off", shape.raystartoff);
				shape.conformOffset = EditorGUILayout.FloatField("Conform Offset", shape.conformOffset);
				shape.raydist = EditorGUILayout.FloatField("Ray Dist", shape.raydist);
				EditorGUILayout.EndToggleGroup();
			}
			else
			{
				shape.ClearMesh();
			}

			showsplines = EditorGUILayout.Foldout(showsplines, "Spline Data");

			if ( showsplines )
			{
				EditorGUILayout.BeginVertical("Box");
				if ( shape.splines != null && shape.splines.Count > 0 )
					DisplaySpline(shape, shape.splines[shape.selcurve]);
				EditorGUILayout.EndVertical();
			}

			EditorGUILayout.BeginHorizontal();

			Color col = GUI.backgroundColor;
			GUI.backgroundColor = Color.green;
			if ( GUILayout.Button("Add") )
			{
				// Create a new spline in the shape
				MegaSpline spl = MegaSpline.Copy(shape.splines[shape.selcurve]);

				shape.splines.Add(spl);
				shape.selcurve = shape.splines.Count - 1;
				EditorUtility.SetDirty(shape);
				buildmesh = true;
			}

			if ( shape.splines.Count > 1 )
			{
				GUI.backgroundColor = Color.red;
				if ( GUILayout.Button("Delete") )
				{
					// Delete current spline
					shape.splines.RemoveAt(shape.selcurve);


					for ( int i = 0; i < shape.splines.Count; i++ )
					{
						if ( shape.splines[i].outlineSpline == shape.selcurve )
							shape.splines[i].outlineSpline = -1;

						if ( shape.splines[i].outlineSpline > shape.selcurve )
							shape.splines[i].outlineSpline--;
					}

					shape.selcurve--;
					if ( shape.selcurve < 0 )
						shape.selcurve = 0;

					EditorUtility.SetDirty(shape);
					buildmesh = true;
				}
			}
			GUI.backgroundColor = col;
			EditorGUILayout.EndHorizontal();
		}

		if ( !shape.imported )
		{
			if ( Params() )
			{
				rebuild = true;
			}
		}

		showfuncs = EditorGUILayout.Foldout(showfuncs, "Extra Functions");

		if ( showfuncs )
		{
			if ( GUILayout.Button("Flatten") )
			{
				shape.SetHeight(shape.selcurve, 0.0f);
				shape.CalcLength();
				EditorUtility.SetDirty(target);
			}

			if ( GUILayout.Button("Remove Twist") )
			{
				shape.SetTwist(shape.selcurve, 0.0f);
				EditorUtility.SetDirty(target);
			}

			if ( GUILayout.Button("Copy IDS") )
			{
				shape.CopyIDS(shape.selcurve);
				EditorUtility.SetDirty(target);
			}
		}

		export = EditorGUILayout.Foldout(export, "Export Options");

		if ( export )
		{
			xaxis = (MegaAxis)EditorGUILayout.EnumPopup("X Axis", xaxis);
			yaxis = (MegaAxis)EditorGUILayout.EnumPopup("Y Axis", yaxis);

			strokewidth = EditorGUILayout.FloatField("Stroke Width", strokewidth);
			strokecol = EditorGUILayout.ColorField("Stroke Color", strokecol);

			if ( GUILayout.Button("Export") )
			{
				Export(shape);
			}
		}

		if ( recalc )
		{
			shape.CalcLength();	//10);

			shape.BuildMesh();

			//MegaLoftLayerSimple[] layers = (MegaLoftLayerSimple[])FindObjectsOfType(typeof(MegaLoftLayerSimple));

			//for ( int i = 0; i < layers.Length; i++ )
			//{
				//layers[i].Notify(shape.splines[shape.selcurve], 0);
			//}

			EditorUtility.SetDirty(shape);
		}

		if ( GUI.changed )
		{
			EditorUtility.SetDirty(target);
			buildmesh = true;
		}

		if ( rebuild )
		{
			shape.MakeShape();
			EditorUtility.SetDirty(target);
			buildmesh = true;
		}

		if ( buildmesh )
		{
			if ( shape.makeMesh )
			{
				shape.SetMats();
				shape.BuildMesh();
			}
		}

		//undoManager.CheckDirty();
	}
    public void OnSceneGUI()
    {
        //Undo.RegisterUndo(target, "Move Shape Points");
        //undoManager.CheckUndo(target);
        //Undo.CreateSnapshot();

        MegaShape shape = (MegaShape)target;

        Handles.matrix = Matrix4x4.identity;            //shape.transform.localToWorldMatrix;

        //Quaternion rot = shape.transform.rotation;
        //Vector3 trans = shape.transform.position;
        Matrix4x4 tm = shape.transform.localToWorldMatrix;              //Matrix4x4.TRS(trans, rot, Vector3.one);

        if (shape.selcurve > shape.splines.Count - 1)
        {
            shape.selcurve = 0;
        }

        bool recalc = false;

        Vector3 dragplane = Vector3.one;

        Color nocol = new Color(0, 0, 0, 0);

        for (int s = 0; s < shape.splines.Count; s++)
        {
            for (int p = 0; p < shape.splines[s].knots.Count; p++)
            {
                if (shape.drawKnots && s == shape.selcurve)
                {
                    pm = tm.MultiplyPoint(shape.splines[s].knots[p].p);

                    if (showlabels)
                    {
                        if (p == selected && s == shape.selcurve)
                        {
                            Handles.color = Color.white;
                            Handles.Label(pm, " Selected\n" + pm.ToString("0.000"));
                        }
                        else
                        {
                            Handles.color = shape.KnotCol;
                            Handles.Label(pm, " " + p);
                        }
                    }

                    Handles.color = nocol;
                    Vector3 newp = Handles.PositionHandle(pm, Quaternion.identity);
                    if (newp != pm)
                    {
                        Undo.SetSnapshotTarget(shape, "Knot Move");
                    }

                    Vector3 dl = Vector3.Scale(newp - pm, dragplane);
                    shape.splines[s].knots[p].p += dl;                          //Vector3.Scale(newp - pm, dragplane);

                    //delta = shape.splines[s].knots[p].p - pm;

                    shape.splines[s].knots[p].invec  += dl;                     //delta;
                    shape.splines[s].knots[p].outvec += dl;                     //delta;

                    //if ( shape.splines[s].knots[p].p != pm )
                    if (newp != pm)
                    {
                        selected = p;
                        recalc   = true;
                    }

                    //pm = shape.splines[s].knots[p].p;
                }

#if true
                if (shape.drawHandles && s == shape.selcurve)
                {
                    Handles.color = shape.VecCol;
                    pm            = tm.MultiplyPoint(shape.splines[s].knots[p].p);

                    Vector3 ip = tm.MultiplyPoint(shape.splines[s].knots[p].invec);
                    Vector3 op = tm.MultiplyPoint(shape.splines[s].knots[p].outvec);
                    Handles.DrawLine(pm, ip);
                    Handles.DrawLine(pm, op);

                    Handles.color = shape.HandleCol;

                    Vector3 invec = tm.MultiplyPoint(shape.splines[s].knots[p].invec);
                    Handles.color = nocol;
                    Vector3 newinvec = Handles.PositionHandle(invec, Quaternion.identity);

                    if (newinvec != invec)                              //shape.splines[s].knots[p].invec )
                    {
                        Undo.SetSnapshotTarget(shape, "Handle Move");
                    }
                    Vector3 dl = Vector3.Scale(newinvec - invec, dragplane);
                    shape.splines[s].knots[p].invec += dl;              //Vector3.Scale(newinvec - invec, dragplane);
                    if (invec != newinvec)                              //shape.splines[s].knots[p].invec )
                    {
                        if (shape.lockhandles)
                        {
                            //Vector3 d = invec - shape.splines[s].knots[p].invec;
                            shape.splines[s].knots[p].outvec -= dl;
                        }

                        //shape.splines[s].knots[p].invec = invec;
                        selected = p;
                        recalc   = true;
                    }
                    Vector3 outvec = tm.MultiplyPoint(shape.splines[s].knots[p].outvec);

                    Vector3 newoutvec = Handles.PositionHandle(outvec, Quaternion.identity);
                    if (newoutvec != outvec)                            //shape.splines[s].knots[p].outvec )
                    {
                        Undo.SetSnapshotTarget(shape, "Handle Move");
                    }
                    dl = Vector3.Scale(newoutvec - outvec, dragplane);
                    //outvec += dl;	//Vector3.Scale(newoutvec - outvec, dragplane);
                    shape.splines[s].knots[p].outvec += dl;
                    if (outvec != newoutvec)                            //shape.splines[s].knots[p].outvec )
                    {
                        if (shape.lockhandles)
                        {
                            //Vector3 d = outvec - shape.splines[s].knots[p].outvec;
                            shape.splines[s].knots[p].invec -= dl;
                        }

                        //shape.splines[s].knots[p].outvec = outvec;
                        selected = p;
                        recalc   = true;
                    }
                    Vector3 hp = tm.MultiplyPoint(shape.splines[s].knots[p].invec);
                    if (selected == p)
                    {
                        Handles.Label(hp, " " + p);
                    }

                    hp = tm.MultiplyPoint(shape.splines[s].knots[p].outvec);

                    if (selected == p)
                    {
                        Handles.Label(hp, " " + p);
                    }
                }
#endif
            }
        }

        // Draw nearest point (use for adding knot)
        Vector3 wcp          = tm.MultiplyPoint(CursorPos);
        Vector3 newCursorPos = Handles.PositionHandle(wcp, Quaternion.identity);

        if (newCursorPos != wcp)
        {
            Vector3 cd = newCursorPos - wcp;

            CursorPos += cd;

            float calpha = 0.0f;
            CursorPos     = shape.FindNearestPoint(CursorPos, 5, ref CursorKnot, ref CursorTangent, ref calpha);
            CursorPercent = calpha * 100.0f;
        }

        Handles.Label(tm.MultiplyPoint(CursorPos), "Cursor " + CursorPercent.ToString("0.00") + "% - " + CursorPos);

        if (recalc)
        {
            shape.CalcLength(10);
            shape.BuildMesh();
        }

        Handles.matrix = Matrix4x4.identity;
        //undoManager.CheckDirty(target);

        if (GUI.changed)
        {
            //Undo.RegisterCreatedObjectUndo(shape, "plop");
            Undo.CreateSnapshot();
            Undo.RegisterSnapshot();
        }

        Undo.ClearSnapshotTarget();
    }
    void Update()
    {
        if (building)
        {
            Ray mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);

            RaycastHit info;

            bool hit = Physics.Raycast(mouseRay, out info);

            if (Input.GetMouseButtonUp(0) || hit == false)
            {
                building = false;

                // Finish of line and make spline
                if (ValidSpline())
                {
                    FinishSpline(obj, lasthitpos);
                }
                else
                {
                    Destroy(obj);
                }

                obj     = null;
                cspline = null;
                cshape  = null;
            }
            else
            {
                if (hit)
                {
                    Vector3 hp = info.point;
                    hp.y += offset;

                    float dist = Vector3.Distance(lasthitpos, hp);

                    travelled += dist;

                    if (travelled > updatedist)
                    {
                        cspline.AddKnot(cshape.transform.worldToLocalMatrix.MultiplyPoint3x4(hp), Vector3.zero, Vector3.zero);
                        cshape.AutoCurve();
                        travelled -= updatedist;
                    }
                    else
                    {
                        cspline.knots[cspline.knots.Count - 1].p = cshape.transform.worldToLocalMatrix.MultiplyPoint3x4(hp);
                        cshape.AutoCurve();

                        if (cspline.knots.Count == 2)
                        {
                            float dist1 = cspline.KnotDistance(0, 1);

                            if (dist1 > 0.1f)
                            {
                                cshape.BuildMesh();
                            }
                        }
                        else
                        {
                            if (cspline.knots.Count > 2)
                            {
                                cshape.BuildMesh();
                            }
                        }
                    }

                    lasthitpos = hp;
                }
            }
        }
        else
        {
            if (Input.GetMouseButtonDown(0))
            {
                Ray mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);

                RaycastHit info;

                bool hit = Physics.Raycast(mouseRay, out info);
                if (hit)
                {
                    Vector3 hp = info.point;
                    hp.y += offset;

                    lasthitpos = hp;
                    travelled  = 0.0f;

                    obj      = CreateSpline(hp);
                    building = true;
                }
            }
        }
    }