int Tetgen::correctPolyTetraAdd(vector<int>&tet_id_buff, vector<Adpt>&adpt_buff,Node* cr_nd) { int i,j; Tetra* crtet,* nbtet; Node* nd0,* nd1,* nd2; Adpt tmp_adpt; const int ij0[4] = {1,2,3,0}; const int ij1[4] = {3,3,1,1}; const int ij2[4] = {2,0,0,2}; //pick up surface triangle(=adpt_buff) of poly tetrahedra(polygon)(=tet_id_buff) i = 0; int n = (int)tet_id_buff.size(); while (i < n) { crtet = getTetra(tet_id_buff[i] - 1); for (j = 0; j < 4; j++) { nbtet = crtet->getNeighborElement(j); nd0 = crtet->getNode(ij0[j]); nd1 = crtet->getNode(ij1[j]); nd2 = crtet->getNode(ij2[j]); if (!nbtet) { tmp_adpt.face[0] = nd0; tmp_adpt.face[1] = nd1; tmp_adpt.face[2] = nd2; tmp_adpt.neib = NULL; tmp_adpt.num = 0; tmp_adpt.vol = getTetraVolume(nd0,nd1,nd2,cr_nd); adpt_buff.push_back(tmp_adpt); } //if !nbtet else if (nbtet->getState() != 1) { tmp_adpt.face[0] = nd0; tmp_adpt.face[1] = nd1; tmp_adpt.face[2] = nd2; tmp_adpt.neib = nbtet; tmp_adpt.num = nbtet->getConection(crtet); tmp_adpt.vol = getTetraVolume(nd0,nd1,nd2,cr_nd); adpt_buff.push_back(tmp_adpt); if (tmp_adpt.vol < LIMIT) { tet_id_buff.push_back(nbtet->getId()); nbtet->setState(1); adpt_buff.clear(); i = -1; n = (int)tet_id_buff.size(); break; } } //else if nbtet->getState() != 1 } //for j i++; } //while i < tet_id_buff.size() return (int)tet_id_buff.size(); }
float FEMTetrahedronMesh::volume() const { float r = 0.f; for(unsigned i = 0; i < m_totalTetrahedrons; i++) r += getTetraVolume(m_tetrahedron[i]); return r; }
int Tetgen::isPossibleMerge(Node* po_nd,Node* ne_nd,deque<Tetra*>&pohang, deque<Tetra*>&nehang) { double vol,pre_vol,pst_vol; Tetra* ptet; Node* nd1,* nd2,* nd3; int edge; double mindens,minvolm; const int ij0[4] = {1,2,3,0}; const int ij1[4] = {3,3,1,1}; const int ij2[4] = {2,0,0,2}; mindens = cr_crowd->getCurrentMinDensity(); minvolm = mindens * mindens * mindens * rate_minvolm * 0.5; pre_vol = pst_vol = 0.; int n = (int)pohang.size(); for(int i = 0; i < n; i++) { ptet = pohang[i]; pre_vol += ptet->getVolume(); edge = ptet->getNodeNumber(ne_nd); nd1 = ptet->getNode(ij0[edge]); nd2 = ptet->getNode(ij1[edge]); nd3 = ptet->getNode(ij2[edge]); vol = getTetraVolume(nd1,nd2,nd3,po_nd); printf("pr %20.15f\n",pre_vol); printf("%5d%5d%5d%5d\n",po_nd->getId(),nd1->getId(),nd2->getId(), nd3->getId()); printf("%20.15f\n",vol); //check area //if new area is too small( area < minvolm ), do not merge //but it possible to merge, if you want to do ////if(vol < minvolm) return 0; if(vol < LIMIT_10) return 0; pst_vol += vol; } n = (int)nehang.size(); for(int i = 0; i < n; i++) { ptet = nehang[i]; pre_vol += ptet->getVolume(); } printf("pre %20.15f\n",pre_vol); printf("pst %20.15f\n",pst_vol); getch(); //if pst_vol > pre_vol(or pst_vol < pre_vol ), cannot merge if(fabs(pre_vol - pst_vol) > LIMIT) return 0; return 1; }
float FEMTetrahedronMesh::getTetraVolume(Tetrahedron & tet) const { Vector3F x0 = m_X[tet.indices[0]]; Vector3F x1 = m_X[tet.indices[1]]; Vector3F x2 = m_X[tet.indices[2]]; Vector3F x3 = m_X[tet.indices[3]]; Vector3F e10 = x1-x0; Vector3F e20 = x2-x0; Vector3F e30 = x3-x0; return getTetraVolume(e10,e20,e30); }
int Tetgen::correctPolyTetraCut(vector<int>&tet_id_buff, vector<Adpt>&adpt_buff,Node* cr_nd) { int i,j; Tetra* crtet,* nbtet; Adpt tmp_adpt; const int ij0[4] = {1,2,3,0}; const int ij1[4] = {3,3,1,1}; const int ij2[4] = {2,0,0,2}; ///adpt.reserve(tet_id_buff.size()*2); //pick up surface triangle(=adpt_buff) of poly tetrahedra(polygon)(=tet_id_buff) //this part is diffarent from function Poly (other parts are almost same) i = 0; int n = (int)tet_id_buff.size(); while (i < n) { crtet = getTetra(tet_id_buff[i] - 1); for (j = 0; j < 4; j++) { nbtet = crtet->getNeighborElement(j); if (!nbtet) { tmp_adpt.face[0] = crtet->getNode(ij0[j]); tmp_adpt.face[1] = crtet->getNode(ij1[j]); tmp_adpt.face[2] = crtet->getNode(ij2[j]); tmp_adpt.neib = NULL; tmp_adpt.num = 0; tmp_adpt.vol = getTetraVolume(tmp_adpt.face[0], tmp_adpt.face[1], tmp_adpt.face[2], cr_nd); adpt_buff.push_back(tmp_adpt); if(tmp_adpt.vol < LIMIT) { crtet->setState(-1); tet_id_buff[i] = tet_id_buff[tet_id_buff.size() - 1]; tet_id_buff.pop_back(); adpt_buff.clear(); i = -1; n = (int)tet_id_buff.size(); break; } } //if !nbtet else if (nbtet->getState() != 1) { tmp_adpt.face[0] = crtet->getNode(ij0[j]); tmp_adpt.face[1] = crtet->getNode(ij1[j]); tmp_adpt.face[2] = crtet->getNode(ij2[j]); tmp_adpt.neib = nbtet; tmp_adpt.num = nbtet->getConection(crtet); tmp_adpt.vol = getTetraVolume(tmp_adpt.face[0], tmp_adpt.face[1], tmp_adpt.face[2], cr_nd); adpt_buff.push_back(tmp_adpt); if (tmp_adpt.vol < LIMIT) { crtet->setState(-1); tet_id_buff[i] = tet_id_buff[tet_id_buff.size() - 1]; tet_id_buff.pop_back(); adpt_buff.clear(); n = (int)tet_id_buff.size(); i = -1; break; } } //else if nbtet->getState() != 1 } //for j i++; } //while i < tet_id_buff.size() return (int)tet_id_buff.size(); }