Exemplo n.º 1
0
//----------------------------------------------------------------------------
void CIsoSurface::MakeUnique (std::vector<TVector3D>& rkVA,
    std::vector<TriangleKey>& rkTA)
{
    int iVQuantity = (int)rkVA.size();
    int iTQuantity = (int)rkTA.size();
    if ( iVQuantity == 0 || iTQuantity == 0 )
        return;

    // use a hash table to generate unique storage
    VMap kVMap;
    VMapIterator pkVIter;
    for (int iV = 0, iNextVertex = 0; iV < iVQuantity; iV++)
    {
        // keep only unique vertices
        std::pair<VMapIterator,bool> kResult = kVMap.insert( std::make_pair(rkVA[iV],iNextVertex) );
        if ( kResult.second == true )
            iNextVertex++;
    }

std::cerr << "Found " << kVMap.size() << " vertices" << std::endl;
    
    // use a hash table to generate unique storage
    TMap kTMap;
    TMapIterator pkTIter;
    for (int iT = 0, iNextTriangle = 0; iT < iTQuantity; iT++)
    {
        // replace old vertex indices by new ones
        TriangleKey& rkTri = rkTA[iT];
        pkVIter = kVMap.find(rkVA[rkTri.V[0]]);
        assert( pkVIter != kVMap.end() );
        rkTri.V[0] = pkVIter->second;
        pkVIter = kVMap.find(rkVA[rkTri.V[1]]);
        assert( pkVIter != kVMap.end() );
        rkTri.V[1] = pkVIter->second;
        pkVIter = kVMap.find(rkVA[rkTri.V[2]]);
        assert( pkVIter != kVMap.end() );
        rkTri.V[2] = pkVIter->second;

        // keep only unique triangles
        std::pair<TMapIterator,bool> kResult = kTMap.insert(
            std::make_pair(rkTri,iNextTriangle));
        if ( kResult.second == true )
            iNextTriangle++;
    }

    // pack the vertices
    rkVA.resize(kVMap.size());
    for (pkVIter = kVMap.begin(); pkVIter != kVMap.end(); pkVIter++)
        rkVA[pkVIter->second] = pkVIter->first;

    // pack the triangles
    rkTA.resize(kTMap.size());
    for (pkTIter = kTMap.begin(); pkTIter != kTMap.end(); pkTIter++)
        rkTA[pkTIter->second] = pkTIter->first;
}
Exemplo n.º 2
0
//----------------------------------------------------------------------------
void ExtractCurveTris::MakeUnique (std::vector<Vector2f>& vertices, 
    std::vector<EdgeKey>& edges)
{
    int numVertices = (int)vertices.size();
    if (numVertices == 0)
    {
        return;
    }

    // Use maps to generate unique storage.
    typedef std::map<Vector2f, int> VMap;
    typedef std::map<Vector2f, int>::iterator VIterator;
    VMap vertexMap;
    for (int v = 0,  nextVertex = 0; v < numVertices; ++v)
    {
        std::pair<VIterator, bool> result = vertexMap.insert(
            std::make_pair(vertices[v],  nextVertex));

        if (result.second == true)
        {
            ++nextVertex;
        }
    }

    typedef std::map<EdgeKey, int> EMap;
    typedef std::map<EdgeKey, int>::iterator EIterator;
    EMap* edgeMap = 0;
    int e;
    VIterator vIter;

    int numEdges = (int)edges.size();
    if (numEdges)
    {
        edgeMap = new0 EMap();
        int nextEdge = 0;
        for (e = 0; e < numEdges; ++e)
        {
            // Replace old vertex indices by new ones.
            vIter = vertexMap.find(vertices[edges[e].V[0]]);
            assertion(vIter != vertexMap.end(),  "Unexpected condition\n");
            edges[e].V[0] = vIter->second;
            vIter = vertexMap.find(vertices[edges[e].V[1]]);
            assertion(vIter != vertexMap.end(),  "Unexpected condition\n");
            edges[e].V[1] = vIter->second;

            // Keep only unique edges.
            std::pair<EIterator, bool> result = edgeMap->insert(
                std::make_pair(edges[e],  nextEdge));

            if (result.second == true)
            {
                ++nextEdge;
            }
        }
    }

    // Pack the vertices into an array.
    numVertices = (int)vertexMap.size();
    vertices.resize(numVertices);
    for (vIter = vertexMap.begin(); vIter != vertexMap.end(); ++vIter)
    {
        vertices[vIter->second] = vIter->first;
    }

    // Pack the edges into an array.
    if (numEdges > 0)
    {
        numEdges = (int)edgeMap->size();
        edges.resize(numEdges);
        EIterator eIter;
        for (eIter = edgeMap->begin(); eIter != edgeMap->end(); ++eIter)
        {
            edges[eIter->second] = eIter->first;
        }
        delete0(edgeMap);
    }
    else
    {
        edges.clear();
    }
}
Exemplo n.º 3
0
/// This version of the constructor take one pass throught the data.  It
/// constructs a ibis::index::VMap first, then construct the sbiad from the
/// VMap.  It uses more computer memory than the two-pass version, but will
/// probably run a little faster.
void ibis::sbiad::construct1(const char* f, const uint32_t nbase) {
    VMap bmap; // a map between values and their position
    try {
	mapValues(f, bmap);
    }
    catch (...) { // need to clean up bmap
	LOGGER(ibis::gVerbose >= 0)
	    << "sbiad::construct reclaiming storage "
	    "allocated to bitvectors (" << bmap.size() << ")";

	for (VMap::iterator it = bmap.begin(); it != bmap.end(); ++ it)
	    delete (*it).second;
	bmap.clear();
	ibis::fileManager::instance().signalMemoryAvailable();
	throw;
    }
    if (bmap.empty()) return;
    nrows = (*(bmap.begin())).second->size();
    if (nrows != col->partition()->nRows()) {
	for (VMap::iterator it = bmap.begin(); it != bmap.end(); ++ it)
	    delete (*it).second;
	bmap.clear();
	ibis::fileManager::instance().signalMemoryAvailable();

	LOGGER(ibis::gVerbose >= 0)
	    << "Warning -- sbiad::construct1 the bitvectors "
	    "do not have the expected size(" << col->partition()->nRows()
	    << "). stopping..";
	throw ibis::bad_alloc("incorrect bitvector sizes");
    }

    // convert bmap into the current data structure
    // fill the arrays vals and cnts
    const uint32_t card = bmap.size();
    vals.reserve(card);
    cnts.reserve(card);
    for (VMap::const_iterator it = bmap.begin(); it != bmap.end(); ++it) {
	vals.push_back((*it).first);
	cnts.push_back((*it).second->cnt());
    }
    // fill the array bases
    setBases(bases, card, nbase);
    // count the number of bitvectors to genreate
    const uint32_t nb = bases.size();
    uint32_t nobs = 0;
    uint32_t i;
    for (i = 0; i < nb; ++i)
	nobs += bases[i];
    // allocate enough bitvectors in bits
    bits.resize(nobs);
    for (i = 0; i < nobs; ++i)
	bits[i] = 0;
    if (ibis::gVerbose > 5) {
	col->logMessage("sbiad::construct", "initialized the array of "
			"bitvectors, start converting %lu bitmaps into %lu-"
			"component range code (with %lu bitvectors)",
			static_cast<long unsigned>(vals.size()),
			static_cast<long unsigned>(nb),
			static_cast<long unsigned>(nobs));
    }

    // converting to multi-level equality encoding first
    i = 0;
    for (VMap::const_iterator it = bmap.begin(); it != bmap.end();
	 ++it, ++i) {
	uint32_t offset = 0;
	uint32_t ii = i;
	for (uint32_t j = 0; j < nb; ++j) {
	    uint32_t k = ii % bases[j];
	    if (bits[offset+k]) {
		*(bits[offset+k]) |= *((*it).second);
	    }
	    else {
		bits[offset+k] = new ibis::bitvector();
		bits[offset+k]->copy(*((*it).second));
		// expected to be operated on more than 64 times
		if (vals.size() > 64*bases[j])
		    bits[offset+k]->decompress();
	    }
	    ii /= bases[j];
	    offset += bases[j];
	}

	delete (*it).second; // no longer need the bitmap
    }
    for (i = 0; i < nobs; ++i) {
	if (bits[i] == 0) {
	    bits[i] = new ibis::bitvector();
	    bits[i]->set(0, nrows);
	}
    }
#if DEBUG+0 > 0 || _DEBUG+0 > 0
    if (ibis::gVerbose > 11) {
	LOGGER(ibis::gVerbose >= 0)
	    << "DEBUG -- sbiad::construct1 converted"
	    << bmap.size() << " bitmaps for each distinct value into "
	    << bits.size() << bases.size()
	    << "-component equality encoded bitmaps";
    }
#endif
    // sum up the bitvectors according to the interval-encoding
    array_t<bitvector*> beq;
    beq.swap(bits);
    try { // use a try block to ensure the bitvectors in beq are freed
	uint32_t ke = 0;
	bits.clear();
	for (i = 0; i < nb; ++i) {
	    if (bases[i] > 2) {
		nobs = (bases[i] - 1) / 2;
		bits.push_back(new ibis::bitvector);
		bits.back()->copy(*(beq[ke]));
		if (nobs > 64)
		    bits.back()->decompress();
		for (uint32_t j = ke+1; j <= ke+nobs; ++j)
		    *(bits.back()) |= *(beq[j]);
		bits.back()->compress();
		for (uint32_t j = 1; j < bases[i]-nobs; ++j) {
		    bits.push_back(*(bits.back()) - *(beq[ke+j-1]));
		    *(bits.back()) |= *(beq[ke+j+nobs]);
		    bits.back()->compress();
		}
		for (uint32_t j = ke; j < ke+bases[i]; ++j) {
		    delete beq[j];
		    beq[j] = 0;
		}
	    }
	    else {
		bits.push_back(beq[ke]);
		if (bases[i] > 1) {
		    delete beq[ke+1];
		    beq[ke+1] = 0;
		}
	    }
	    ke += bases[i];
	}
    }
    catch (...) {
	LOGGER(ibis::gVerbose > 1)
	    << "Warning -- column::[" << col->name()
	    << "]::construct1 encountered an exception while converting "
	    "to inverval encoding, cleaning up ...";
	for (uint32_t i = 0; i < beq.size(); ++ i)
	    delete beq[i];
	throw;
    }
    beq.clear();
#if DEBUG+0 > 0 || _DEBUG+0 > 0
    if (ibis::gVerbose > 11) {
	LOGGER(ibis::gVerbose >= 0)
	    << "DEBUG -- sbiad::construct1 completed "
	    << "converting equality encoding to interval encoding";
    }
#endif
    optionalUnpack(bits, col->indexSpec());

    // write out the current content
    if (ibis::gVerbose > 8) {
 	ibis::util::logger lg;
 	print(lg());
    }
} // ibis::sbiad::construct1