//---------------------------------------------------------------------------- void Mgc::FindIntersection (const Tetrahedron& rkT0, const Tetrahedron& rkT1, Mgc::TetrahedronConsumer& dest) { // build planar faces of T0 const int planePer=4; Plane akPlane[planePer]; rkT0.GetPlanes(akPlane); /* early-exit test for non-overlapping tets */ if (1) { Plane ak1Plane[planePer]; rkT1.GetPlanes(ak1Plane); if (allOutside(akPlane,planePer,rkT1) || allOutside(ak1Plane,planePer,rkT0)) return; /* tets do not overlap */ } /* Build filter to successively clip tets by each plane of T0, passing the final tets to the user's destination. */ PlaneSplitTetrahedronConsumer cons0(akPlane[0],dest); PlaneSplitTetrahedronConsumer cons1(akPlane[1],cons0); PlaneSplitTetrahedronConsumer cons2(akPlane[2],cons1); PlaneSplitTetrahedronConsumer cons3(akPlane[3],cons2); /* Pass T1 through the filter chain */ cons3.Add(rkT1); }
void AddTetra() { Tetrahedron* tetra = new Tetrahedron(ColouredParticleSystem::RandomVector(30.0) + Vec3(0, 15, 0), (float)rand() * 10.0f / RAND_MAX); tetra->ApplyImpulse(ColouredParticleSystem::RandomVector(0.05f)); tetra->ApplyAngularImpulse(ColouredParticleSystem::RandomVector(0.05f)); tetra->ConvexPolyhedron::SetDebugColour(Vec4(ColouredParticleSystem::RandomVector(1), 1)); PhysicsSystem::GetCurrentInstance()->AddRigidBody(tetra); }
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()) ) ); }
number CalculateVolume(const Tetrahedron& tet, Grid::VertexAttachmentAccessor<APosition>& aaPos) { vector3& a = aaPos[tet.vertex(0)]; vector3& b = aaPos[tet.vertex(1)]; vector3& c = aaPos[tet.vertex(2)]; vector3& d = aaPos[tet.vertex(3)]; return CalculateTetrahedronVolume(a, b, c, d); }
int main(int argc, char *argv[]) { //Add commentar QApplication app(argc, argv); if (!QGLFormat::hasOpenGL()) { cerr << "This system has no OpenGL support" << endl; return 1; } //skuska Tetrahedron tetrahedron; tetrahedron.setWindowTitle(QObject::tr("Tetrahedron")); tetrahedron.resize(300, 300); tetrahedron.show(); return app.exec(); }
/// Centers a tetrahedral mesh (returning a new mesh) void IndexedTetraArray::center() { // determine the centroid of this array of tetrahedra Point3d centroid = Point3d::zero(GLOBAL); double total_volume = 0; for (unsigned i=0; i< num_tetra(); i++) { Tetrahedron tet = get_tetrahedron(i, GLOBAL); double volume = tet.calc_volume(); centroid += tet.calc_centroid()*volume; total_volume += volume; } centroid /= total_volume; // translate the mesh so that the centroid is at the origin for (unsigned i=0; i< _vertices->size(); i++) ((Origin3d&) (*_vertices)[i]) -= Origin3d(centroid); }
void RCNeighbourList::removeDOFParent(int index) { Tetrahedron* el = dynamic_cast<Tetrahedron*>(rclist[index]->el); Mesh* mesh = el->getMesh(); int edges = mesh->getGeo(EDGE); int faces = mesh->getGeo(FACE); if (mesh->getNumberOfDofs(EDGE)) { int node = mesh->getNode(EDGE); for (int j = 0; j < edges; j++) el->setDof(node + j, NULL); } if (mesh->getNumberOfDofs(FACE)) { int node = mesh->getNode(FACE); RCListElement* neigh = rclist[index]->neigh[0]; // face 2 if (!neigh || neigh > rclist[index]) mesh->freeDof(const_cast<DegreeOfFreedom*>(el->getDof(node + 2)), FACE); neigh = rclist[index]->neigh[1]; // face 3 if (!neigh || neigh > rclist[index]) mesh->freeDof(const_cast<DegreeOfFreedom*>(el->getDof(node + 3)), FACE); for (int j = 0; j < faces; j++) el->setDof(node + j, NULL); } if (mesh->getNumberOfDofs(CENTER)) { int node = mesh->getNode(CENTER); mesh->freeDof(const_cast<DegreeOfFreedom*>(el->getDof(node)), CENTER); el->setDof(node, NULL); } }
//---------------------------------------------------------------------------- void Mgc::FindIntersection (const Tetrahedron& rkT0, const Tetrahedron& rkT1, vector<Tetrahedron>& rkIntr) { // build planar faces of T0 Plane akPlane[4]; rkT0.GetPlanes(akPlane); // initial object to clip is T1 rkIntr.clear(); rkIntr.push_back(rkT1); // clip T1 against planes of T0 for (int iP = 0; iP < 4; iP++) { vector<Tetrahedron> kInside; for (int iT = 0; iT < (int)rkIntr.size(); iT++) SplitAndDecompose(rkIntr[iT],akPlane[iP],kInside); rkIntr = kInside; } }
// ------------------------------------------------------------- // 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; }
bool SaveGridToNCDF(Grid& grid, const char* filename, ISubsetHandler* pSH, APosition aPos) { // open the file to which we'll write ofstream out(filename); if(!out) return false; // access subset-handler if(!pSH){ UG_LOG("ERROR: SubsetHandler required for NCDF (Exodus) export.\n"); return false; } ISubsetHandler& sh = *pSH; // access the position attachment if(!grid.has_vertex_attachment(aPos)) return false; if(grid.num_volumes() != grid.num<Tetrahedron>()){ UG_LOG("Saving grid to EXODUS-format.\n" << " WARNING: only Tetrahedrons exported in the moment.\n"); } Grid::VertexAttachmentAccessor<APosition> aaPos(grid, aPos); // assign vertex indices AInt aInt; grid.attach_to_vertices(aInt); Grid::VertexAttachmentAccessor<AInt> aaInt(grid, aInt); AssignIndices(grid.vertices_begin(), grid.vertices_end(), aaInt, 1); // write exodus header int var4 = 4; out << "netcdf object {" << endl; out << "dimensions:" << endl; out << "\tlen_string = 33 ;" << endl; out << "\tlen_line = 81 ;" << endl; out << "\tfour = " << var4 << " ;" << endl; out << "\ttime_step = UNLIMITED ;" << endl; out << "\tnum_dim = 3 ;" << endl; out << "\tnum_nodes = " << grid.num_vertices() << " ;" << endl; out << "\tnum_elem = " << grid.num<Tetrahedron>() << " ;" << endl; out << "\tnum_el_blk = " << sh.num_subsets() << " ;" << endl; for(int i = 0; i < sh.num_subsets(); ++i){ GridObjectCollection goc = sh.get_grid_objects_in_subset(i); out << "\tnum_el_in_blk" << i+1 << " = " << goc.num<Tetrahedron>() << " ;" << endl; out << "\tnum_nod_per_el" << i+1 << " = 4 ;" << endl; } out << "\tnum_qa_rec = 1 ;" << endl; // write variables out << endl; out << "variables:" << endl; out << "\tdouble time_whole(time_step) ;" << endl; out << "\tint eb_status(num_el_blk) ;" << endl; out << "\tint eb_prop1(num_el_blk) ;" << endl; out << "\t\teb_prop1:name = \"ID\" ;" << endl; for(int i = 0; i < sh.num_subsets(); ++i){ out << "\tint connect" << i+1 << "(num_el_in_blk" << i+1 << ", num_nod_per_el" << i+1 << ") ;" << endl; out << "\t\tconnect" << i+1 << ":elem_type = \"TETRA4\" ;" << endl; } out << "\tdouble coord(num_dim, num_nodes) ;" << endl; out << "\tchar qa_records(num_qa_rec, four, len_string) ;" << endl; out << "\tchar coor_names(num_dim, len_string) ;" << endl; out << "\tint elem_map(num_elem) ;" << endl; out << "\tint elem_num_map(num_elem) ;" << endl; out << "\tint node_num_map(num_nodes) ;" << endl; out << "// global attributes:" << endl; out << "\t:api_version = 4.01f ;" << endl; out << "\t:version = 3.01f ;" << endl; out << "\t:floating_point_word_size = " << sizeof(number) << " ;" << endl; out << "\t:file_size = 0 ;" << endl; out << "\t:title = \"Exported from lib_grid.\" ;" << endl; // write data out << endl; out << "data:" << endl; out << "eb_status = "; for(int i = 0; i < sh.num_subsets(); ++i){ out << "1"; if(i + 1 < sh.num_subsets()) out << ", "; } out << " ;" << endl << endl; out << "eb_prop1 = "; for(int i = 0; i < sh.num_subsets(); ++i){ out << i+1; if(i + 1 < sh.num_subsets()) out << ", "; } out << " ;" << endl << endl; // write elements for(int i = 0; i < sh.num_subsets(); ++i){ // get the goc for this subset GridObjectCollection goc = sh.get_grid_objects_in_subset(i); out << "connect" << i+1 << " =" << endl; for(size_t lvl = 0; lvl < goc.num_levels(); ++lvl){ for(TetrahedronIterator iter = goc.begin<Tetrahedron>(lvl); iter != goc.end<Tetrahedron>(lvl); ++iter) { // last comma in each row if(iter != goc.begin<Tetrahedron>(lvl)) out << "," << endl; Tetrahedron* tet = *iter; out << " "; out << aaInt[tet->vertex(0)] << ", "; out << aaInt[tet->vertex(1)] << ", "; out << aaInt[tet->vertex(2)] << ", "; out << aaInt[tet->vertex(3)]; } } out << " ;" << endl << endl; } // write coords // x out << "coord =" << endl << " "; size_t endlCounter = 1; for(VertexIterator iter = grid.vertices_begin(); iter != grid.vertices_end(); ++iter, ++endlCounter) { if(endlCounter > 5){ endlCounter = 1; out << endl << " "; } out << " " << aaPos[*iter].x() << ","; } // y for(VertexIterator iter = grid.vertices_begin(); iter != grid.vertices_end(); ++iter, ++endlCounter) { if(endlCounter > 5){ endlCounter = 1; out << endl << " "; } out << " " << aaPos[*iter].y() << ","; } // z for(VertexIterator iter = grid.vertices_begin(); iter != grid.vertices_end(); ++iter, ++endlCounter) { if(iter != grid.vertices_begin()){ out << ","; if(endlCounter > 5){ endlCounter = 1; out << endl << " "; } } out << " " << aaPos[*iter].z(); } out << " ;" << endl << endl; // write qa_records out << "qa_records =" << endl; out << " \"lib_grid\"," << endl; out << " \"...\"," << endl; out << " \"...\"," << endl; out << " \"...\" ;" << endl; // write coor_names out << endl; out << "coor_names =" << endl; out << " \"x\"," << endl; out << " \"y\"," << endl; out << " \"z\" ;" << endl; // write elem_map out << endl; out << "elem_map = "; endlCounter = 1; for(size_t i = 0; i < grid.num<Tetrahedron>(); ++i, ++endlCounter) { out << i+1; if(i+1 < grid.num<Tetrahedron>()){ out << ", "; if(endlCounter > 4){ endlCounter = 0; out << endl << " "; } } } out << " ;" << endl; // write elem_num_map out << endl; out << "elem_num_map = "; endlCounter = 1; for(size_t i = 0; i < grid.num<Tetrahedron>(); ++i, ++endlCounter) { out << i+1; if(i+1 < grid.num<Tetrahedron>()){ out << ", "; if(endlCounter > 4){ endlCounter = 0; out << endl << " "; } } } out << " ;" << endl; // write node_num_map out << endl; out << "node_num_map = "; endlCounter = 1; for(size_t i = 0; i < grid.num<Vertex>(); ++i, ++endlCounter) { out << i+1; if(i+1 < grid.num<Vertex>()){ out << ", "; if(endlCounter > 4){ endlCounter = 0; out << endl << " "; } } } out << " ;" << endl; // close object out << "}" << endl; // remove vertex indices grid.detach_from_vertices(aInt); // done return true; }
void CpuDelaunayMesher::findDelaunayBall(const glm::ivec3& cId, int vId) { Tetrahedron* base = findBaseTetrahedron(cId, vId); Vertex& v0 = vert[base->v[0]]; Vertex& v1 = vert[base->v[1]]; Vertex& v2 = vert[base->v[2]]; Vertex& v3 = vert[base->v[3]]; _ballQueue.clear(); _ballQueue.push_back(&v0); _ballQueue.push_back(&v1); _ballQueue.push_back(&v2); _ballQueue.push_back(&v3); _ball.xOrTri(base->t0()); _ball.xOrTri(base->t1()); _ball.xOrTri(base->t2()); _ball.xOrTri(base->t3()); removeTetrahedronGrid(base); const glm::dvec3& v = vert[vId].p; ++_currentVisitTime; v0.visitTime = _currentVisitTime; v1.visitTime = _currentVisitTime; v2.visitTime = _currentVisitTime; v3.visitTime = _currentVisitTime; for(int qId = 0; qId < _ballQueue.size(); ++qId) { Vertex* vertex = _ballQueue[qId]; TetListNode* node = vertex->tetList.head; while(node != nullptr) { Tetrahedron* tet = node->tet; node = node->next; if(tet->visitTime < _currentVisitTime) { tet->visitTime = _currentVisitTime; if(intersects(v, tet)) { _ball.xOrTri(tet->t0()); _ball.xOrTri(tet->t1()); _ball.xOrTri(tet->t2()); _ball.xOrTri(tet->t3()); // First 8 vertices are corner vertices and are generally // touching a large 'fan' of tetrahedron. Those tetrahedrons // are still accessible via inserted neighboring vertices. const int BOUNDING_VERTICES = 8; if(tet->v[0] >= BOUNDING_VERTICES) { Vertex* tv0 = &vert[tet->v[0]]; if(tv0->visitTime < _currentVisitTime) { tv0->visitTime = _currentVisitTime; _ballQueue.push_back(tv0); } } if(tet->v[1] >= BOUNDING_VERTICES) { Vertex* tv1 = &vert[tet->v[1]]; if(tv1->visitTime < _currentVisitTime) { tv1->visitTime = _currentVisitTime; _ballQueue.push_back(tv1); } } if(tet->v[2] >= BOUNDING_VERTICES) { Vertex* tv2 = &vert[tet->v[2]]; if(tv2->visitTime < _currentVisitTime) { tv2->visitTime = _currentVisitTime; _ballQueue.push_back(tv2); } } if(tet->v[3] >= BOUNDING_VERTICES) { Vertex* tv3 = &vert[tet->v[3]]; if(tv3->visitTime < _currentVisitTime) { tv3->visitTime = _currentVisitTime; _ballQueue.push_back(tv3); } } removeTetrahedronGrid(tet); } } } } }
DeformableBody* MeshLoader::tetrahedron( void ) { DeformableBody* body = new DeformableBody( ); Mesh* mesh = new Mesh( ); body->mesh = mesh; // -- build the mesh -- /* // x unit vector. Will rotate it around the unit sphere in x and z Vector3 i_hat = Vector3( 1.0, 0.0, 0.0 ); // y unit vector. Will be the top of the tetrahedron Vector3 j_hat = Vector3( 0.0, 1.0, 0.0 ); Vector3 u; // rotate x_hat around z axis by 30 degrees for first vertex u = Matrix3::rotZ( -1.0 * 1.0/12.0 * 2.0 * PI ) * i_hat; Vertex* v1 = new Vertex( u, u ); // now rotate u around the y axis 120 degrees for second vertex u = Matrix3::rotY( 1.0/3.0 * 2.0 * PI ) * u; Vertex* v2 = new Vertex( u, u ); // now rotate u around the y axis another 120 degrees for third vertex u = Matrix3::rotY( 1.0/3.0 * 2.0 * PI ) * u; Vertex* v3 = new Vertex( u, u ); Vertex* v4 = new Vertex( j_hat, j_hat ); */ // Note the following is defined by Schneider & Eberly : Geometric Tools for Computer Graphics p. 347 Vector3 u; u = Vector3( 2.0*sqrt(2.0)/3.0, -1.0/3.0, 0.0 ); Vertex* v1 = new Vertex( u, u ); u = Vector3( -sqrt(2.0)/3.0, -1.0/3.0, sqrt(6.0)/3.0 ); Vertex* v2 = new Vertex( u, u ); u = Vector3( -sqrt(2.0)/3.0, -1.0/3.0, -sqrt(6.0)/3.0 ); Vertex* v3 = new Vertex( u, u ); u = Vector3( 0.0, 1.0, 0.0 ); Vertex* v4 = new Vertex( u, u ); ///* v1->position.print(); printf("\n"); v2->position.print(); printf("\n"); v3->position.print(); printf("\n"); v4->position.print(); printf("\n"); //*/ Trigon* t; t = new Trigon( ); t->addVertex( 0 ); t->addVertex( 1 ); t->addVertex( 3 ); mesh->appendPolygon( t ); t = new Trigon( ); t->addVertex( 1 ); t->addVertex( 2 ); t->addVertex( 3 ); mesh->appendPolygon( t ); t = new Trigon( ); t->addVertex( 2 ); t->addVertex( 0 ); t->addVertex( 3 ); mesh->appendPolygon( t ); t = new Trigon( ); t->addVertex( 0 ); t->addVertex( 1 ); t->addVertex( 2 ); mesh->appendPolygon( t ); // -- build the body -- Node* node1, *node2, *node3, *node4; Spring* edge1, *edge2, *edge3, *edge4, *edge5, *edge6; Tetrahedron* tetra; mesh->appendVertex( v1 ); node1 = new Node( ); node1->vertex = v1; node1->mass = 0.25; body->appendNode( node1 ); mesh->appendVertex( v2 ); node2 = new Node( ); node2->vertex = v2; node2->mass = 0.25; body->appendNode( node2 ); mesh->appendVertex( v3 ); node3 = new Node( ); node3->vertex = v3; node3->mass = 0.25; body->appendNode( node3 ); mesh->appendVertex( v4 ); node4 = new Node( ); node4->vertex = v4; node4->mass = 0.25; body->appendNode( node4 ); edge1 = new Spring( node1, node2, TETRA_SPRING_COEFFICIENT, TETRA_DAMPING_COEFFICIENT ); edge2 = new Spring( node2, node3, TETRA_SPRING_COEFFICIENT, TETRA_DAMPING_COEFFICIENT ); edge3 = new Spring( node3, node1, TETRA_SPRING_COEFFICIENT, TETRA_DAMPING_COEFFICIENT ); edge4 = new Spring( node1, node4, TETRA_SPRING_COEFFICIENT, TETRA_DAMPING_COEFFICIENT ); edge5 = new Spring( node2, node4, TETRA_SPRING_COEFFICIENT, TETRA_DAMPING_COEFFICIENT ); edge6 = new Spring( node3, node4, TETRA_SPRING_COEFFICIENT, TETRA_DAMPING_COEFFICIENT ); body->appendEdge( edge1 ); body->appendEdge( edge2 ); body->appendEdge( edge3 ); body->appendEdge( edge4 ); body->appendEdge( edge5 ); body->appendEdge( edge6 ); tetra = new Tetrahedron( ); tetra->insert( node1 ); tetra->insert( node2 ); tetra->insert( node3 ); tetra->insert( node4 ); tetra->insert( edge1 ); tetra->insert( edge2 ); tetra->insert( edge3 ); tetra->insert( edge4 ); tetra->insert( edge5 ); tetra->insert( edge6 ); body->appendTetrahedron( tetra ); return body; }
// creates edge and triangle structures and links them to existing vertex/tetrahedron structure, to permit storing attributes void createAggregateDataStructure(){ int i, j; // traverse all tetrahedra and create their triangles, edges and references to them stack<Cell> tetraStack; tetraStack.push(dt->infinite_cell()); // while stack not empty while (tetraStack.size() > 0){ // pop tetra from stack Cell ch = tetraStack.top(); tetraStack.pop(); Tetrahedron *currTetra = &ch->info(); // DEBUG // cout << "tetra " << COUT_CELL(ch) << endl; bool triangleCreated[4]; Edge *edge[6]; for (i = 0; i < 6; i++) edge[i] = NULL; // reference its four triangles (create if not yet existing) for (i = 0; i < 4; i++) { triangleCreated[i] = false; // look up at neighbor tetrahedron Cell oppCH = ch->neighbor(i); int oppIndex = oppCH->index(ch); Tetrahedron *oppTetra = &oppCH->info(); // test if triangle exists already Triangle *triangle = oppTetra->triangle(oppIndex); if (triangle == NULL){ triangleCreated[i] = true; // create new triangle //int vIndex[3]; //for (j = 0; j < 3; j++) // // vIndex[j] = (i + 1 + j) % 4; // vIndex[j] = tetraTriVertexIndices[i][j]; Triangle newTriangle(ch, i); dtTriangles.push_back(newTriangle); triangle = &dtTriangles.back(); // also push tetrahedron on stack as unhandled tetraStack.push(oppCH); // DEBUG // cout << "triangle " << *triangle << " created" << endl; } currTetra->setTriangle(i, triangle); // reference triangle oppTetra->setTriangle(oppIndex, triangle); // also in opposite tetrahedron } // reference its six edges (create if not yet existing) for (i = 0; i < 6; i++){ int edgeVIndex[2]; for (j = 0; j < 2; j++) edgeVIndex[j] = ch->vertex(tetraEdgeVertexIndices[i][j])->info().index(); sort(edgeVIndex, edgeVIndex + 2); IntPair intPair(edgeVIndex[0], edgeVIndex[1]); map<IntPair, Edge>::iterator mapIter = dtEdgeMap.find(intPair); if (mapIter != dtEdgeMap.end()) edge[i] = &mapIter->second; else { Edge newEdge(ch, tetraEdgeVertexIndices[i][0], tetraEdgeVertexIndices[i][1]); dtEdgeMap.insert(pair<IntPair, Edge>(intPair, newEdge)); map<IntPair, Edge>::iterator mapIter = dtEdgeMap.find(intPair); edge[i] = &mapIter->second; } } // only set edges into newly created triangles for (i = 0; i < 4; i++) if (triangleCreated[i]) for (j = 0; j < 3; j++) currTetra->triangle(i)->setEdge(j, edge[tetraTriEdgeIndices[i][j]]); } // DEBUG cout << "aggregate data structure: " << dtEdgeMap.size() << " edges, " << dtTriangles.size() << " triangles" << endl; }
/** * Determines whether or not the node intersects the given tetrahedron * @param tetrahedron The tetrahedron to check * @return TRUE if the tetrahedron intersects the box, FALSE otherwise */ bool SpatialPartitionNode::intersects( const Tetrahedron & tetrahedron ) const { return boxesOverlap( box, tetrahedron.bbox() ); }