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()) ) ); }
// ------------------------------------------------------------- // 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(); } }