Example #1
0
void Tipsify::operator()(std::size_t cacheSize) {
    /* Neighboring triangles for each vertex, per-vertex live triangle count */
    std::vector<UnsignedInt> liveTriangleCount, neighborPosition, neighbors;
    buildAdjacency(liveTriangleCount, neighborPosition, neighbors);

    /* Global time, per-vertex caching timestamps, per-triangle emmited flag */
    UnsignedInt time = cacheSize+1;
    std::vector<UnsignedInt> timestamp(vertexCount);
    std::vector<bool> emitted(indices.size()/3);

    /* Dead-end vertex stack */
    std::stack<UnsignedInt> deadEndStack;

    /* Output index buffer */
    std::vector<UnsignedInt> outputIndices;
    outputIndices.reserve(indices.size());

    /* Starting vertex for fanning, cursor */
    UnsignedInt fanningVertex = 0;
    UnsignedInt i = 0;
    while(fanningVertex != 0xFFFFFFFFu) {
        /* Array with candidates for next fanning vertex (in 1-ring around
           fanning vertex) */
        std::vector<UnsignedInt> candidates;

        /* For all neighbors of fanning vertex */
        for(UnsignedInt ti = neighborPosition[fanningVertex], t = neighbors[ti]; ti != neighborPosition[fanningVertex+1]; t = neighbors[++ti]) {
            /* Continue if already emitted */
            if(emitted[t]) continue;
            emitted[t] = true;

            /* Write all vertices of the triangle to output buffer */
            for(UnsignedInt vi = 0; vi != 3; ++vi) {
                const UnsignedInt v = indices[vi + t*3];

                outputIndices.push_back(v);

                /* Add to dead end stack and candidates array */
                /** @todo Limit size of dead end stack to cache size */
                deadEndStack.push(v);
                candidates.push_back(v);

                /* Decrease live triangle count */
                --liveTriangleCount[v];

                /* If not in cache, set timestamp */
                if(time-timestamp[v] > cacheSize)
                    timestamp[v] = time++;
            }
        }

        /* Get next fanning vertex */
        fanningVertex = 0xFFFFFFFFu;

        /* Go through candidates in 1-ring around fanning vertex */
        Int candidatePriority = -1;
        for(UnsignedInt v: candidates) {
            /* Skip if it doesn't have any live triangles */
            if(!liveTriangleCount[v]) continue;

            /* Get most fresh candidate which will still be in cache even
               after fanning. Every fanned triangle will generate at most
               two cache misses, thus 2*liveTriangleCount */
            Int priority = 0;
            if(time-timestamp[v]+2*liveTriangleCount[v] <= cacheSize)
                priority = time-timestamp[v];
            if(priority > candidatePriority) {
                fanningVertex = v;
                candidatePriority = priority;
            }
        }

        /* On dead-end */
        if(fanningVertex == 0xFFFFFFFFu) {
            /* Find vertex with live triangles in dead-end stack */
            while(!deadEndStack.empty()) {
                unsigned int d = deadEndStack.top();
                deadEndStack.pop();

                if(!liveTriangleCount[d]) continue;
                fanningVertex = d;
                break;
            }

            /* If not found, find next artbitrary vertex with live
               triangles */
            while(++i < vertexCount) {
                if(!liveTriangleCount[i]) continue;

                fanningVertex = i;
                break;
            }
        }
    }

    /* Swap original index buffer with optimized */
    std::swap(indices, outputIndices);
}
bool AkonadiServer::init()
{
    connect(watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)),
            this, SLOT(serviceOwnerChanged(QString,QString,QString)));
    return true;
}

connect(&mapper, SIGNAL(mapped(Q1&)), this, SLOT(onSomeEvent(const Q2&)));

connect(&mapper,
        SIGNAL(mapped(Q1&)),
        this,
        SLOT(onSomeEvent(const Q2&)));

connect(&mapper,
        SIGNAL(emitted(Q1*)),
        this,
        SLOT(accept(const Q2*)));

connect(&mapper,
        SIGNAL(emitted(X<int>)),
        this,
        SLOT(accept(X<int>)));