Example #1
0
static tetrahedra read_tetrahedra (boost::tokenizer<>::iterator & p,
                                   const boost::tokenizer<>::iterator & end,
                                   std::list<vertex_id> & finalized_vertices,
                                   const dias::vertex_db & vertices,
                                   int v_count)
{
    vertex_id v_ids[4];
    int j = 0;
    while (p != end)
    {
        std::string v_str = *p++;
        int v = boost::lexical_cast<int> (v_str);
        if (v >= 0)
            v_ids[j] = v;
        else
        {
            v_ids[j] = v_count + v;
            finalized_vertices.push_back (v_ids[j]);
        }
        j++;
    }
    assert (j == 4);

    return tetrahedra (v_ids, vertices);
}
Example #2
0
/// Returns the number of tetrahedra in the alpha shape.
int AlphaShape::tetrahedronCount() const
{
    return tetrahedra().size();
}
Example #3
0
const NGroupPresentation& Dim4Triangulation::fundamentalGroup() const {
    if (fundGroup_.known())
        return *fundGroup_.value();

    NGroupPresentation* ans = new NGroupPresentation();

    if (isEmpty())
        return *(fundGroup_ = ans);

    ensureSkeleton();

    // Each non-boundary not-in-forest tetrahedron is a generator.
    // Each non-boundary triangle is a relation.
    long nBdryTets = 0;
    for (BoundaryComponentIterator bit = boundaryComponents_.begin();
            bit != boundaryComponents_.end(); ++bit)
        nBdryTets += (*bit)->countTetrahedra();

    // Cast away all unsignedness in case we run into problems subtracting.
    long nGens = static_cast<long>(countTetrahedra()) - nBdryTets
        - static_cast<long>(size())
        + static_cast<long>(countComponents());

    // Insert the generators.
    ans->addGenerator(nGens);

    // Find out which tetrahedron corresponds to which generator.
    long* genIndex = new long[countTetrahedra()];
    long i = 0;
    for (Dim4Tetrahedron* tet : tetrahedra())
        if (! (tet->isBoundary() || tet->inMaximalForest()))
            genIndex[tet->index()] = i++;

    // Run through each triangle and insert the corresponding relations.
    Dim4Pentachoron* pent;
    int facet;
    Dim4Tetrahedron* tet;
    NGroupExpression* rel;
    for (Dim4Triangle* f : triangles()) {
        if (f->isBoundary())
            continue;

        // Put in the relation corresponding to this triangle.
        rel = new NGroupExpression();
        for (auto& emb : *f) {
            pent = emb.pentachoron();
            facet = emb.vertices()[3];

            tet = pent->tetrahedron(facet);
            if (tet->inMaximalForest())
                continue;

            // We define the "direction" for this dual edge to point
            // from embedding tet->front() to embedding tet->back().
            //
            // Test whether we are traversing this dual edge forwards or
            // backwards as we walk around the triangle (*fit).
            if ((tet->front().pentachoron() == pent) &&
                    (tet->front().tetrahedron() == facet))
                rel->addTermLast(genIndex[tet->index()], 1);
            else
                rel->addTermLast(genIndex[tet->index()], -1);
        }
        ans->addRelation(rel);
    }

    // Tidy up.
    delete[] genIndex;
    ans->intelligentSimplify();

    return *(fundGroup_ = ans);
}