Esempio n. 1
0
//----------------------------------------------------------------------------
void Skinning::CreateScene ()
{
    mScene = new0 Node();
    mTrnNode = new0 Node();
    mScene->AttachChild(mTrnNode);

    // The skinned object is a cylinder.
    const int radialSamples = 10;
    const int axisSamples = 7;
    const float radius = 10.0f;
    const float height = 80.0f;
    const float invRS = 1.0f/(float)radialSamples;
    const float invASm1 = 1.0f/(float)(axisSamples - 1);
    const float halfHeight = 0.5f*height;
    const APoint center(0.0f, 0.0f, 100.0f);
    const AVector u(0.0f,0.0f,-1.0f);
    const AVector v(0.0f,1.0f,0.0f);
    const AVector axis(1.0f,0.0f,0.0f);

    // Generate geometry.
    VertexFormat* vformat = VertexFormat::Create(3,
                            VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
                            VertexFormat::AU_COLOR, VertexFormat::AT_FLOAT3, 0,
                            VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT4, 0);
    int vstride = vformat->GetStride();
    const int numVertices = axisSamples*(radialSamples + 1);
    VertexBuffer* vbuffer = new0 VertexBuffer(numVertices, vstride);
    VertexBufferAccessor vba(vformat, vbuffer);

    // Generate points on the unit circle to be used in computing the mesh
    // points on a cylinder slice.
    int r, a, aStart, i;
    float* sn = new1<float>(radialSamples + 1);
    float* cs = new1<float>(radialSamples + 1);
    for (r = 0; r < radialSamples; ++r)
    {
        float angle = Mathf::TWO_PI*invRS*r;
        cs[r] = Mathf::Cos(angle);
        sn[r] = Mathf::Sin(angle);
    }
    sn[radialSamples] = sn[0];
    cs[radialSamples] = cs[0];

    // Generate the cylinder itself.
    for (a = 0, i = 0; a < axisSamples; ++a, ++i)
    {
        float axisFraction = a*invASm1;  // in [0,1]
        float z = -halfHeight + height*axisFraction;

        // Compute center of slice.
        APoint sliceCenter = center + z*axis;

        // Compute slice vertices with duplication at end point.
        Float3 color(axisFraction, 1.0f - axisFraction, 0.3f);
        Float4 tcoord;
        int save = i;
        for (r = 0; r < radialSamples; ++r, ++i)
        {
            AVector normal = cs[r]*u + sn[r]*v;
            vba.Position<Float3>(i) = sliceCenter + radius*normal;
            vba.Color<Float3>(0,i) = color;
            vba.TCoord<Float4>(0, i) = ComputeWeights(a);
        }

        vba.Position<Float3>(i) = vba.Position<Float3>(save);
        vba.Color<Float3>(0, i) = color;
        vba.TCoord<Float4>(0, i) = ComputeWeights(a);
    }

    // Generate connectivity.
    int numTriangles = 2*(axisSamples - 1)*radialSamples;
    int numIndices = 3*numTriangles;
    IndexBuffer* ibuffer = new0 IndexBuffer(numIndices, sizeof(int));
    int* indices = (int*)ibuffer->GetData();
    for (a = 0, aStart = 0; a < axisSamples - 1; ++a)
    {
        int i0 = aStart;
        int i1 = i0 + 1;
        aStart += radialSamples + 1;
        int i2 = aStart;
        int i3 = i2 + 1;
        for (i = 0; i < radialSamples; ++i, indices += 6)
        {
            indices[0] = i0++;
            indices[1] = i1;
            indices[2] = i2;
            indices[3] = i1++;
            indices[4] = i3++;
            indices[5] = i2++;
        }
    }

    delete1(cs);
    delete1(sn);

    TriMesh* mesh = new0 TriMesh(vformat, vbuffer, ibuffer);
    mTrnNode->AttachChild(mesh);

    std::string effectFile = Environment::GetPathR("Skinning.wmfx");
    SkinningEffect* effect = new0 SkinningEffect(effectFile);

    ShaderFloat* skinningMatrix[4] =
    {
        new0 ShaderFloat(4),
        new0 ShaderFloat(4),
        new0 ShaderFloat(4),
        new0 ShaderFloat(4)
    };

    for (i = 0; i < 4; ++i)
    {
        mSkinningMatrix[i] = skinningMatrix[i]->GetData();
    }

    mesh->SetEffectInstance(effect->CreateInstance(skinningMatrix));
}
	typename QPBO<REAL>::EdgeId QPBO<REAL>::AddPairwiseTerm(NodeId _i, NodeId _j, REAL E00, REAL E01, REAL E10, REAL E11)
{
	//printf("%d,%d",_i,node_num);
	user_assert(_i >= 0 && _i < node_num);
	user_assert(_j >= 0 && _j < node_num);
	user_assert(_i != _j);

	REAL ci, cj, cij, cji;

	if (!first_free) 
	{
		reallocate_arcs(2*(GetMaxEdgeNum() + GetMaxEdgeNum()/2));
	}

	EdgeId e = (int)(first_free - arcs[IsArc0(first_free) ? 0 : 1])/2;
	first_free = first_free->next;

	if (stage == 0)
	{
		Arc *a, *a_rev;
		a     = &arcs[0][2*e];
		a_rev = &arcs[0][2*e+1];

		Node* i = nodes[0] + _i;
		Node* j = nodes[0] + _j;

		if (E01 + E10 >= E00 + E11)
		{
			ComputeWeights(E00, E01, E10, E11, ci, cj, cij, cji);

			SET_TO(a, j);
			SET_FROM(a,     i);
			SET_FROM(a_rev, j);

			j->tr_cap += cj;
		}
		else
		{
			all_edges_submodular = false;
			ComputeWeights(E01, E00, E11, E10, ci, cj, cij, cji);

			SET_TO(a, GetMate0(j));
			a->next = NULL;
			a_rev->next = NULL;

			j->tr_cap -= cj;
		}

		SET_SISTERS(a, a_rev);
		SET_TO(a_rev, i);

		i->tr_cap += ci;
		a->r_cap = cij;
		a_rev->r_cap = cji;
	}
	else
	{
		Arc *a[2], *a_rev[2];
		a[0]     = &arcs[0][2*e];
		a_rev[0] = &arcs[0][2*e+1];
		a[1]     = &arcs[1][2*e];
		a_rev[1] = &arcs[1][2*e+1];

		Node* i[2] = { nodes[0] + _i, nodes[1] + _i };
		Node* j[2];

		if (E01 + E10 >= E00 + E11)
		{
			j[0] = nodes[0] + _j; j[1] = nodes[1] + _j;
			ComputeWeights(E00, E01, E10, E11, ci, cj, cij, cji);
		}
		else
		{
			j[1] = nodes[0] + _j; j[0] = nodes[1] + _j;
			ComputeWeights(E01, E00, E11, E10, ci, cj, cij, cji);
		}

		SET_SISTERS(a[0], a_rev[0]);
		SET_SISTERS(a[1], a_rev[1]);

		SET_TO(a[0],     j[0]);
		SET_TO(a_rev[0], i[0]);
		SET_TO(a[1],     i[1]);
		SET_TO(a_rev[1], j[1]);

		SET_FROM(a[0],     i[0]);
		SET_FROM(a_rev[0], j[0]);
		SET_FROM(a[1],     j[1]);
		SET_FROM(a_rev[1], i[1]);

		i[0]->tr_cap += ci; i[1]->tr_cap -= ci;
		j[0]->tr_cap += cj; j[1]->tr_cap -= cj;
		a[0]->r_cap = a[1]->r_cap = cij;
		a_rev[0]->r_cap = a_rev[1]->r_cap = cji;
	}

	zero_energy += E00;

	return e;
}
	void QPBO<REAL>::AddPairwiseTerm(EdgeId e, NodeId _i, NodeId _j, REAL E00, REAL E01, REAL E10, REAL E11)
{
	user_assert(e >= 0 && arcs[0][2*e].sister);
	user_assert(arcs[0][2*e].head==&nodes[0][_i] || arcs[0][2*e].head==&nodes[1][_i] || arcs[0][2*e].head==&nodes[0][_j] || arcs[0][2*e].head==&nodes[1][_j]);
	user_assert(arcs[0][2*e+1].head==&nodes[0][_i] || arcs[0][2*e+1].head==&nodes[1][_i] || arcs[0][2*e+1].head==&nodes[0][_j] || arcs[0][2*e+1].head==&nodes[1][_j]);
	user_assert(_i != _j);

	REAL delta, ci, cj, cij, cji;

	if (stage == 0)
	{
		Arc* a = &arcs[0][2*e];
		Arc* a_rev = &arcs[0][2*e+1];
		code_assert(a->sister==a_rev && a->sister==a_rev);

		Node* i = a_rev->head;
		Node* j = a->head;
		code_assert(IsNode0(i));
		if (i != &nodes[0][_i]) { delta = E01; E01 = E10; E10 = delta; }
		if (IsNode0(j))
		{
			ComputeWeights(E00, E01, E10, E11, ci, cj, cij, cji);
			
			i->tr_cap += ci;
			j->tr_cap += cj;
			a->r_cap += cij;
			a_rev->r_cap += cji;

			if (a->r_cap < 0)
			{
				delta = a->r_cap;
				a->r_cap = 0;
				a_rev->r_cap += delta;
				i->tr_cap -= delta;
				j->tr_cap += delta;
			}
			if (a_rev->r_cap < 0)
			{
				delta = a_rev->r_cap;
				a_rev->r_cap = 0;
				a->r_cap += delta;
				j->tr_cap -= delta;
				i->tr_cap += delta;
			}

			if (a->r_cap < 0)
			{
				all_edges_submodular = false;
				REMOVE_FROM(a, i);
				REMOVE_FROM(a_rev, j);
				SET_TO(a, GetMate0(j));

				delta = a->r_cap;
				i->tr_cap -= delta;
				a->r_cap = -delta;
			}
		}
		else
		{
			j = GetMate1(j);
			ComputeWeights(E01, E00, E11, E10, ci, cj, cij, cji);
			
			i->tr_cap += ci;
			j->tr_cap -= cj;
			a->r_cap += cij;
			a_rev->r_cap += cji;

			if (a->r_cap < 0)
			{
				delta = a->r_cap;
				a->r_cap = 0;
				a_rev->r_cap += delta;
				i->tr_cap -= delta;
				j->tr_cap -= delta;
			}
			if (a_rev->r_cap < 0)
			{
				delta = a_rev->r_cap;
				a_rev->r_cap = 0;
				a->r_cap += delta;
				j->tr_cap += delta;
				i->tr_cap += delta;
			}

			if (a->r_cap < 0)
			{
				SET_FROM(a, i);
				SET_FROM(a_rev, j);
				SET_TO(a, j);

				delta = a->r_cap;
				i->tr_cap -= delta;
				a->r_cap = -delta;
			}
		}
	}
	else
	{
		Arc* a[2] = { &arcs[0][2*e], &arcs[1][2*e] };
		Arc* a_rev[2] = { &arcs[0][2*e+1], &arcs[1][2*e+1] };
		code_assert(a[0]->sister==a_rev[0] && a[1]->sister==a_rev[1] && a[0]==a_rev[0]->sister && a[1]==a_rev[1]->sister);

		Node* i[2] = { a_rev[0]->head, a[1]->head };
		Node* j[2] = { a[0]->head, a_rev[1]->head };
		int k = IsNode0(i[0]) ? 0 : 1;
		if (i[k] != &nodes[0][_i]) { delta = E01; E01 = E10; E10 = delta; }
		if (IsNode0(j[k]))
		{ 
			ComputeWeights(E00, E01, E10, E11, ci, cj, cij, cji);
		}
		else
		{ 
			ComputeWeights(E01, E00, E11, E10, ci, cj, cij, cji);
		};

		// make sure that a[0]->r_cap == a[1]->r_cap and a_rev[0]->r_cap == a_rev[1]->r_cap by pushing flow
		delta = a[1]->r_cap - a[0]->r_cap;
		//a[1]->r_cap -= delta;   // don't do the subtraction - later we'll set explicitly a[1]->r_cap = a[0]->r_cap
		//a[1]->sister->r_cap += delta;
		a_rev[1]->head->tr_cap -= delta;
		a[1]->head->tr_cap     += delta;

		i[0]->tr_cap += ci; i[1]->tr_cap -= ci;
		j[0]->tr_cap += cj; j[1]->tr_cap -= cj;
		a[0]->r_cap += cij;
		a_rev[0]->r_cap += cji;

		if (a[0]->r_cap < 0)
		{
			delta = a[0]->r_cap;
			a[0]->r_cap = 0;
			a_rev[0]->r_cap += delta;
			i[0]->tr_cap -= delta; i[1]->tr_cap += delta;
			j[0]->tr_cap += delta; j[1]->tr_cap -= delta;
		}
		if (a_rev[0]->r_cap < 0)
		{
			delta = a_rev[0]->r_cap;
			a_rev[0]->r_cap = 0;
			a[0]->r_cap += delta;
			j[0]->tr_cap -= delta; j[1]->tr_cap += delta;
			i[0]->tr_cap += delta; i[1]->tr_cap -= delta;
		}

		if (a[0]->r_cap < 0)
		{
			// need to swap submodular <-> supermodular
			SET_TO(a[0], j[1]);
			SET_TO(a_rev[1], j[0]);
			REMOVE_FROM(a_rev[0], j[0]);
			SET_FROM(a_rev[0], j[1]);
			REMOVE_FROM(a[1], j[1]);
			SET_FROM(a[1], j[0]);

			delta = a[0]->r_cap;
			i[0]->tr_cap -= delta; i[1]->tr_cap += delta;
			a[0]->r_cap = -delta;
		}

		a[1]->r_cap = a[0]->r_cap;
		a_rev[1]->r_cap = a_rev[0]->r_cap;
	}

	zero_energy += E00;
}
Esempio n. 4
0
/*
 * Function: FMMSetup
 * -----------------------------------------------------------------
 * Prepare for the FMM calculation by setting the parameters, computing
 * the weight matrices, pre-computing the SVD (if necessary), reading
 * in the necessary matrices, and building the FMM hierarchy.
 */
void H2_3D_Tree::FMMSetup(nodeT **A, double *Tkz,  double *Kweights,
                          double *Cweights, double boxLen, doft *cutoff,
                          int n, double epsilon, doft * dof,  int treeLevel, char *Kmat, char *Umat, char *Vmat,
                          double *Ucomp, double *Vcomp,int& skipLevel, double alpha, int use_chebyshev, rfftw_plan
                          p_r2c) {
    
	vector3 center;
    setHomogen(kernelType);
    homogen = -homogen;
    
    if (use_chebyshev) {
        sprintf(Kmat,"./BBFMM3D/output/%sCK%d.bin",kernelType.c_str(),n);
        sprintf(Umat,"./BBFMM3D/output/%sCU%d.bin",kernelType.c_str(),n);
        sprintf(Vmat,"./BBFMM3D/output/%sCV%d.bin",kernelType.c_str(),n);
    } else {
        sprintf(Kmat,"./BBFMM3D/output/%sUK%d.bin",kernelType.c_str(),n);
        sprintf(Umat,"./BBFMM3D/output/%sUU%d.bin",kernelType.c_str(),n);
        sprintf(Vmat,"./BBFMM3D/output/%sUV%d.bin",kernelType.c_str(),n);
    }
    
    // Compute the Chebyshev weights and sets up the lookup table
	ComputeWeights(Tkz,Ktable,Kweights,Cweights,n,alpha,use_chebyshev); //??????
    // Precompute the SVD of the kernel interaction matrix (if
    // necessary)
    
    
    if (use_chebyshev) {
    int i;
    FILE *fK, *fU, *fV;
    fK = fopen(Kmat, "rb");
    fU = fopen(Umat, "rb");
    fV = fopen(Vmat, "rb");
    
    
    if (fK == NULL || fU == NULL || fV == NULL) { // Create files
        if (fK!=NULL)
            fclose(fK);
        if (fU!=NULL)
            fclose(fU);
        if (fV!=NULL)
            fclose(fV);
        
        printf("Pre-Compute files do not exit. Creating now ...\n");
        
        if (homogen > 1e-9) { // homogeneous kernel
                ComputeKernelSVD(Kweights, n, epsilon, dof,
                                 Kmat, Umat, Vmat, symmetry, Ucomp, Vcomp,alpha,
                                 1);
            
        }
        else { // non-homogeneous kernel
            
            // Open new files for writing boxLen and treeLevel
            
            fK = fopen(Kmat, "wb");
            fwrite(&boxLen, sizeof(double), 1, fK);
            fwrite(&treeLevel, sizeof(int), 1, fK);
            fclose(fK);
            
            
            double boxLenLevel = boxLen/4; // first FMM level
            for (i=2; i<=treeLevel; i++, boxLenLevel/=2)
                // FMM starts from the second level
                ComputeKernelSVD(Kweights, n,  epsilon, dof,
                                 Kmat, Umat, Vmat, symmetry, Ucomp, Vcomp,alpha,
                                 boxLenLevel);
        }
    }
    
    //non-homogen
    else if (homogen < 1e-9) { // check if the file is usable
        
        fK = fopen(Kmat, "rb");
        double fileBoxLen;
        int fileTreeLevel;
        i  = fread(&fileBoxLen, sizeof(double), 1, fK);
        i += fread(&fileTreeLevel, sizeof(int), 1, fK);
        if (i != 2)
            printf("fread error in FMMSetup().\n");
        
        int count = 0;
        while (fileBoxLen > boxLen +1e-9) {
            fileBoxLen /= 2;
            count ++;
        }
        if (fabs(boxLen-fileBoxLen) < 1e-9 && treeLevel + count <=
            fileTreeLevel) {
            skipLevel = count; // count * Ksize
            printf("Reading pre-compute files ...\n");
        }
        else { // Recreate the files
            
            printf("Recreating pre-compute files now ...\n");
            
            fK = fopen(Kmat, "wb");
            fwrite(&boxLen, sizeof(double), 1, fK);
            fwrite(&treeLevel, sizeof(int), 1, fK);
            fclose(fK);
            
            int i;
            double boxLenLevel = boxLen/4; // first FMM level
            for (i=2; i<=treeLevel; i++, boxLenLevel/=2)
                // FMM starts from the second level
                ComputeKernelSVD(Kweights, n, epsilon, dof,
                                 Kmat, Umat, Vmat, symmetry, Ucomp, Vcomp,alpha,
                                 boxLenLevel);
        }
    }
    else
        printf("Reading pre-compute files ...\n");

    fU = fopen(Umat,"rb");
    int j = fread(&(cutoff->f), sizeof(int), 1, fU);
    fclose(fU);
    
    fV = fopen(Vmat,"rb");
    j += fread(&(cutoff->s), sizeof(int), 1, fV);
    fclose(fV);
    
    if (j != 2)
        printf("fread() error in FMMSetup().\n");

    }
    
    else { // uniform
        FILE *f;
        if ((f=fopen(Kmat,"rb")) == NULL) {
            ComputeKernelUniformGrid(Kweights,n,dof,Kmat,alpha, p_r2c);
        }
        cutoff->f = dof->f*n*n*n;
        cutoff->s = dof->s*n*n*n;
    }
    

    
        // Builds the FMM hierarchy
	center.x = 0;
	center.y = 0;
	center.z = 0;
	(*A) = NULL;

	NewNode(A,center,L,n);
	BuildFMMHierarchy(A,treeLevel,n,cutoff,dof);
}