bool on_triangle(primitive::triangle_t const& tri, geom::ray_t const& ray, point_t& point) { bool b = on_plane(tri, ray, point); if (b) { point_t bcent = donkey::algo::barycentric(tri, point); if (bcent.x < 0 || bcent.y < 0 || bcent.z < 0) return false; } return true; }
bool on_cube( primitive::cube_t const& cube, geom::ray_t const& ray, point_t& point, primitive::cube_t::face_id& faceid ) { bool b = false; for (int i = 0; i < primitive::cube_t::kNumFaceIds; ++i) { primitive::cube_t::face_id fid = primitive::cube_t::face_id(i); point_t p; if (on_plane(cube.planes[i], ray, p) && cube.inFace(fid, p)) { point = p; faceid = fid; b = true; break; } } return b; }
bool on_object(scene_object_ptr object, geom::ray_t const& ray, points_v& points) { if (!(object)) return false; bool b = false; switch (object->type) { case object::kPlane: { point_t pt; if (true == (b = on_plane( *(std::dynamic_pointer_cast<primitive::plane_t>(object)), ray, pt)) ) { points.push_back(pt); } break; } case object::kSphere: { point_t p1, p2; if (true == (b = on_sphere( *(std::dynamic_pointer_cast<primitive::sphere_t>(object)), ray, p1, p2)) ) { points.push_back(p1); points.push_back(p2); } break; } default:; } return b; }
void operator()(MeshType const & input_mesh, MeshType const & output_mesh, viennagrid_plc plc_output_mesh, PointType const & N) { typedef viennagrid::result_of::const_element_range<MeshType>::type ConstElementRangeType; typedef viennagrid::result_of::iterator<ConstElementRangeType>::type ConstElementRangeIterator; viennagrid::result_of::element_copy_map<>::type copy_map(output_mesh, false); ConstElementRangeType triangles( input_mesh, 2 ); for (ConstElementRangeIterator tit = triangles.begin(); tit != triangles.end(); ++tit) { ElementType v[3]; PointType p[3]; double dp[3]; for (int pi = 0; pi != 3; ++pi) { v[pi] = viennagrid::vertices(*tit)[pi]; p[pi] = viennagrid::get_point( v[pi] ); dp[pi] = viennagrid::inner_prod( p[pi], N ); } if ( !inside(dp[0]) && !inside(dp[1]) && !inside(dp[2]) ) { // all points outside -> ignore continue; } int on_plane_count = 0; for (int pi = 0; pi != 3; ++pi) if ( on_plane(dp[pi]) ) ++on_plane_count; if (on_plane_count == 3) continue; if (on_plane_count == 2) { // std::cout << "!!!!!!!!!!!!!!!!!!!!!!!! on_plane_count = 2" << std::endl; int not_on_plane_index = !on_plane(dp[0]) ? 0 : !on_plane(dp[1]) ? 1 : 2; if ( inside(dp[not_on_plane_index]) ) { copy_map(*tit); int oi0 = (not_on_plane_index == 0) ? 1 : 0; int oi1 = (not_on_plane_index == 2) ? 1 : 2; add_line(copy_map(v[oi0]), copy_map(v[oi1])); } // else // std::cout << " outside -> skipping" << std::endl; continue; } if (on_plane_count == 1) { // std::cout << "!!!!!!!!!!!!!!!!!!!!!!!! on_plane_count = 1" << std::endl; int on_plane_index = on_plane(dp[0]) ? 0 : on_plane(dp[1]) ? 1 : 2; int oi0 = (on_plane_index == 0) ? 1 : 0; int oi1 = (on_plane_index == 2) ? 1 : 2; if ( !inside(dp[oi0]) && !inside(dp[oi1]) ) continue; if ( inside(dp[oi0]) && inside(dp[oi1]) ) { copy_map(*tit); continue; } // oi0 is inside if ( !inside(dp[oi0]) ) std::swap(oi0, oi1); ElementType v_ = get_vertex(output_mesh, N, v[oi0], v[oi1]); viennagrid::make_triangle( output_mesh, copy_map(v[on_plane_index]), copy_map(v[oi0]), v_); add_line(v_, copy_map(v[on_plane_index])); continue; } if ( inside(dp[0]) && inside(dp[1]) && inside(dp[2]) ) { // all points inside -> copy copy_map(*tit); continue; } int pos_count = 0; for (int pi = 0; pi != 3; ++pi) if ( inside(dp[pi]) ) ++pos_count; int pi = (dp[0]*dp[1] > 0) ? 2 : (dp[1]*dp[2] > 0) ? 0 : 1; int oi0 = (pi == 0) ? 1 : 0; int oi1 = (pi == 2) ? 1 : 2; ElementType v1_ = get_vertex(output_mesh, N, v[pi], v[oi0]); ElementType v2_ = get_vertex(output_mesh, N, v[pi], v[oi1]); add_line(v1_, v2_); if (pos_count == 1) { viennagrid::make_triangle( output_mesh, copy_map(v[pi]), v1_, v2_); } else { viennagrid::make_triangle( output_mesh, copy_map(v[oi0]), copy_map(v[oi1]), v1_); viennagrid::make_triangle( output_mesh, copy_map(v[oi1]), v1_, v2_); } } std::vector<viennagrid_int> line_ids; std::map<ElementType, viennagrid_int> vertices_on_hyperplane; for (LinesOnHyperplaneType::iterator it = lines_on_hyperplane.begin(); it != lines_on_hyperplane.end(); ++it) { vertices_on_hyperplane.insert( std::make_pair((*it).first, -1) ); vertices_on_hyperplane.insert( std::make_pair((*it).second, -1) ); } for (std::map<ElementType, viennagrid_int>::iterator vit = vertices_on_hyperplane.begin(); vit != vertices_on_hyperplane.end(); ++vit) { PointType p = viennagrid::get_point( (*vit).first ); viennagrid_plc_vertex_create(plc_output_mesh, &p[0], &vit->second); } for (LinesOnHyperplaneType::iterator it = lines_on_hyperplane.begin(); it != lines_on_hyperplane.end(); ++it) { viennagrid_int line_id; viennagrid_plc_line_create(plc_output_mesh, vertices_on_hyperplane[(*it).first], vertices_on_hyperplane[(*it).second], &line_id); line_ids.push_back(line_id); } viennagrid_plc_facet_create(plc_output_mesh, line_ids.size(), &line_ids[0], NULL); }