Exemple #1
0
double
cell_volume(const Cell_handle& c)
{
   Tetrahedron t = Tetrahedron(c->vertex(0)->point(),
                               c->vertex(1)->point(),
                               c->vertex(2)->point(),
                               c->vertex(3)->point());
   return ( CGAL::to_double(CGAL::abs(t.volume()) ) );
}
Exemple #2
0
// -------------------------------------------------------------
// dg_voronoi_point
// -------------------------------------------------------------
// This function computes a voronoi point when some degeneracies
// have been discovered about the four points of a tetrahedron.
//
// In this function we assume that the degeneracies occured
// because of the coplanarity. We approximate the circumcenter
// of the tetrahedron by the circumcenter of one of the triangular
// facets.
// -------------------------------------------------------------
Point
dg_voronoi_point(const Point &a,
                 const Point &b,
                 const Point &c,
                 const Point &d,
                 bool &is_correct_computation)
{

    // First, we check if our assumption is correct.
    // This is more of a debugging purpose than of
    // actual computation.
    Tetrahedron t = Tetrahedron(a,b,c,d);
    if( ! t.is_degenerate() )
    {
        // cerr << "error in the assumption of coplanarity." << endl;
        /*
        // debug
        cout << "{OFF " << endl;
        cout << "4 4 0" << endl;
        cout << a << "\n" << b << "\n" << c << "\n" << d << endl;
        cout << "3\t0 1 2" << endl;
        cout << "3\t0 2 3" << endl;
        cout << "3\t0 3 1" << endl;
        cout << "3\t1 2 3" << endl;
        cout << "}" << endl;
        // end debug
        */
    }

    // Approximate the circumcenter of the tetrahedron with that of
    // one of its triangular facets. The facet should not be collinear.
    // The following boolean variable will keep track if we have found
    // a valid circumcenter (of a triangle) to replace that of a
    // tetrahedron.
    Point cc = CGAL::ORIGIN;
    is_correct_computation = false;
    Point p[4] = {a,b,c,d};
    for(int i = 0; i < 4; i ++)
    {
        // first check if the facet is degenerate or not.
        Triangle_3 t = Triangle_3(p[(i+1)%4], p[(i+2)%4], p[(i+3)%4]);
        if( t.is_degenerate() ) continue;

        // since we found a non-degenerate triangle we can now compute
        // its circumcenter and we will be done.
        cc = nondg_cc_tr_3(p[(i+1)%4], p[(i+2)%4], p[(i+3)%4], is_correct_computation);

        if( is_correct_computation )
            break;
    }

    if( is_correct_computation )
    {
        if(cc == CGAL::ORIGIN) cerr << "<dg_vp : returning cc as ORIGIN>" << endl;
        return cc;
    }

    cerr << "four points are colinear. " << endl;

    // for the time being, I just average the four points. What should be
    // the circumcenter of a tetrahedron whose four points are collinear ?
    cc = CGAL::ORIGIN +
         ( 0.25*Vector
           (
               a[0]+b[0]+c[0]+d[0],
               a[1]+b[1]+c[1]+d[1],
               a[2]+b[2]+c[2]+d[2]
           )
         );

    if(cc == CGAL::ORIGIN) cerr << "<dg_vp : returning cc as ORIGIN>" << endl;
    return cc;
}
Node* PlanetComponent::place(Vector3 pos, int colour_id, int polyhedron_id, int scale_)
{
    colour = colours[colour_id];
    scale = scale_;

    node = GetScene()->CreateChild("Planet");
    node->SetPosition(pos);
    node->SetRotation(Quaternion(Random(360.0f), Random(360.0f), Random(360.0f)));
    node->SetScale(scale);

    polyhedra_t polyhedron_type = static_cast<polyhedra_t>(polyhedron_id);
    switch(polyhedron_type)
    {

        case polyhedra_t::tetrahedron:
            polyhedron = Tetrahedron();
            break;

        case polyhedra_t::octahedron:
            polyhedron = Octahedron();
            break;

        case polyhedra_t::hexahedron:
            polyhedron = Hexahedron();
            break;

        case polyhedra_t::icosahedron:
            polyhedron = Icosahedron();
            break;

        case polyhedra_t::dodecahedron:
            polyhedron = Dodecahedron();
            break;

    }

    CustomGeo* cg = new CustomGeo(context_);

    for (unsigned i = 0; i < polyhedron.vertices.size(); i += 3)
    {
        cg->AddPoint(
            Vector3(
                polyhedron.vertices[i],
                polyhedron.vertices[i + 1],
                polyhedron.vertices[i + 2]
            )
        );
    }

    for (unsigned i = 0; i < polyhedron.triangles.size(); i += 3)
    {
        cg->AddTriangle(
            polyhedron.triangles[i],
            polyhedron.triangles[i + 1],
            polyhedron.triangles[i + 2],
            false
        );
    }

    cg->Build(node, false, false, 32, 63);


    Material* material = new Material(context_);
    material->SetShaderParameter("MatDiffColor", colour.ToVector4() / Vector4(255, 255, 255, 1));
    material->SetShaderParameter("MatSpecColor", colour.ToVector4() / Vector4(255, 255, 255, 1));
    node->GetComponent<StaticModel>()->SetMaterial(material);

    return node;
}
void ManifoldTetrahedronSetTopologyContainer::createTetrahedraAroundEdgeArray ()
{
    std::cout << "ManifoldTetrahedronSetTopologyContainer::createTetrahedraAroundEdgeArray ()"<<std::endl;

    // Get edge array
    sofa::helper::vector<Edge> edges = getEdgeArray();

    // Creating Tetrahedrons edges shell unordered
    TetrahedronSetTopologyContainer::createTetrahedraAroundEdgeArray();
    helper::ReadAccessor< Data< sofa::helper::vector<Tetrahedron> > > m_tetrahedron = d_tetrahedron;
    //	for (unsigned int i = 0; i < m_tetrahedraAroundEdge.size(); i++)
    //  std::cout << i << " => " << m_tetrahedraAroundEdge[i] << std::endl;


    for (unsigned int edgeIndex =0; edgeIndex<edges.size(); edgeIndex++)
    {

        sofa::helper::vector <unsigned int> &shell = getTetrahedraAroundEdgeForModification (edgeIndex);
        sofa::helper::vector <unsigned int>::iterator it;
        sofa::helper::vector < sofa::helper::vector <unsigned int> > vertexTofind;
        sofa::helper::vector <unsigned int> goodShell;
        unsigned int firstVertex =0;
        unsigned int secondVertex =0;
        unsigned int cpt = 0;

        vertexTofind.resize (shell.size());

        // Path to follow creation
        for (unsigned int tetraIndex = 0; tetraIndex < shell.size(); tetraIndex++)
        {
            cpt = 0;

            for (unsigned int vertex = 0; vertex < 4; vertex++)
            {
                if(m_tetrahedron[shell[ tetraIndex]][vertex] != edges[edgeIndex][0] && m_tetrahedron[shell[ tetraIndex]][vertex] != edges[edgeIndex][1] )
                {
                    vertexTofind[tetraIndex].push_back (m_tetrahedron[shell[ tetraIndex]][vertex]);
                    cpt++;
                }

                if (cpt == 2)
                    break;
            }
        }

        Tetrahedron tetra_first = Tetrahedron(edges[edgeIndex][0], edges[edgeIndex][1], vertexTofind[0][0], vertexTofind[0][1]);

        int good = getTetrahedronOrientation (m_tetrahedron[shell[ 0]], tetra_first);

        if (good == 1) //then tetra is in good order, initialisation.
        {
            firstVertex = vertexTofind[0][0];
            secondVertex = vertexTofind[0][1];
        }
        else if (good == 0)
        {
            firstVertex = vertexTofind[0][1];
            secondVertex = vertexTofind[0][0];
        }
        else
        {
            std::cout << "Error: createTetrahedraAroundEdgeArray: Houston there is a probleme." <<std::endl;
        }

        goodShell.push_back(shell[0]);

        bool testFind = false;
        bool reverse = false;
        cpt = 0;


        // Start following path
        for (unsigned int i = 1; i < shell.size(); i++)
        {
            for (unsigned int j = 1; j < shell.size(); j++)
            {

                Tetrahedron tetra_test1 = Tetrahedron(edges[edgeIndex][0], edges[edgeIndex][1], secondVertex, vertexTofind[j][1]);
                Tetrahedron tetra_test2 = Tetrahedron(edges[edgeIndex][0], edges[edgeIndex][1], secondVertex, vertexTofind[j][0]);

                if (vertexTofind[j][0] == secondVertex && getTetrahedronOrientation (m_tetrahedron[shell[ j]], tetra_test1) == 1) //find next tetra, in one or the other order.
                {
                    goodShell.push_back(shell[j]);
                    secondVertex = vertexTofind[j][1];
                    testFind = true;
                    break;
                }
                else if(vertexTofind[j][1] == secondVertex && getTetrahedronOrientation (m_tetrahedron[shell[ j]], tetra_test2) == 1)
                {
                    goodShell.push_back(shell[j]);
                    secondVertex = vertexTofind[j][0];
                    testFind = true;
                    break;
                }
            }

            if (!testFind) //tetra has not be found, this mean we reach a border, we reverse the method
            {
                reverse = true;
                break;
            }

            cpt++;
            testFind =false;
        }


        // Reverse path following methode
        if(reverse)
        {
#ifndef NDEBUG
            std::cout << "Edge on border: "<< edgeIndex << std::endl;
#endif
            for (unsigned int i = cpt+1; i<shell.size(); i++)
            {
                for (unsigned int j = 0; j<shell.size(); j++)
                {

                    Tetrahedron tetra_test1 = Tetrahedron(edges[edgeIndex][0], edges[edgeIndex][1], vertexTofind[j][1], firstVertex);
                    Tetrahedron tetra_test2 = Tetrahedron(edges[edgeIndex][0], edges[edgeIndex][1], vertexTofind[j][0], firstVertex);

                    if (vertexTofind[j][0] == firstVertex && getTetrahedronOrientation (m_tetrahedron[shell[ j]], tetra_test1) == 1) //find next tetra, in one or the other order.
                    {
                        goodShell.insert (goodShell.begin(),shell[j]);
                        firstVertex = vertexTofind[j][1];
                        testFind = true;
                        break;
                    }
                    else if(vertexTofind[j][1] == firstVertex && getTetrahedronOrientation (m_tetrahedron[shell[ j]], tetra_test2) == 1)
                    {
                        goodShell.insert (goodShell.begin(),shell[j]);
                        firstVertex = vertexTofind[j][0];
                        testFind = true;
                        break;
                    }
                }
            }
        }

        shell = goodShell;
        goodShell.clear();
        vertexTofind.clear();
    }
}