static void normalize(float &nx, float &ny, float &nz) { Vec3 tmpv(nx, ny, nz); VecUtils::normalize(tmpv); nx = tmpv.x; ny = tmpv.y; nz = tmpv.z; }
void Polyhedron_triangulation::extract_CAT() { std::for_each(cat_cells.begin(), cat_cells.end(), std::mem_fun_ref(&std::list<CAT_facet>::clear)); int *tetra_vtx_ptr = tetra_mesh.tetrahedronlist; int *marker = tetra_mesh.pointmarkerlist; REAL *pnt_tbl = tetra_mesh.pointlist; std::function<Point_3(int)> cgal_pnt = [=](int idx) { return Point_3(pnt_tbl[idx*3], pnt_tbl[idx*3+1], pnt_tbl[idx*3+2]); }; for (int i = 0; i < tetra_mesh.numberoftetrahedra; i++, tetra_vtx_ptr += 4) { std::set<int> group_no; std::multimap<int, int> group_no_vidx; typedef std::multimap<int, int>::const_iterator Iter; for (int j = 0; j < 4; j++) { int vid = tetra_vtx_ptr[j]; int gid = marker[vid]; group_no.insert(gid); group_no_vidx.insert(std::make_pair(gid, vid)); } if (group_no.size() == 2) { std::set<int>::const_iterator gid0 = group_no.begin(), gid1 = group_no.begin(); ++gid1; if (group_no_vidx.count(*gid0) == 1 && group_no_vidx.count(*gid1) == 3) { std::pair<Iter, Iter> i0 = group_no_vidx.equal_range(*gid0); std::pair<Iter, Iter> i1 = group_no_vidx.equal_range(*gid1); std::list<Point_3> mid_tri; for (Iter it = i1.first; it != i1.second; ++it) mid_tri.push_back(CGAL::midpoint(cgal_pnt(i0.first->second), cgal_pnt(it->second))); if (*gid0 >= 0) cat_cells[*gid0].push_back(CAT_facet(cgal_pnt(i0.first->second), mid_tri)); if (*gid1 >= 0) for (Iter it = i1.first; it != i1.second; ++it) cat_cells[*gid1].push_back(CAT_facet(cgal_pnt(it->second), mid_tri)); } else if (group_no_vidx.count(*gid0) == 3 && group_no_vidx.count(*gid1) == 1) { std::pair<Iter, Iter> i0 = group_no_vidx.equal_range(*gid0); std::pair<Iter, Iter> i1 = group_no_vidx.equal_range(*gid1); std::list<Point_3> mid_tri; for (Iter it = i0.first; it != i0.second; ++it) mid_tri.push_back(CGAL::midpoint(cgal_pnt(i1.first->second), cgal_pnt(it->second))); if (*gid1 >= 0) cat_cells[*gid1].push_back(CAT_facet(cgal_pnt(i1.first->second), mid_tri)); if (*gid0 >= 0) for (Iter it = i0.first; it != i0.second; ++it) cat_cells[*gid0].push_back(CAT_facet(cgal_pnt(it->second), mid_tri)); } else { std::pair<Iter, Iter> i0 = group_no_vidx.equal_range(*gid0); std::pair<Iter, Iter> i1 = group_no_vidx.equal_range(*gid1); Iter it = i0.first; Point_3 p00(cgal_pnt(it->second)); ++it; Point_3 p01(cgal_pnt(it->second)); it = i1.first; Point_3 p10(cgal_pnt(it->second)); ++it; Point_3 p11(cgal_pnt(it->second)); Point_3 midpnt[4] = {CGAL::midpoint(p00, p10), CGAL::midpoint(p00, p11), CGAL::midpoint(p01, p10), CGAL::midpoint(p01, p11)}; std::list<Point_3> mid_pm; // the middle parallelogram mid_pm.push_back(midpnt[0]); mid_pm.push_back(midpnt[1]); if (Vector_3(midpnt[0], midpnt[1])*Vector_3(midpnt[2], midpnt[3]) < 0) { mid_pm.push_back(midpnt[2]); mid_pm.push_back(midpnt[3]); } else { mid_pm.push_back(midpnt[3]); mid_pm.push_back(midpnt[2]); } if (*gid0 >= 0) { cat_cells[*gid0].push_back(CAT_facet(p00, mid_pm)); cat_cells[*gid0].push_back(CAT_facet(p01, mid_pm)); } if (*gid1 >= 0) { cat_cells[*gid1].push_back(CAT_facet(p10, mid_pm)); cat_cells[*gid1].push_back(CAT_facet(p11, mid_pm)); } } } else if (group_no.size() == 3) { // the two vertices in the same group int smgp[2]; // the two vertices in the other two different groups int dfgp[2]; int gi, gj, gk; std::vector< std::pair<int, int> > tmpv(group_no_vidx.begin(), group_no_vidx.end()); if (tmpv[0].first == tmpv[1].first) { smgp[0] = tmpv[0].second; smgp[1] = tmpv[1].second; gi = tmpv[0].first; dfgp[0] = tmpv[2].second; dfgp[1] = tmpv[3].second; gj = tmpv[2].first; gk = tmpv[3].first; } else if (tmpv[1].first == tmpv[2].first) { smgp[0] = tmpv[1].second; smgp[1] = tmpv[2].second; gi = tmpv[1].first; dfgp[0] = tmpv[0].second; dfgp[1] = tmpv[3].second; gj = tmpv[0].first; gk = tmpv[3].first; } else { smgp[0] = tmpv[2].second; smgp[1] = tmpv[3].second; gi = tmpv[2].first; dfgp[0] = tmpv[0].second; dfgp[1] = tmpv[1].second; gj = tmpv[0].first; gk = tmpv[1].first; } Point_3 pi[2] = {cgal_pnt(smgp[0]), cgal_pnt(smgp[1])}; Point_3 pj(cgal_pnt(dfgp[0])), pk(cgal_pnt(dfgp[1])); Point_3 tri_cent[2] = {CGAL::centroid(pi[0], pj, pk), CGAL::centroid(pi[1], pj, pk)}; Point_3 edge_mid[5] = {CGAL::midpoint(pi[0], pj), CGAL::midpoint(pi[0], pk), CGAL::midpoint(pi[1], pj), CGAL::midpoint(pi[1], pk), CGAL::midpoint(pj, pk)}; //std::list<Point_3> quad_i0i1j, quad_i0i1k, tri_i0i1jk; std::array<Point_3, 4> quad_i0i1j = {edge_mid[0], edge_mid[2], tri_cent[1], tri_cent[0]}; std::array<Point_3, 4> quad_i0i1k = {edge_mid[1], edge_mid[3], tri_cent[1], tri_cent[0]}; std::array<Point_3, 3> tri_i0i1jk = {edge_mid[4], tri_cent[1], tri_cent[0]}; if (gi >= 0) { cat_cells[gi].push_back(CAT_facet(pi[0], quad_i0i1j.begin(), quad_i0i1j.end())); cat_cells[gi].push_back(CAT_facet(pi[0], quad_i0i1k.begin(), quad_i0i1k.end())); cat_cells[gi].push_back(CAT_facet(pi[1], quad_i0i1j.begin(), quad_i0i1j.end())); cat_cells[gi].push_back(CAT_facet(pi[1], quad_i0i1k.begin(), quad_i0i1k.end())); } if (gj >= 0) { cat_cells[gj].push_back(CAT_facet(pj, quad_i0i1j.begin(), quad_i0i1j.end())); cat_cells[gj].push_back(CAT_facet(pj, tri_i0i1jk.begin(), tri_i0i1jk.end())); } if (gk >= 0) { cat_cells[gk].push_back(CAT_facet(pk, quad_i0i1k.begin(), quad_i0i1k.end())); cat_cells[gk].push_back(CAT_facet(pk, tri_i0i1jk.begin(), tri_i0i1jk.end())); } } else if (group_no.size() == 4) { std::array<Point_3, 4> vs; std::array<int, 4> groupid; for (int j = 0; j < 4; j++) { vs[j] = cgal_pnt(tetra_vtx_ptr[j]); groupid[j] = marker[tetra_vtx_ptr[j]]; } Point_3 tetra_cent = CGAL::centroid(vs.begin(), vs.end(), CGAL::Dimension_tag<0>()); for (int j = 0; j < 4; j++) { if (groupid[j] < 0) continue; for (int k = 0; k < 4; k++) { if (j == k) continue; for (int l = 0; l < 4; l++) { if (l == j || l == k) continue; Point_3 mpnt = CGAL::midpoint(vs[j], vs[k]); int m; for (m = 0; m < 4; m++) if (m != j && m != k && m != l) break; Point_3 tri_cent[2] = { CGAL::centroid(vs[j], vs[k], vs[l]), CGAL::centroid(vs[j], vs[k], vs[m]) }; std::list<Point_3> tri; tri.push_back(mpnt); tri.push_back(tri_cent[0]); tri.push_back(tri_cent[1]); cat_cells[groupid[j]].push_back(CAT_facet(vs[j], tri)); tri.pop_front(); tri.push_back(tetra_cent); cat_cells[groupid[j]].push_back(CAT_facet(vs[j], tri)); } } } } } }
void EGS_TrackView::renderTracks(int nx, int ny, EGS_Vector *image) { EGS_Vector tmpv(0,0,0), tmpv2(0,0,0), tmpv3(0,0,0); int di, xxx1, xxx2, yyy1, yyy2; double e1, e2, dst1, dst2; double xx1, xx2, yy1, yy2, s1, s2, dx, dy, dd, de, cx, cy, gd, ge; for (int i = 0; i < m_nTracks; i++) { // no reason to render the track if it has less than 2 vertices if (m_buffer[i]->getNumVertices() < 2) continue; EGS_ParticleTrack::ParticleInfo *pInfo = m_buffer[i]->getParticleInfo(); // check if the user wants to see this type of particles if (pInfo->q == 0 && !m_vis_particle[1]) continue; else if (pInfo->q == -1 && !m_vis_particle[2]) continue; else if (pInfo->q == 1 && !m_vis_particle[3]) continue; else if ((pInfo->q > 1 || pInfo->q < -1) && !m_vis_particle[4]) continue; // get initial vertex of the track - begining EGS_ParticleTrack::Vertex *v1 = m_buffer[i]->getVertex(0); // calculate distance from camera to projection plane along (v1-xo) s1 = (1 - m_scr_a*xo.x - m_scr_b*xo.y - m_scr_c*xo.z) / (m_scr_a*(v1->x.x-xo.x)+m_scr_b*(v1->x.y-xo.y)+m_scr_c*(v1->x.z-xo.z)); // calculate coordinates of the projection point tmpv = (xo + ((v1->x-xo)*s1) - x_screen); xx1 = tmpv * v1_screen; yy1 = tmpv * v2_screen; // convert to pixel coordinates xxx1 = (sx / 2 + xx1) / (sx / nx); yyy1 = (sy / 2 + yy1) / (sy / ny); // get energy of the particle at this vertex e1 = v1->e; // get distance between camera and vertex dst1 = (v1->x - xo).length(); /* set the color of this particle 1.0 = photon = yellow 2.0 = electron = red 3.0 = positron = blue 4.0 = unknown = white */ if (pInfo->q == 0) { tmpv2.x = 1.0; } else if (pInfo->q == -1) { tmpv2.x = 2.0; } else if (pInfo->q == 1) { tmpv2.x = 3.0; } else tmpv2.x = 4.0; for (int j = 1; j < m_buffer[i]->getNumVertices(); j++) { // get the next vertex along the current track EGS_ParticleTrack::Vertex *v2 = m_buffer[i]->getVertex(j); s2 = (1 - m_scr_a*xo.x - m_scr_b*xo.y - m_scr_c*xo.z) / (m_scr_a*(v2->x.x-xo.x)+m_scr_b*(v2->x.y-xo.y)+m_scr_c*(v2->x.z-xo.z)); // double myw = (v2->x.x*v2->x.x + v2->x.y*v2->x.y) / (1.0*v2->x.z*v2->x.z); // if (myw > 1) break; // calculate coordinates of the projection point for the new vertex tmpv = (xo + ((v2->x-xo)*s2) - x_screen); xx2 = tmpv * v1_screen; yy2 = tmpv * v2_screen; // convert to pixel coordinates xxx2 = (sx / 2 + xx2) / (sx / nx); yyy2 = (sy / 2 + yy2) / (sy / ny); // get energy of the particle at this vertex e2 = v2->e/m_maxE; // // set transparency based on distance to z axis // double myd = (v2->x.x*v2->x.x + v2->x.y*v2->x.y)/9; // e2 = exp(-sqrt(myd)); // get distance between camera and vertex dst2 = (v2->x - xo).length(); // calculate some help variables dx = (xxx2 - xxx1); dy = (yyy2 - yyy1); dd = (dst2 - dst1); de = (e2 - e1); gd = dst1; ge = e1; if (dx == 0.0000 && dy == 0.0000) continue; // iterate along the longer side if (abs(dx) > abs(dy)) { di = (xxx1 > xxx2) ? -1 : 1; cy = yyy1; dy = dy / abs(dx); dd = dd / abs(dx); de = de / abs(dx); // for each x calculate the corresponding y for (int cx = xxx1; cx != xxx2; cx += di) { // render only if we are inside the screen if (cx >= 0 && cx < nx && cy >= 0 && cy < ny) { // grab what's already in the image buffer at this location tmpv3 = image[cx + ((int)(cy))*nx]; if (tmpv3.z < 0) { // there is already a track there if (-gd > tmpv3.z) tmpv3.z = -gd; // current track is closer if (tmpv2.x > tmpv3.x) tmpv3.x = tmpv2.x; // put "important" particles in front tmpv3.y += (1-tmpv3.y)*e2; // compound transparency values } else { tmpv3.x = tmpv2.x; tmpv3.y=e2; tmpv3.z=-gd; // just update with current track info } // write new values to image buffer image[cx + ((int)(cy))*nx] = tmpv3; } cy += dy; gd += dd; ge += de; } } else { di = (yyy1 > yyy2) ? -1 : 1; cx = xxx1; dx = dx / abs(dy); dd = dd / abs(dy); de = de / abs(dy); // for each y calculate the corresponding x for (int cy = yyy1; cy != yyy2; cy += di) { // render only if we are inside the screen if (cx >= 0 && cx < nx && cy >= 0 && cy < ny) { // grab what's already in the image buffer at this location tmpv3 = image[(int)(cx) + cy*nx]; if (tmpv3.z < 0) { // there is already a track there if (-gd > tmpv3.z) tmpv3.z = -gd; // current track is closer if (tmpv2.x > tmpv3.x) tmpv3.x = tmpv2.x; // put "important" particles in front tmpv3.y += (1-tmpv3.y)*e2; // compound transparency values } else { tmpv3.x = tmpv2.x; tmpv3.y=e2; tmpv3.z=-gd; // just update with current track info } // write new values to image buffer image[(int)(cx) + cy*nx] = tmpv3; } cx += dx; gd += dd; ge += de; } } // save already calculated data for the next segment v1 = v2; s1 = s2; xx1 = xx2; yy1 = yy2; xxx1 = xxx2; yyy1 = yyy2; e1 = e2; dst1 = dst2; } } }
void TriangleType::draw(RenderMode::WhichColorMode& wcm, RenderMode::RenderType& r,const Matrix44& adjust_matrix, const Vec3& bias) { if (!visible_) { return; } // std::vector<Vertex*>& vs = sample_.vertices_; //r = RenderMode::PointMode; switch(r) { case RenderMode::PointMode:{ break; } case RenderMode::FlatMode:{ glBegin(GL_TRIANGLES); for( int i = 0 ;i <3 ;++i) { if(this->i_norm[i]!=-1) { Vec4 tmpn( sample_[this->i_norm[i]].nx() , sample_[this->i_norm[i]].ny() ,sample_[this->i_norm[i]].nz() ,1.); Vec4 normal_to_show = tmpn;//adjust_matrix * tmpn; glNormal3f( normal_to_show(0), normal_to_show(1), normal_to_show(2)); //Logger<<"NORMAL: "<<(float)vs[this->i_norm[i]]->nx()<<" "<< // (float)vs[this->i_norm[i]]->ny()<<" "<< // (float)vs[this->i_norm[i]]->nz()<<std::endl; } ColorType color2 = Color_Utility::span_color_from_table(sample_[this->i_vertex[i]].label()); glColor3f( color2(0) ,color2(1) ,color2(2) /* (GLfloat) vs[this->i_vertex[i]]->r(), (GLfloat) vs[this->i_vertex[i]]->g(), (GLfloat) vs[this->i_vertex[i]]->b()*/ ); //Logger<<"COLOR: "<<vs[this->i_vertex[i]]->r()<<" "<< // vs[this->i_vertex[i]]->g()<<" "<< // vs[this->i_vertex[i]]->b()<<std::endl; Vec4 tmpv( sample_[this->i_vertex[i]].x() , sample_[this->i_vertex[i]].y() ,sample_[this->i_vertex[i]].z() ,1.); Vec4 point_to_show = adjust_matrix * tmpv; glVertex3f( point_to_show(0)+ bias(0), point_to_show(1)+ bias(1), point_to_show(2)+ bias(2) ); //Logger<<"VERTEX: "<<vs[this->i_vertex[i]]->x()<<" "<< // vs[this->i_vertex[i]]->y()<<" "<< // vs[this->i_vertex[i]]->z()<<std::endl; } glEnd(); break; } case RenderMode::WireMode:{ glLineWidth(2.0f); glBegin(GL_LINE_LOOP); for( int i = 0 ;i <3 ;++i) { if(this->i_norm[i]!=-1) { Vec4 tmpn( sample_[this->i_norm[i]].nx() , sample_[this->i_norm[i]].ny() ,sample_[this->i_norm[i]].nz() ,1.); Vec4 normal_to_show = adjust_matrix * tmpn; glNormal3f( normal_to_show(0), normal_to_show(1), normal_to_show(2)); } ColorType color2 = Color_Utility::span_color_from_table(sample_[this->i_vertex[i]].label()); glColor3f( color2(0) ,color2(1) ,color2(2) /*(GLfloat) vs[this->i_vertex[i]]->r(), (GLfloat) vs[this->i_vertex[i]]->g(), (GLfloat) vs[this->i_vertex[i]]->b() */); Vec4 tmpv( sample_[this->i_vertex[i]].x() , sample_[this->i_vertex[i]].y() ,sample_[this->i_vertex[i]].z() ,1.); Vec4 point_to_show = adjust_matrix * tmpv; glVertex3f( point_to_show(0)+ bias(0), point_to_show(1)+ bias(1), point_to_show(2)+ bias(2) ); } glEnd(); break; } case RenderMode::FlatWireMode:{ glBegin(GL_TRIANGLES); for( int i = 0 ;i <3 ;++i) { if(this->i_norm[i]!=-1) { Vec4 tmpn( sample_[this->i_norm[i]].nx() , sample_[this->i_norm[i]].ny() ,sample_[this->i_norm[i]].nz() ,1.); Vec4 normal_to_show = tmpn;//adjust_matrix * tmpn; glNormal3f( normal_to_show(0), normal_to_show(1), normal_to_show(2)); //Logger<<"NORMAL: "<<(float)vs[this->i_norm[i]]->nx()<<" "<< // (float)vs[this->i_norm[i]]->ny()<<" "<< // (float)vs[this->i_norm[i]]->nz()<<std::endl; } ColorType color2 = Color_Utility::span_color_from_table(sample_[this->i_vertex[i]].label()); glColor3f( color2(0) ,color2(1) ,color2(2) /* (GLfloat) vs[this->i_vertex[i]]->r(), (GLfloat) vs[this->i_vertex[i]]->g(), (GLfloat) vs[this->i_vertex[i]]->b()*/ ); //Logger<<"COLOR: "<<vs[this->i_vertex[i]]->r()<<" "<< // vs[this->i_vertex[i]]->g()<<" "<< // vs[this->i_vertex[i]]->b()<<std::endl; Vec4 tmpv( sample_[this->i_vertex[i]].x() , sample_[this->i_vertex[i]].y() ,sample_[this->i_vertex[i]].z() ,1.); Vec4 point_to_show = adjust_matrix * tmpv; glVertex3f( point_to_show(0)+ bias(0), point_to_show(1)+ bias(1), point_to_show(2)+ bias(2) ); //Logger<<"VERTEX: "<<vs[this->i_vertex[i]]->x()<<" "<< // vs[this->i_vertex[i]]->y()<<" "<< // vs[this->i_vertex[i]]->z()<<std::endl; } glEnd(); glLineWidth(2.0f); glBegin(GL_LINE_LOOP); for( int i = 0 ;i <3 ;++i) { if(this->i_norm[i]!=-1) { Vec4 tmpn( sample_[this->i_norm[i]].nx() , sample_[this->i_norm[i]].ny() ,sample_[this->i_norm[i]].nz() ,1.); Vec4 normal_to_show = adjust_matrix * tmpn; glNormal3f( normal_to_show(0), normal_to_show(1), normal_to_show(2)); } glColor3f( 0.5f,0.5f,0.5f /*(GLfloat) vs[this->i_vertex[i]]->r(), (GLfloat) vs[this->i_vertex[i]]->g(), (GLfloat) vs[this->i_vertex[i]]->b() */); Vec4 tmpv( sample_[this->i_vertex[i]].x() , sample_[this->i_vertex[i]].y() ,sample_[this->i_vertex[i]].z() ,1.); Vec4 point_to_show = adjust_matrix * tmpv; glVertex3f( point_to_show(0)+ bias(0), point_to_show(1)+ bias(1), point_to_show(2)+ bias(2) ); } glEnd(); break; } case RenderMode::SmoothMode:{ break;} case RenderMode::TextureMode:{ break;} case RenderMode::SelectMode:{ break;} default:{} } }