var bezierPatch = new Array(
    new Array(new Vec3D(-0.00010714300151448697,0.20535700023174286,0),new Vec3D(0,0.19642899930477142,-0.017857100814580917),new Vec3D(0,0.19642899930477142,-0.017857100814580917),new Vec3D(0.00010714300151448697,0.20535700023174286,0),new Vec3D(-0.05357139930129051,0.20535700023174286,0),new Vec3D(-0.022271400317549706,0.17857100069522858,-0.05342860147356987),new Vec3D(0.022271400317549706,0.17857100069522858,-0.05342860147356987),new Vec3D(0.05357139930129051,0.20535700023174286,0),new Vec3D(-0.10714299976825714,0.09524290263652802,-0.017857100814580917),new Vec3D(-0.04464289918541908,0.09524290263652802,-0.0892857015132904),new Vec3D(0.04464289918541908,0.09524290263652802,-0.0892857015132904),new Vec3D(0.10714299976825714,0.09524290263652802,-0.017857100814580917),new Vec3D(-0.10714299976825714,0,-0.017857100814580917),new Vec3D(-0.04464289918541908,0,-0.0892857015132904),new Vec3D(0.04464289918541908,0,-0.0892857015132904),new Vec3D(0.10714299976825714,0,-0.017857100814580917)),
    new Array(new Vec3D(0.00010714300151448697,0.20535700023174286,0),new Vec3D(0.0001357139990432188,0.20758900046348572,0.004464290104806423),new Vec3D(0.00015714300388935953,0.21651799976825714,0.004464290104806423),new Vec3D(0.0001250000059371814,0.21428599953651428,0),new Vec3D(0.05357139930129051,0.20535700023174286,0),new Vec3D(0.06139640137553215,0.21205399930477142,0.013357100076973438),new Vec3D(0.07142859697341919,0.22098200023174286,0.015625),new Vec3D(0.0625,0.21428599953651428,0),new Vec3D(0.10714299976825714,0.09524290263652802,-0.017857100814580917),new Vec3D(0.12276799976825714,0.09524290263652802,0),new Vec3D(0.14285700023174286,0.09524290263652802,0.004464290104806423),new Vec3D(0.125,0.09524290263652802,-0.017857100814580917),new Vec3D(0.10714299976825714,0,-0.017857100814580917),new Vec3D(0.12276799976825714,0,0),new Vec3D(0.14285700023174286,0,0.004464290104806423),new Vec3D(0.125,0,-0.017857100814580917)),
    new Array(new Vec3D(0.0001250000059371814,0.21428599953651428,0),new Vec3D(0,0.20535700023174286,-0.017857100814580917),new Vec3D(0,0.20535700023174286,-0.017857100814580917),new Vec3D(-0.0001250000059371814,0.21428599953651428,0),new Vec3D(0.0625,0.21428599953651428,0),new Vec3D(0.026785699650645256,0.1875,-0.0625),new Vec3D(-0.026785699650645256,0.1875,-0.0625),new Vec3D(-0.0625,0.21428599953651428,0),new Vec3D(0.125,0.09524290263652802,-0.017857100814580917),new Vec3D(0.05357139930129051,0.09524290263652802,-0.10714299976825714),new Vec3D(-0.05357139930129051,0.09524290263652802,-0.10714299976825714),new Vec3D(-0.125,0.09524290263652802,-0.017857100814580917),new Vec3D(0.125,0,-0.017857100814580917),new Vec3D(0.05357139930129051,0,-0.10714299976825714),new Vec3D(-0.05357139930129051,0,-0.10714299976825714),new Vec3D(-0.125,0,-0.017857100814580917)),
    new Array(new Vec3D(-0.0001250000059371814,0.21428599953651428,0),new Vec3D(-0.00015714300388935953,0.21651799976825714,0.004464290104806423),new Vec3D(-0.0001357139990432188,0.20758900046348572,0.004464290104806423),new Vec3D(-0.00010714300151448697,0.20535700023174286,0),new Vec3D(-0.0625,0.21428599953651428,0),new Vec3D(-0.07142859697341919,0.22098200023174286,0.015625),new Vec3D(-0.06139640137553215,0.21205399930477142,0.013357100076973438),new Vec3D(-0.05357139930129051,0.20535700023174286,0),new Vec3D(-0.125,0.09524290263652802,-0.017857100814580917),new Vec3D(-0.14285700023174286,0.09524290263652802,0.004464290104806423),new Vec3D(-0.12276799976825714,0.09524290263652802,0),new Vec3D(-0.10714299976825714,0.09524290263652802,-0.017857100814580917),new Vec3D(-0.125,0,-0.017857100814580917),new Vec3D(-0.14285700023174286,0,0.004464290104806423),new Vec3D(-0.12276799976825714,0,0),new Vec3D(-0.10714299976825714,0,-0.017857100814580917)),
    new Array(new Vec3D(-0.10714299976825714,0,-0.017857100814580917),new Vec3D(-0.04464289918541908,0,-0.0892857015132904),new Vec3D(0.04464289918541908,0,-0.0892857015132904),new Vec3D(0.10714299976825714,0,-0.017857100814580917),new Vec3D(-0.10714299976825714,-0.14285700023174286,-0.017857100814580917),new Vec3D(-0.04464289918541908,-0.14285700023174286,-0.0892857015132904),new Vec3D(0.04464289918541908,-0.14285700023174286,-0.0892857015132904),new Vec3D(0.10714299976825714,-0.14285700023174286,-0.017857100814580917),new Vec3D(-0.013392900116741657,-0.16071400046348572,0.038689300417900085),new Vec3D(-0.005578570067882538,-0.16071400046348572,0.038689300417900085),new Vec3D(0.005578570067882538,-0.16071400046348572,0.038689300417900085),new Vec3D(0.013392900116741657,-0.16071400046348572,0.038689300417900085),new Vec3D(-0.013392900116741657,-0.25,0.05357139930129051),new Vec3D(-0.005578570067882538,-0.25,0.05357139930129051),new Vec3D(0.005578570067882538,-0.25,0.05357139930129051),new Vec3D(0.013392900116741657,-0.25,0.05357139930129051)),
    new Array(new Vec3D(0.10714299976825714,0,-0.017857100814580917),new Vec3D(0.12276799976825714,0,0),new Vec3D(0.14285700023174286,0,0.004464290104806423),new Vec3D(0.125,0,-0.017857100814580917),new Vec3D(0.10714299976825714,-0.14285700023174286,-0.017857100814580917),new Vec3D(0.12276799976825714,-0.14285700023174286,0),new Vec3D(0.14285700023174286,-0.14285700023174286,0.004464290104806423),new Vec3D(0.125,-0.14285700023174286,-0.017857100814580917),new Vec3D(0.013392900116741657,-0.16071400046348572,0.038689300417900085),new Vec3D(0.015346400439739227,-0.16071400046348572,0.038689300417900085),new Vec3D(0.017857100814580917,-0.16071400046348572,0.03143569827079773),new Vec3D(0.015625,-0.16071400046348572,0.029760699719190598),new Vec3D(0.013392900116741657,-0.25,0.05357139930129051),new Vec3D(0.015346400439739227,-0.25,0.05357139930129051),new Vec3D(0.017857100814580917,-0.25,0.04631790146231651),new Vec3D(0.015625,-0.25,0.04464289918541908)),
    new Array(new Vec3D(0.125,0,-0.017857100814580917),new Vec3D(0.05357139930129051,0,-0.10714299976825714),new Vec3D(-0.05357139930129051,0,-0.10714299976825714),new Vec3D(-0.125,0,-0.017857100814580917),new Vec3D(0.125,-0.14285700023174286,-0.017857100814580917),new Vec3D(0.05357139930129051,-0.14285700023174286,-0.10714299976825714),new Vec3D(-0.05357139930129051,-0.14285700023174286,-0.10714299976825714),new Vec3D(-0.125,-0.14285700023174286,-0.017857100814580917),new Vec3D(0.015625,-0.16071400046348572,0.029760699719190598),new Vec3D(0.006696430034935474,-0.16071400046348572,0.023064300417900085),new Vec3D(-0.007810709998011589,-0.16071400046348572,0.02083210088312626),new Vec3D(-0.015625,-0.16071400046348572,0.029760699719190598),new Vec3D(0.015625,-0.25,0.04464289918541908),new Vec3D(0.006696430034935474,-0.25,0.03794639930129051),new Vec3D(-0.007810709998011589,-0.25,0.035714298486709595),new Vec3D(-0.015625,-0.25,0.04464289918541908)),
    new Array(new Vec3D(-0.125,0,-0.017857100814580917),new Vec3D(-0.14285700023174286,0,0.004464290104806423),new Vec3D(-0.12276799976825714,0,0),new Vec3D(-0.10714299976825714,0,-0.017857100814580917),new Vec3D(-0.125,-0.14285700023174286,-0.017857100814580917),new Vec3D(-0.14285700023174286,-0.14285700023174286,0.004464290104806423),new Vec3D(-0.12276799976825714,-0.14285700023174286,0),new Vec3D(-0.10714299976825714,-0.14285700023174286,-0.017857100814580917),new Vec3D(-0.015625,-0.16071400046348572,0.029760699719190598),new Vec3D(-0.017578599974513054,-0.16071400046348572,0.03199290111660957),new Vec3D(-0.015346400439739227,-0.16071400046348572,0.038689300417900085),new Vec3D(-0.013392900116741657,-0.16071400046348572,0.038689300417900085),new Vec3D(-0.015625,-0.25,0.04464289918541908),new Vec3D(-0.017578599974513054,-0.25,0.046875),new Vec3D(-0.015346400439739227,-0.25,0.05357139930129051),new Vec3D(-0.013392900116741657,-0.25,0.05357139930129051)),
    new Array(new Vec3D(-0.013392900116741657,-0.25,0.05357139930129051),new Vec3D(-0.005578570067882538,-0.25,0.05357139930129051),new Vec3D(0.005578570067882538,-0.25,0.05357139930129051),new Vec3D(0.013392900116741657,-0.25,0.05357139930129051),new Vec3D(-0.013392900116741657,-0.46424999833106995,0.0892857015132904),new Vec3D(-0.005578570067882538,-0.46424999833106995,0.0892857015132904),new Vec3D(0.005578570067882538,-0.46424999833106995,0.0892857015132904),new Vec3D(0.013392900116741657,-0.46424999833106995,0.0892857015132904),new Vec3D(-0.04464289918541908,-0.6785709857940674,0.05357139930129051),new Vec3D(-0.008928569965064526,-0.6785709857940674,0.0625),new Vec3D(0.008928569965064526,-0.6785709857940674,0.0625),new Vec3D(0.04464289918541908,-0.6785709857940674,0.05357139930129051),new Vec3D(-0.04464289918541908,-0.857142984867096,0.035714298486709595),new Vec3D(-0.008928569965064526,-0.857142984867096,0.04464289918541908),new Vec3D(0.008928569965064526,-0.857142984867096,0.04464289918541908),new Vec3D(0.04464289918541908,-0.857142984867096,0.035714298486709595)),
    new Array(new Vec3D(0.013392900116741657,-0.25,0.05357139930129051),new Vec3D(0.015346400439739227,-0.25,0.05357139930129051),new Vec3D(0.017857100814580917,-0.25,0.04631790146231651),new Vec3D(0.015625,-0.25,0.04464289918541908),new Vec3D(0.013392900116741657,-0.46424999833106995,0.0892857015132904),new Vec3D(0.015346400439739227,-0.4642859995365143,0.0892857015132904),new Vec3D(0.017857100814580917,-0.46424999833106995,0.08203209936618805),new Vec3D(0.015625,-0.46424999833106995,0.08035709708929062),new Vec3D(0.04464289918541908,-0.6785709857940674,0.05357139930129051),new Vec3D(0.05357139930129051,-0.6785709857940674,0.051339298486709595),new Vec3D(0.05357139930129051,-0.6785709857940674,0.03348210081458092),new Vec3D(0.04464289918541908,-0.6785709857940674,0.035714298486709595),new Vec3D(0.04464289918541908,-0.857142984867096,0.035714298486709595),new Vec3D(0.05357139930129051,-0.857142984867096,0.03348210081458092),new Vec3D(0.05357139930129051,-0.857142984867096,0.015625),new Vec3D(0.04464289918541908,-0.857142984867096,0.017857100814580917)),
    new Array(new Vec3D(0.015625,-0.25,0.04464289918541908),new Vec3D(0.006696430034935474,-0.25,0.03794639930129051),new Vec3D(-0.007810709998011589,-0.25,0.035714298486709595),new Vec3D(-0.015625,-0.25,0.04464289918541908),new Vec3D(0.015625,-0.46424999833106995,0.08035709708929062),new Vec3D(0.006696430034935474,-0.4642859995365143,0.0736607015132904),new Vec3D(-0.007810709998011589,-0.46424999833106995,0.07142859697341919),new Vec3D(-0.015625,-0.46424999833106995,0.08035709708929062),new Vec3D(0.04464289918541908,-0.6785709857940674,0.035714298486709595),new Vec3D(0.008928569965064526,-0.6785709857940674,0.04464289918541908),new Vec3D(-0.008928569965064526,-0.6785709857940674,0.04464289918541908),new Vec3D(-0.04464289918541908,-0.6785709857940674,0.035714298486709595),new Vec3D(0.04464289918541908,-0.857142984867096,0.017857100814580917),new Vec3D(0.008928569965064526,-0.857142984867096,0.026785699650645256),new Vec3D(-0.008928569965064526,-0.857142984867096,0.026785699650645256),new Vec3D(-0.04464289918541908,-0.857142984867096,0.017857100814580917)),
    new Array(new Vec3D(-0.015625,-0.25,0.04464289918541908),new Vec3D(-0.017578599974513054,-0.25,0.046875),new Vec3D(-0.015346400439739227,-0.25,0.05357139930129051),new Vec3D(-0.013392900116741657,-0.25,0.05357139930129051),new Vec3D(-0.015625,-0.46424999833106995,0.08035709708929062),new Vec3D(-0.017578599974513054,-0.4642859995365143,0.0825892984867096),new Vec3D(-0.015346400439739227,-0.4642859995365143,0.0892857015132904),new Vec3D(-0.013392900116741657,-0.46424999833106995,0.0892857015132904),new Vec3D(-0.04464289918541908,-0.6785709857940674,0.035714298486709595),new Vec3D(-0.05357139930129051,-0.6785709857940674,0.03348210081458092),new Vec3D(-0.05357139930129051,-0.6785709857940674,0.051339298486709595),new Vec3D(-0.04464289918541908,-0.6785709857940674,0.05357139930129051),new Vec3D(-0.04464289918541908,-0.857142984867096,0.017857100814580917),new Vec3D(-0.05357139930129051,-0.857142984867096,0.015625),new Vec3D(-0.05357139930129051,-0.857142984867096,0.03348210081458092),new Vec3D(-0.04464289918541908,-0.857142984867096,0.035714298486709595)),
    new Array(new Vec3D(-0.04464289918541908,-0.857142984867096,0.035714298486709595),new Vec3D(-0.008928569965064526,-0.857142984867096,0.04464289918541908),new Vec3D(0.008928569965064526,-0.857142984867096,0.04464289918541908),new Vec3D(0.04464289918541908,-0.857142984867096,0.035714298486709595),new Vec3D(-0.04464289918541908,-0.9285709857940674,0.02857140079140663),new Vec3D(-0.008928569965064526,-0.9285709857940674,0.03750000149011612),new Vec3D(0.008928569965064526,-0.9285709857940674,0.03750000149011612),new Vec3D(0.04464289918541908,-0.9285709857940674,0.02857140079140663),new Vec3D(-0.05392859876155853,-0.9996430277824402,0.017857100814580917),new Vec3D(0.00035714299883693457,-0.9996430277824402,0.017857100814580917),new Vec3D(0,-0.9996430277824402,0.017857100814580917),new Vec3D(0.05357139930129051,-0.9996430277824402,0.017857100814580917),new Vec3D(-0.00035714299883693457,-1,0.017857100814580917),new Vec3D(0.00035714299883693457,-1,0.017857100814580917),new Vec3D(0,-1,0.017857100814580917),new Vec3D(0,-1,0.017857100814580917)),
    new Array(new Vec3D(0.04464289918541908,-0.857142984867096,0.035714298486709595),new Vec3D(0.05357139930129051,-0.857142984867096,0.03348210081458092),new Vec3D(0.05357139930129051,-0.857142984867096,0.015625),new Vec3D(0.04464289918541908,-0.857142984867096,0.017857100814580917),new Vec3D(0.04464289918541908,-0.9285709857940674,0.02857140079140663),new Vec3D(0.05357139930129051,-0.9285709857940674,0.026339299976825714),new Vec3D(0.05357139930129051,-0.9285709857940674,0.008482139557600021),new Vec3D(0.04464289918541908,-0.9285709857940674,0.010714299976825714),new Vec3D(0.05357139930129051,-0.9996430277824402,0.017857100814580917),new Vec3D(0.0669642984867096,-0.9996430277824402,0.017857100814580917),new Vec3D(0.06732139736413956,-0.9996430277824402,0),new Vec3D(0.05392859876155853,-0.9996430277824402,0),new Vec3D(0,-1,0.017857100814580917),new Vec3D(0,-1,0.017857100814580917),new Vec3D(0.00035714299883693457,-1,0),new Vec3D(0.00035714299883693457,-1,0)),
    new Array(new Vec3D(0.04464289918541908,-0.857142984867096,0.017857100814580917),new Vec3D(0.008928569965064526,-0.857142984867096,0.026785699650645256),new Vec3D(-0.008928569965064526,-0.857142984867096,0.026785699650645256),new Vec3D(-0.04464289918541908,-0.857142984867096,0.017857100814580917),new Vec3D(0.04464289918541908,-0.9285709857940674,0.010714299976825714),new Vec3D(0.008928569965064526,-0.9285709857940674,0.019642900675535202),new Vec3D(-0.008928569965064526,-0.9285709857940674,0.019642900675535202),new Vec3D(-0.04464289918541908,-0.9285709857940674,0.010714299976825714),new Vec3D(0.05392859876155853,-0.9996430277824402,0),new Vec3D(0.00035714299883693457,-0.9996430277824402,0),new Vec3D(-0.00035714299883693457,-0.9996430277824402,0),new Vec3D(-0.05392859876155853,-0.9996430277824402,0),new Vec3D(0.00035714299883693457,-1,0),new Vec3D(0.00035714299883693457,-1,0),new Vec3D(-0.00035714299883693457,-1,0),new Vec3D(-0.00035714299883693457,-1,0)),
    new Array(new Vec3D(-0.04464289918541908,-0.857142984867096,0.017857100814580917),new Vec3D(-0.05357139930129051,-0.857142984867096,0.015625),new Vec3D(-0.05357139930129051,-0.857142984867096,0.03348210081458092),new Vec3D(-0.04464289918541908,-0.857142984867096,0.035714298486709595),new Vec3D(-0.04464289918541908,-0.9285709857940674,0.010714299976825714),new Vec3D(-0.05357139930129051,-0.9285709857940674,0.008482139557600021),new Vec3D(-0.05357139930129051,-0.9285709857940674,0.026339299976825714),new Vec3D(-0.04464289918541908,-0.9285709857940674,0.02857140079140663),new Vec3D(-0.05392859876155853,-0.9996430277824402,0),new Vec3D(-0.06732139736413956,-0.9996430277824402,0),new Vec3D(-0.06750000268220901,-0.9996430277824402,0.017857100814580917),new Vec3D(-0.05392859876155853,-0.9996430277824402,0.017857100814580917),new Vec3D(-0.00035714299883693457,-1,0),new Vec3D(-0.00035714299883693457,-1,0),new Vec3D(-0.0005357139743864536,-1,0.017857100814580917),new Vec3D(-0.00035714299883693457,-1,0.017857100814580917))
);

function B3(i, t){
    switch(i){
    case 0:
        return Math.pow((1-t), 3);
    case 1:
        return 3*Math.pow((1-t), 2)*t;
    case 2:
        return 3*(1-t)*Math.pow(t, 2);
    case 3:
        return Math.pow(t, 3);
    }
}

function getBezierPoint(u, v, patchPointArray)
{
    if(patchPointArray.length != 16){
        return false;
    }

    var x = 0;
    var y = 0;
    var z = 0;

    for(i = 0; i < 4; ++i){
        for(j = 0; j < 4; ++j){
            var p = patchPointArray[i+j*4];
            x += B3(i, u)*B3(j, v)*p.x;
            y += B3(i, u)*B3(j, v)*p.y;
            z += B3(i, u)*B3(j, v)*p.z;
        }
    }

    return (new Vec3D(x, y, z));
}


function drawSquare(core, p1, p2, p3, p4)
{
    var p = new Array();
    p.push(p1);
    p.push(p2);
    p.push(p3);
    core.addPolygon( p.length, true, p );

    var p = new Array();
    p.push(p4);
    p.push(p3);
    p.push(p2);
    core.addPolygon( p.length, true, p );
}

function buildUI(obj)
{
    obj.addParameterInt('BezierPatchDivision',6,1,1000,true,true);
    obj.setParameter("name", "TeaSpoon");

    var rot = new Vec3D(0, 270, 0);
    obj.setParameter("rotation", rot, true);

    // print param
    /*     
    print('-- object type:'+obj.type());
    var info = obj.parameterInfo();
    for (var j=0;j<info.length;j++) {
        print(info[j][0] +" [" + info[j][1] + "]:"+obj.getParameter(info[j][0]));
    }
    */

}

function buildObject(obj){

    // Draw
    var core = obj.core();
    var div = obj.getParameter("BezierPatchDivision");
    var add = 1/div;
    var xnum = div+1;

    for(k = 0; k < bezierPatch.length; ++k){

        // compute bezier patch point
        var pa = bezierPatch[k];
        var drawPointArray = new Array();

        for(v = 0, vc = 0; v <= 1 || vc < xnum; v += add, ++vc){
            for(u = 0, uc = 0 ;u <= 1 || uc < xnum; u += add, ++uc){
                var p = getBezierPoint(u, v, pa);
                drawPointArray.push(p);
            }
        }
        //print("drawPointArray:"+drawPointArray.length);

        // draw polygon
        for(y = 0; y < div; ++y){
            for(x = 0; x < div; ++x){
                var p1 = x+y*xnum;
                var p2 = x+1+y*xnum;
                var p3 = x+(y+1)*xnum;
                var p4 = x+1+(y+1)*xnum;
                //print("x:"+x+" y:"+y+" p1:"+p1+" p2:"+p2+" p3:"+p3+" p4:"+p4);
                drawSquare(core, drawPointArray[p1], drawPointArray[p2], drawPointArray[p3], drawPointArray[p4]);
            }
        }
    }

}