| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -70,16 +70,11 @@ struct equal_to<face_with_orient_t> { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} // namespace std
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// point (x,y,z): dictionary order
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					inline bool point_xyz_less(const Eigen::Vector3d &p, const Eigen::Vector3d &q) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    return std::lexicographical_compare(p.begin(), p.end(), q.begin(), q.end()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// ============================================================================================
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void topo_ray_shooting(const scene_bg_mesh_info_t                   &scene_bg_mesh_info, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                       const stl_vector_mp<std::array<uint32_t, 4>> &tetrahedrons, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                       const flat_hash_map_mp<uint32_t, uint32_t>   &vertex_lexigraphical_adjacency, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                       const stl_vector_mp<arrangement_t>           &tetrahedron_arrangements, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                       const stl_vector_mp<iso_vertex_t>            &iso_verts, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                       const stl_vector_mp<polygon_face_t>          &iso_faces, | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -91,10 +86,6 @@ void topo_ray_shooting(const scene_bg_mesh_info_t                   &scene_bg_me | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                       const stl_vector_mp<uint32_t>                &component_of_patch, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                       stl_vector_mp<std::pair<uint32_t, uint32_t>> &shell_links) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // map: tet vert index --> index of next vert (with smaller (x,y,z))
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    flat_hash_map_mp<uint32_t, uint32_t> next_vert{}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    build_next_vert(scene_bg_mesh_info, tetrahedrons, next_vert); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // find extremal edge for each component
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // extremal edge of component i is stored at position [2*i], [2*i+1]
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    stl_vector_mp<uint32_t>                                          extremal_edge_of_component{}; | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -110,7 +101,7 @@ void topo_ray_shooting(const scene_bg_mesh_info_t                   &scene_bg_me | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        patches, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        components, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        component_of_patch, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        next_vert, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        vertex_lexigraphical_adjacency, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        extremal_edge_of_component, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        iso_vert_on_v_v_next, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        iso_face_id_of_tet_face, | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -178,18 +169,16 @@ void topo_ray_shooting(const scene_bg_mesh_info_t                   &scene_bg_me | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                                                   : shell_of_half_patch[2 * patch_of_face[iso_fId] + 1]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // follow the ray till another iso-vertex or the sink
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                auto       v_curr      = extreme_v2; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // while (next_vert[v_curr] != invalid_index && iso_vert_on_v_v_next[v_curr] == invalid_index) {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                while (next_vert.find(v_curr) != next_vert.end() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                while (vertex_lexigraphical_adjacency.find(v_curr) != vertex_lexigraphical_adjacency.end() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                       && iso_vert_on_v_v_next.find(v_curr) == iso_vert_on_v_v_next.end()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    v_curr = next_vert[v_curr]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    v_curr = vertex_lexigraphical_adjacency.at(v_curr); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // if (iso_vert_on_v_v_next[v_curr] != invalid_index) {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (iso_vert_on_v_v_next.find(v_curr) != iso_vert_on_v_v_next.end()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    // reached iso-vert at end of the ray
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    const auto  iso_vId_end         = iso_vert_on_v_v_next[v_curr]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    const auto  end_tetId           = iso_verts[iso_vId_end].header.volume_index; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    const auto &end_tet_arrangement = tetrahedron_arrangements[end_tetId]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    auto        v_next              = next_vert[v_curr]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    auto        v_next              = vertex_lexigraphical_adjacency.at(v_curr); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    // find local vertex indices in the end tetrahedron
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    for (uint32_t j = 0; j < 4; ++j) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        if (tetrahedrons[end_tetId][j] == v_curr) { | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -221,24 +210,6 @@ void topo_ray_shooting(const scene_bg_mesh_info_t                   &scene_bg_me | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void build_next_vert(const scene_bg_mesh_info_t                   &scene_bg_mesh_info, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                     const stl_vector_mp<std::array<uint32_t, 4>> &tetrahedrons, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                     flat_hash_map_mp<uint32_t, uint32_t>         &next_vert) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    next_vert.reserve(tetrahedrons.size() * 2); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for (const auto &tet : tetrahedrons) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        // find the smallest vertex of tet
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        auto min_iter = std::min_element(tet.begin(), tet.end(), [&](const uint32_t &lhs, const uint32_t &rhs) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            return point_xyz_less(get_vert_pos(lhs, scene_bg_mesh_info), get_vert_pos(rhs, scene_bg_mesh_info)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        //
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        for (auto iter = tet.begin(); iter != tet.end(); ++iter) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (iter != min_iter) next_vert[*iter] = *min_iter; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void find_extremal_edges(const scene_bg_mesh_info_t                                       &scene_bg_mesh_info, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                         const stl_vector_mp<iso_vertex_t>                                &iso_verts, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                         const stl_vector_mp<polygon_face_t>                              &iso_faces, | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -277,12 +248,8 @@ void find_extremal_edges(const scene_bg_mesh_info_t | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                u2 = v2; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                if (v2 == u2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                    if (point_xyz_less(get_vert_pos(v1, scene_bg_mesh_info), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                                       get_vert_pos(u1, scene_bg_mesh_info))) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                        u1 = v1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                } else if (point_xyz_less(get_vert_pos(v2, scene_bg_mesh_info), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                                          get_vert_pos(u2, scene_bg_mesh_info))) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                    if (v1 < u1) { u1 = v1; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                } else if (v2 < u2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                    u1 = v1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                    u2 = v2; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                } | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -300,12 +267,8 @@ void find_extremal_edges(const scene_bg_mesh_info_t | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                u2 = v1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                if (v1 == u2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                    if (point_xyz_less(get_vert_pos(v2, scene_bg_mesh_info), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                                       get_vert_pos(u1, scene_bg_mesh_info))) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                        u1 = v2; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                } else if (point_xyz_less(get_vert_pos(v1, scene_bg_mesh_info), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                                          get_vert_pos(u2, scene_bg_mesh_info))) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                    if (v2 < u1) { u1 = v2; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                } else if (v1 < u2) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                    u1 = v2; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                    u2 = v1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                } | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  |