예제 #1
0
vector<vector<int> > computePossibilities(const PtGraph &graph, const vector<Sphere> &spheres,
                                          const Skeleton &skeleton)
{
    int i, j;

    vector<vector<int> > out(skeleton.cGraph().verts.size());
    vector<int> allVerts, limbVerts, fatVerts;
    for(i = 0; i < (int)graph.verts.size(); ++i) {
        allVerts.push_back(i);
        const vector<int> &edg = graph.edges[i];
        double rad = spheres[i].radius;
        Vector3 cur = graph.verts[i];
        for(j = 0; j < (int)edg.size(); ++j) {
            Vector3 e1 = graph.verts[edg[j]];
            int k;
            for(k = 0; k < (int)edg.size(); ++k) {
                if(rad > 2. * spheres[edg[k]].radius)
                    continue;
                Vector3 e2 = graph.verts[edg[k]];
                if((e2 - cur).normalize() * (cur - e1).normalize() > 0.8)
                    break;
            }
            if(k < (int)edg.size())
                continue;
            limbVerts.push_back(i);
            break;
        }
    }
    vector<double> rads;
    for(i = 0; i < (int)graph.verts.size(); ++i)
        rads.push_back(spheres[i].radius);
    sort(rads.begin(), rads.end());
    double cutoff = (int)rads.size() < 50 ? 0. : rads[rads.size() - 50];
    for(i = 0; i < (int)graph.verts.size(); ++i)
        if(spheres[i].radius >= cutoff)
            fatVerts.push_back(i);
    std::cout  << "Extrem, fat verts " << limbVerts.size() << " " << fatVerts.size() << endl;
    
    for(i = 0; i < (int)out.size(); ++i) {
        bool limb = (skeleton.cGraph().edges[i].size() == 1);
        bool fat = skeleton.cFat()[i];

        if(fat)
            out[i] = fatVerts;
        else if(limb)
            out[i] = limbVerts;
        else
            out[i] = allVerts;
    }

    return out;
}
예제 #2
0
vector<int> discreteEmbed(const PtGraph &graph, const vector<Sphere> &spheres,
                          const Skeleton &skeleton, const vector<vector<int> > &possibilities)
{
    int i, j;
    FP fp(graph, skeleton, spheres);

    fp.footBase = 1.;
    for(i = 0; i < (int)graph.verts.size(); ++i)
        fp.footBase = min(fp.footBase, graph.verts[i][1]);

    vector<PenaltyFunction *> penaltyFunctions = getPenaltyFunctions(&fp);

    int toMatch = skeleton.cGraph().verts.size();
    
    std::cout  << "Matching!" << endl;
    
    priority_queue<PartialMatch> todo;
    
    PartialMatch output(graph.verts.size());
    todo.push(output);
    
    int maxSz = 0;
    
    while(!todo.empty()) {
        PartialMatch cur = todo.top();
        todo.pop();
        
        int idx = cur.match.size();
        
        int curSz = (int)log((double)todo.size());
        if(curSz > maxSz) {
            maxSz = curSz;
            if(maxSz > 3)
                std::cout  << "Reached " << todo.size() << endl;
        }
        
        if(idx == toMatch) {
            output = cur;
            std::cout  << "Found: residual = " << cur.penalty << endl;
            break;
        }
        
        for(i = 0; i < (int)possibilities[idx].size(); ++i) {
            int candidate = possibilities[idx][i];
            int k;
            double extraPenalty = computePenalty(penaltyFunctions, cur, candidate);

            if(extraPenalty < 0)
                std::cout  << "ERR = " << extraPenalty << endl;
            if(cur.penalty + extraPenalty < 1.) {
                PartialMatch next = cur;
                next.match.push_back(candidate);
                next.penalty += extraPenalty;
                next.heuristic = next.penalty;
                
                //compute taken vertices and edges
                if(idx > 0) {
                    vector<int> path = fp.paths.path(candidate, next.match[skeleton.cPrev()[idx]]);
                    for(j = 0; j < (int)path.size(); ++j)
                        next.vTaken[path[j]] = true;
                }

                //compute heuristic
                for(j = idx + 1; j < toMatch; ++j) {
                    if(skeleton.cPrev()[j] > idx)
                        continue;
                    double minP = 1e37;
                    for(k = 0; k < (int)possibilities[j].size(); ++k) {
                        minP = min(minP, computePenalty(penaltyFunctions, next, possibilities[j][k], j));
                    }
                    next.heuristic += minP;
                    if(next.heuristic > 1.)
                        break;
                }

                if(next.heuristic > 1.)
                    continue;

                todo.push(next);
            }
        }
    }
    
    if(output.match.size() == 0)
    {
        std::cout  << "No Match" << endl;
    }

    for(i = 0; i < (int)penaltyFunctions.size(); ++i)
        delete penaltyFunctions[i];

    return output.match;
}