//---------------------------------------------------------------------------- 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; }
/* * 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); }