Skip to content

Commit

Permalink
Merge pull request #933 from Geode-solutions/brep_helper_ray_tracing
Browse files Browse the repository at this point in the history
feat(BRepHelper): add ray tracing based test for point in block.
  • Loading branch information
panquez authored Jun 5, 2024
2 parents 8b75e37 + e692519 commit ed36887
Show file tree
Hide file tree
Showing 8 changed files with 205 additions and 0 deletions.
1 change: 1 addition & 0 deletions bindings/python/src/model/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ add_geode_python_binding(
"helpers/model_component_filter.cpp"
"helpers/model_concatener.cpp"
"helpers/model_crs.cpp"
"helpers/ray_tracing.cpp"
"mixin/builder/blocks_builder.cpp"
"mixin/builder/block_collections_builder.cpp"
"mixin/builder/corners_builder.cpp"
Expand Down
41 changes: 41 additions & 0 deletions bindings/python/src/model/helpers/ray_tracing.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2019 - 2024 Geode-solutions
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/

#include "../../common.h"

#include <geode/model/mixin/core/block.h>
#include <geode/model/representation/core/brep.h>

#include <geode/model/helpers/ray_tracing.h>

namespace geode
{
void define_model_ray_tracing( pybind11::module& module )
{
module
.def( "find_intersections_with_boundaries",
&find_intersections_with_boundaries )
.def( "is_point_inside_block", &is_point_inside_block )
.def( "block_containing_point", &block_containing_point );
}
} // namespace geode
1 change: 1 addition & 0 deletions bindings/python/src/model/model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ namespace geode
void define_model_component_filter( pybind11::module& );
void define_model_concatener( pybind11::module& );
void define_model_coordinate_reference_system( pybind11::module& );
void define_model_ray_tracing( pybind11::module& );
} // namespace geode

PYBIND11_MODULE( opengeode_py_model, module )
Expand Down
6 changes: 6 additions & 0 deletions include/geode/model/helpers/ray_tracing.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,10 @@ namespace geode
const BRep& brep,
const Block3D& block );

bool opengeode_model_api is_point_inside_block(
const BRep& brep, const Block3D& block, const Point3D& point );

absl::optional< uuid > opengeode_model_api block_containing_point(
const BRep& brep, const Point3D& point );

} // namespace geode
88 changes: 88 additions & 0 deletions src/geode/model/helpers/ray_tracing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,55 @@
#include <geode/model/mixin/core/surface.h>
#include <geode/model/representation/core/brep.h>

namespace
{
geode::BoundarySurfaceIntersections find_intersections_with_boundaries(
const geode::Ray3D& ray,
const geode::BRep& brep,
const geode::Block3D& block )
{
geode::BoundarySurfaceIntersections result;
for( const auto& surface : brep.boundaries( block ) )
{
const auto aabb = geode::create_aabb_tree( surface.mesh() );
geode::RayTracing3D ray_tracing{ surface.mesh(), ray };
aabb.compute_ray_element_bbox_intersections( ray, ray_tracing );
result[surface.id()] = ray_tracing.all_intersections();
}
return result;
}

absl::optional< geode::index_t > count_real_intersections_with_boudaries(
const geode::Ray3D& ray,
const geode::BRep& brep,
const geode::Block3D& block )
{
geode::index_t nb_intersections{ 0 };
const auto tracing =
find_intersections_with_boundaries( ray, brep, block );
for( const auto& intersections : tracing )
{
for( const auto& intersection : intersections.second )
{
if( intersection.position != geode::Position::inside )
{
return absl::nullopt;
}
if( std::fabs( intersection.distance )
<= geode::global_epsilon )
{
continue;
}
else
{
nb_intersections += 1;
}
}
}
return nb_intersections;
}
} // namespace

namespace geode
{
BoundarySurfaceIntersections find_intersections_with_boundaries(
Expand All @@ -51,4 +100,43 @@ namespace geode
return result;
}

bool is_point_inside_block(
const BRep& brep, const Block3D& block, const Point3D& point )
{
std::array< Vector3D, 12 > directions = { { { { 0., 0., 1. } },
{ { 0.1, 0., 1. } }, { { 0.3, 0., 1. } }, { { 0.5, 0., 1. } },
{ { 0., 1., 0. } }, { { 0.1, 1., 0. } }, { { 0.3, 1., 0. } },
{ { 0.5, 1., 0. } }, { { 1., 0., 0. } }, { { 1., 0., 0.1 } },
{ { 1., 0., 0.3 } }, { { 1., 0., 0.5 } } } };

for( const auto& direction : directions )
{
const Ray3D ray{ direction, point };
auto nb_intersections =
count_real_intersections_with_boudaries( ray, brep, block );

if( nb_intersections.has_value() )
{
return ( nb_intersections.value() % 2 == 1 );
}
}
throw OpenGeodeException{
"Cannot determine the point is inside the block or not "
"(ambigous intersection with rays)."
};
}

absl::optional< uuid > block_containing_point(
const BRep& brep, const Point3D& point )
{
for( const auto& block : brep.blocks() )
{
if( is_point_inside_block( brep, block, point ) )
{
return block.id();
}
}
return absl::nullopt;
}

} // namespace geode
Binary file added tests/data/box_brep.og_brep
Binary file not shown.
7 changes: 7 additions & 0 deletions tests/model/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ add_geode_test(
${PROJECT_NAME}::geometry
${PROJECT_NAME}::model
)
add_geode_test(
SOURCE "test-ray-tracing-helpers.cpp"
DEPENDENCIES
${PROJECT_NAME}::basic
${PROJECT_NAME}::geometry
${PROJECT_NAME}::model
)
add_geode_test(
SOURCE "test-relationships.cpp"
DEPENDENCIES
Expand Down
61 changes: 61 additions & 0 deletions tests/model/test-ray-tracing-helpers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2019 - 2024 Geode-solutions
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/

#include <geode/basic/assert.h>
#include <geode/basic/logger.h>

#include <geode/model/helpers/ray_tracing.h>

#include <geode/geometry/bounding_box.h>
#include <geode/model/representation/core/brep.h>
#include <geode/model/representation/io/brep_input.h>

#include <geode/tests/common.h>

void test()
{
geode::OpenGeodeModelLibrary::initialize();

// load a 40x40x40 aligned cubic box brep
auto brep = geode::load_brep(
absl::StrCat( geode::data_path, "box_brep.og_brep" ) );
geode::Point3D center( { 20., 20., 20. } );

// get the block
const auto block_id = geode::block_containing_point( brep, center );
OPENGEODE_EXCEPTION( block_id.has_value(),
"[Test] fail to recover block_containing_point." );

// test point iside the block
geode::Point3D inside( { 0.00001, 0.00001, 0.00001 } );
geode::Point3D outside( { -0.00001, 0.00001, 0.00001 } );
OPENGEODE_EXCEPTION( geode::is_point_inside_block(
brep, brep.block( block_id.value() ), inside ),
"[Test] the point named inside should be inside the block." );

OPENGEODE_EXCEPTION( !geode::is_point_inside_block(
brep, brep.block( block_id.value() ), outside ),
"[Test] the point named outside should be outside the block." );
}

OPENGEODE_TEST( "ray-tracing-helpers" )

0 comments on commit ed36887

Please sign in to comment.