cp.cnstr_lhs = [[(0, 0, 1.0)],
                    [(0, 1, 1.0)],
                    [(0, 2, 1.0)],
#                    [(1, 1, 1.0)],
#                    [(1, 2, 1.0)],
                     ]

    cp.cnstr_rhs = [0.0, 0.0, 0.0, ]# 0, 0, 0, ]

    cp.tf_lst = [(caf, [1, 2, 3, 4, 5, 6])]

    x0 = np.zeros((cp.n_dofs), dtype = float)

    print 'initial lengths\n', cp.c_lengths
    print 'initial vectors\n', cp.c_vectors
    print 'initial G\n', cp.get_G(x0)
    print 'initial G_du\n', cp.get_G_du(x0)

    cp.solve(x0)

    # Visualization
    cpv = CreasePatternView(data = cp, show_cnstr = True)

    cpv.configure_traits()


    # 1) introduce the mapping association to the surface
    #    similar to cnstr_face
    # 2) define a rule for mountains and valley nodes.
    # 3) visualize attractor / control surface.
    cp.tf_lst = [(caf, [0, 1, 4])]

    cp.cnstr_lhs = [
        [(0, 0, 1.0)],
        [(0, 1, 1.0)],
        #                    [(1, 1, 1.0)],
        #                    [(1, 2, 1.0)],
    ]

    cp.cnstr_rhs = [0.0, 0.0]  # , 0.0, ]# 0, 0, 0, ]

    x0 = np.zeros((cp.n_dofs), dtype=float)

    print "initial lengths\n", cp.c_lengths
    print "initial vectors\n", cp.c_vectors
    print "initial G\n", cp.get_G(x0)
    print "initial G_du\n", cp.get_G_du(x0)

    cp.solve(x0)

    # Visualization
    cpv = CreasePatternView(data=cp, show_cnstr=True)

    cpv.configure_traits()

    # 1) introduce the mapping association to the surface
    #    similar to cnstr_face
    # 2) define a rule for mountains and valley nodes.
    # 3) visualize attractor / control surface.
                       [ 1, 2 ]]

    cp.cnstr_lhs = [[(0, 0, 1.0)],
                    [(0, 1, 1.0)],
                    [(0, 2, 1.0)],
                    [(2, 0, 1.0)],
                    [(2, 1, 1.0)],
                    [(2, 2, 1.0)], ]

    cp.cnstr_rhs = [0.0, 0.0, 0.0, 0, 0, 0]

    x0 = np.zeros((cp.n_dofs), dtype = float)

    print 'initial lengths\n', cp.c_lengths
    print 'initial vectors\n', cp.c_vectors
    print 'initial G\n', cp.get_G(x0)
    print 'initial G_du\n', cp.get_G_du(x0)

    def f(x):
        x = x.reshape(cp.n_n, cp.n_d)
        X = cp.get_new_nodes(x)
        caf.X_arr = [X[1]]
        dist2 = np.linalg.norm(caf.d_arr)
        return dist2

    d0 = f(x0)
    eps = d0 * 1e-4

    x_sol = fmin_slsqp(f, x0, f_eqcons = cp.get_G, fprime_eqcons = cp.get_G_du, acc = 1e-8,
                       epsilon = eps)
    cp = CreasePattern()

    cp.nodes = [[0, 0, 0], [1, 0, 0], [0.5, -0.5, 0], [0.5, 0.5, 0]]

    cp.crease_lines = [[0, 2], [2, 1], [0, 3], [3, 1], [2, 3]]
    cp.facets = [[0, 3, 2], [1, 2, 3]]

    cp.cnstr_lhs = [[(0, 0, 1.0)], [(0, 1, 1.0)], [(0, 2, 1.0)], [(1, 1, 1.0)], [(1, 2, 1.0)], [(3, 2, 1.0)]]

    cp.cnstr_rhs = [0.0, 0.0, 0.0, 0, 0, 0.2]

    x0 = np.zeros((cp.n_dofs), dtype=float)

    print "initial lengths\n", cp.c_lengths
    print "initial vectors\n", cp.c_vectors
    print "initial R\n", cp.get_G(x0)
    print "initial dR\n", cp.get_G_du(x0)

    def f(x):
        x = x.reshape(cp.n_n, cp.n_d)
        X = cp.get_new_nodes(x)
        caf.X_arr = [X[2]]
        dist2 = np.linalg.norm(caf.d_arr)
        return dist2

    d0 = f(x0)
    eps = d0 * 1e-4

    x_sol = fmin_slsqp(f, x0, f_eqcons=cp.get_G, fprime_eqcons=cp.get_G_du, acc=1e-8, epsilon=eps)

    print "x_sol", x_sol