📄 snc_constructor.h
字号:
Point_3 transform_point_on_infibox(const Point_3& p, const Aff_transformation_3& aff) { Point_3 res(p.transform(aff)); res = normalized(p); RT hw(CGAL_NTS abs(res.hx())); if(CGAL_NTS abs(res.hy()) > hw) hw = CGAL_NTS abs(res.hy()); if(CGAL_NTS abs(res.hz()) > hw) hw = CGAL_NTS abs(res.hz()); CGAL_assertion(hw.degree() == 1); CGAL_assertion(hw[0] == 0); return Point_3(res.hx(), res.hy(), res.hz(), hw(1)); } bool erase_redundant_vertices() { std::list<Vertex_handle> redundant_points; Vertex_iterator v; CGAL_forall_vertices(v, *this->sncp()) if(!is_standard(v)) redundant_points.push_back(v); redundant_points.sort(Frame_point_lt<Infi_box,Vertex_handle>()); typename std::list<Vertex_handle>::iterator vi, vinext; for(vi = redundant_points.begin(); vi != redundant_points.end(); ++vi) { vinext = vi; ++vinext; if(vinext == redundant_points.end()) break; if((*vi)->point() == (*vinext)->point()) { CGAL_assertion(!Infi_box::is_complex_facet_infibox_intersection(**vi)); this->sncp()->delete_vertex(*vi); } } NT eval(Infi_box::compute_evaluation_constant_for_halfedge_pairup(*this->sncp())); bool res; do { res = false; typedef Halfedge_key< Point_3, Halfedge_handle> Halfedge_key; typedef Halfedge_key_lt< Point_3, Halfedge_handle, SNC_decorator> Halfedge_key_lt; typedef std::list<Halfedge_key> Halfedge_list; typedef typename Standard_kernel::Kernel_tag Kernel_tag; typedef CGAL::Pluecker_line_3<Kernel_tag,Standard_kernel> Pluecker_line_3; typedef CGAL::Pluecker_line_lt Pluecker_line_lt; typedef std::map< Pluecker_line_3, Halfedge_list, Pluecker_line_lt> Pluecker_line_map; Unique_hash_map<Vertex_handle, bool> erase_vertex(false); std::list<Point_3> recreate; SNC_decorator D(*this); Pluecker_line_map M2; Pluecker_line_map M3; Pluecker_line_map M4; Halfedge_iterator e; CGAL_forall_halfedges(e,*this->sncp()) { Point_3 p = e->source()->point(); Point_3 q = p + e->vector(); Standard_point_3 sp = Infi_box::standard_point(p,eval); Standard_point_3 sq = Infi_box::standard_point(q,eval); Pluecker_line_3 l( sp, sq); int inverted; l = categorize( l, inverted); CGAL_NEF_TRACEN(" segment("<<p<<", "<<q<<")"<< " direction("<<e->vector()<<")"<< " line("<<l<<")"<<" inverted="<<inverted); if(Infi_box::is_edge_on_infibox(e)) { if(Infi_box::is_type4(e)) M4[l].push_back(Halfedge_key(p,inverted,e)); else if(Infi_box::is_type3(e)) M3[l].push_back(Halfedge_key(p,inverted,e)); else M2[l].push_back(Halfedge_key(p,inverted,e)); } } typename Pluecker_line_map::iterator it; CGAL_forall_iterators(it,M4) { CGAL_NEF_TRACEN("search opposite "<<it->first); it->second.sort(Halfedge_key_lt()); typename Halfedge_list::iterator itl; CGAL_forall_iterators(itl,it->second) { Halfedge_handle e1 = itl->e; CGAL_NEF_TRACE(" " << e1->source()->point() << " -> "); ++itl; if(itl == it->second.end()) { erase_vertex[e1->source()] = true; break; } Halfedge_handle e2 = itl->e; CGAL_NEF_TRACE(e2->source()->point()); if(normalized(e1->vector())!=normalized(-e2->vector())) { erase_vertex[e1->source()] = true; --itl; CGAL_NEF_TRACE(" failed "); } CGAL_NEF_TRACEN(""); } CGAL_NEF_TRACEN(""); CGAL_NEF_TRACEN(""); } CGAL_forall_iterators(it,M3) { CGAL_NEF_TRACEN("search opposite "<<it->first); it->second.sort(Halfedge_key_lt()); typename Halfedge_list::iterator itl; CGAL_forall_iterators(itl,it->second) { Halfedge_handle e1 = itl->e; CGAL_NEF_TRACE(" " << e1->source()->point() << " -> "); ++itl; if(itl == it->second.end()) { erase_vertex[e1->source()] = true; break; } Halfedge_handle e2 = itl->e; CGAL_NEF_TRACE(e2->source()->point()); if(normalized(e1->vector())!=normalized(-e2->vector())) { erase_vertex[e1->source()] = true; --itl; CGAL_NEF_TRACE(" failed "); } CGAL_NEF_TRACEN(""); } CGAL_NEF_TRACEN(""); CGAL_NEF_TRACEN(""); } CGAL_forall_iterators(it,M2) { CGAL_NEF_TRACEN("search opposite "<<it->first); it->second.sort(Halfedge_key_lt()); typename Halfedge_list::iterator itl; CGAL_forall_iterators(itl,it->second) { Halfedge_handle e1 = itl->e; CGAL_NEF_TRACE(" " << e1->source()->point() << " -> "); ++itl; if(itl == it->second.end()) { erase_vertex[e1->source()] = true; break; } Halfedge_handle e2 = itl->e; CGAL_NEF_TRACE(e2->source()->point()); if(normalized(e1->vector())!=normalized(-e2->vector())) { erase_vertex[e1->source()] = true; --itl; CGAL_NEF_TRACE(" failed "); } CGAL_NEF_TRACEN(""); } CGAL_NEF_TRACEN(""); CGAL_NEF_TRACEN(""); } std::vector<Vertex_iterator> vertices_to_delete ; Vertex_iterator v; CGAL_forall_vertices(v, *this->sncp()) { if(erase_vertex[v]) { CGAL_NEF_TRACEN("erase " << v->point()); if(Infi_box::is_infibox_corner(v->point())) recreate.push_back(v->point()); vertices_to_delete.push_back(v); res = true; } } for( typename std::vector<Vertex_iterator>::iterator vit = vertices_to_delete.begin() ; vit != vertices_to_delete.end() ; ++ vit ) this->sncp()->delete_vertex(*vit); typename std::list<Point_3>::const_iterator pi; for(pi = recreate.begin(); pi != recreate.end(); ++pi) create_from_point_on_infibox_vertex(*pi); } while(res); return res; } std::list<Point_3> find_points_of_box_with_plane(const Plane_3& h) { Vector_3 orth = h.orthogonal_vector(); NT orth_coords[3]; orth_coords[0] = orth.hx()[0]; orth_coords[1] = orth.hy()[0]; orth_coords[2] = orth.hz()[0]; int add_corners = 0; while(orth_coords[add_corners] == 0){ CGAL_assertion(add_corners < 2); ++add_corners; } std::list<Point_3> points; for(int dir=0; dir<3;++dir) { NT cnst[3]; for(int i=0; i<3;++i) cnst[i] = (i==dir? -h.d()[0] : 0); NT cross[4][4]; cross[0][dir] = -orth_coords[(dir+1)%3]-orth_coords[(dir+2)%3]; cross[1][dir] = orth_coords[(dir+1)%3]-orth_coords[(dir+2)%3]; cross[2][dir] = orth_coords[(dir+1)%3]+orth_coords[(dir+2)%3]; cross[3][dir] = -orth_coords[(dir+1)%3]+orth_coords[(dir+2)%3]; for(int i=0;i<4;++i) cross[i][3] = orth_coords[dir]; cross[0][(dir+1)%3] = cross[3][(dir+1)%3] = orth_coords[dir]; cross[1][(dir+1)%3] = cross[2][(dir+1)%3] = -orth_coords[dir]; cross[0][(dir+2)%3] = cross[1][(dir+2)%3] = orth_coords[dir]; cross[2][(dir+2)%3] = cross[3][(dir+2)%3] = -orth_coords[dir]; for(int i=0; i<4; ++i) if(CGAL_NTS abs(RT(cnst[dir],cross[i][dir])) < CGAL_NTS abs(RT(0,orth_coords[dir])) || (CGAL_NTS abs(RT(cnst[dir],cross[i][dir])) == CGAL_NTS abs(RT(0,orth_coords[dir])) && dir == add_corners)) points.push_back(Point_3(RT(cnst[0], cross[i][0]), RT(cnst[1], cross[i][1]), RT(cnst[2], cross[i][2]), RT(cross[i][3]))); } for(int i=0;i<3;++i) orth_coords[i] = CGAL_NTS abs(orth_coords[i]); int max = 0; if(orth_coords[1] > orth_coords[0]) max = 1; if(orth_coords[2] > orth_coords[max]) max = 2; int min = 0; if(orth_coords[1] < orth_coords[0]) min = 1; if(orth_coords[2] < orth_coords[min]) min = 2; points.sort(circle_lt<Kernel>(max)); typename std::list<Point_3>::const_iterator p; for(p=points.begin();p!=points.end();++p) CGAL_NEF_TRACEN(*p); return points; } std::list<Point_3> find_facet_infibox_intersections(Halffacet_handle fi, std::list<Point_3> points) { // points is a list of the required points, but with the inverse transformation applied std::list<Point_3> res; Halffacet_cycle_iterator fc = fi->facet_cycles_begin(); CGAL_assertion(fc.is_shalfedge()); SHalfedge_handle sh(fc); SHalfedge_around_facet_circulator fcc(sh), fend(fcc); CGAL_For_all(fcc,fend) { Point_3 src(fcc->source()->source()->point()); Point_3 trg(fcc->source()->twin()->source()->point()); typename std::list<Point_3>::iterator pi,pprev; pi = points.begin(); while(pi != points.end()) { *pi = normalized(*pi); // std::cerr << src << "->" << trg << " has on " << *pi << src.x() << " : " << std::endl; // std::cerr << (src.x()-pi->x() <= 0) << "|" << (src.y()-pi->y() <= 0) << "|" << (src.z()-pi->z() <= 0) << std::endl; // std::cerr << (pi->x()-trg.x() <= 0) << "|" << (pi->y()-trg.y() <= 0) << "|" << (pi->z()-trg.z() <= 0) << std::endl; if((src.x()-pi->x() <= 0 && pi->x()-trg.x() <= 0 || src.x()-pi->x() >= 0 && pi->x()-trg.x() >= 0) && (src.y()-pi->y() <= 0 && pi->y()-trg.y() <= 0 || src.y()-pi->y() >= 0 && pi->y()-trg.y() >= 0) && (src.z()-pi->z() <= 0 && pi->z()-trg.z() <= 0 || src.z()-pi->z() >= 0 && pi->z()-trg.z() >= 0)) { // std::cerr << "true" << std::endl; pprev = pi; ++pi; res.push_back(*pprev); points.erase(pprev); } else { // std::cerr << "false" << std::endl; ++pi; } } } return res; } std::list<Vertex_handle> create_vertices_on_infibox(const Plane_3& h, const std::list<Point_3> points, const Mark& bnd, const Mark& inside, const Mark& outside) { std::list<Vertex_handle> res; NT orth_coords[3]; int min,max; Infi_box::compute_min_max(h,orth_coords,min,max); typename std::list<Point_3>::const_iterator p,prev,next; for(p=points.begin();p!=points.end();++p){ if(p==points.begin()) prev = --points.end(); else { prev = p; prev--;} if(p==--points.end()) next=points.begin(); else {next = p; ++next;} CGAL_NEF_TRACEN("points " << *prev << " " << *p << " " << *next); Vector_3 v= *prev - *p; Sphere_point sp1(v); sp1 = normalized(sp1); CGAL_assertion(Infi_box::degree(sp1.hx()) == 0); CGAL_assertion(Infi_box::degree(sp1.hy()) == 0); CGAL_assertion(Infi_box::degree(sp1.hz()) == 0); CGAL_assertion(Infi_box::degree(sp1.hw()) == 0); v= *next - *p; Sphere_point sp2(v); sp2 = normalized(sp2); CGAL_assertion(Infi_box::degree(sp2.hx()) == 0); CGAL_assertion(Infi_box::degree(sp2.hy()) == 0); CGAL_assertion(Infi_box::degree(sp2.hz()) == 0); CGAL_assertion(Infi_box::degree(sp2.hw()) == 0); CGAL_NEF_TRACEN("sps " << sp1 << " " << sp2); CGAL_NEF_TRACEN(orth_coords[min] << "|" << orth_coords[(min+1)%3] << "|" << orth_coords[(min+2)%3]); if(orth_coords[min]==0 && orth_coords[(min+1)%3] == orth_coords[(min+2)%3] && h.d() == 0) res.push_back(create_degenerate_corner_frame_point(*p,sp1,sp2,min,max,h,bnd,inside,outside)); else if(CGAL_NTS abs(p->hx()) == CGAL_NTS abs(p->hy()) && CGAL_NTS abs(p->hz()) == CGAL_NTS abs(p->hy())) res.push_back(create_corner_frame_point(*p,sp1,sp2,max,h,bnd,inside,outside)); else res.push_back(create_frame_point(*p,sp1,sp2,h,bnd,inside,outside)); } return res; } void create_vertices_of_box_with_plane(const Plane_3& h, bool b) { // CGAL_NEF_SETDTHREAD(19*43*11); std::list<Point_3> points(find_points_of_box_with_plane(h)); create_vertices_on_infibox(h,points,b,true,false); RT sum= h.a()+h.b()+h.c(); if(h.d()!=0 || sum!= 0) { CGAL_NEF_TRACEN(sum); create_extended_box_corner( 1, 1, 1, (sum<0 || (sum == 0 && h.d()<0))); } sum=-h.a()+h.b()+h.c(); if(h.d()!=0 || sum!= 0) { CGAL_NEF_TRACEN(sum); create_extended_box_corner(-1, 1, 1, (sum<0 || (sum == 0 && h.d()<0))); } sum= h.a()-h.b()+h.c(); if(h.d()!=0 || sum!= 0) { CGAL_NEF_TRACEN(sum); create_extended_box_corner( 1,-1, 1, (sum<0 || (sum == 0 && h.d()<0))); } sum=-h.a()-h.b()+h.c(); if(h.d()!=0 || sum!= 0) { CGAL_NEF_TRACEN(sum); create_extended_box_corner(-1,-1, 1, (sum<0 || (sum == 0 && h.d()<0))); } sum= h.a()+h.b()-h.c(); if(h.d()!=0 || sum!= 0) { CGAL_NEF_TRACEN(sum); create_extended_box_corner( 1, 1,-1, (sum<0 || (sum == 0 && h.d()<0)));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -