Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -168,13 +168,6 @@ target_link_libraries(ipc_toolkit PRIVATE tight_inclusion::tight_inclusion)
include(scalable_ccd)
target_link_libraries(ipc_toolkit PRIVATE scalable_ccd::scalable_ccd)

# CCD
if(IPC_TOOLKIT_WITH_INEXACT_CCD)
# Etienne Vouga's CTCD Library for the floating point root finding algorithm
include(evouga_ccd)
target_link_libraries(ipc_toolkit PRIVATE evouga::ccd)
endif()

# SimpleBVH
include(simple_bvh)
target_link_libraries(ipc_toolkit PRIVATE simple_bvh::simple_bvh)
Expand All @@ -183,6 +176,13 @@ target_link_libraries(ipc_toolkit PRIVATE simple_bvh::simple_bvh)
include(spdlog)
target_link_libraries(ipc_toolkit PUBLIC spdlog::spdlog)

# CCD
if(IPC_TOOLKIT_WITH_INEXACT_CCD)
# Etienne Vouga's CTCD Library for the floating point root finding algorithm
include(evouga_ccd)
target_link_libraries(ipc_toolkit PRIVATE evouga::ccd)
endif()

# rational-cpp (requires GMP)
if(IPC_TOOLKIT_WITH_RATIONAL_INTERSECTION)
include(rational_cpp)
Expand Down
2 changes: 1 addition & 1 deletion cmake/recipes/CPM.cmake
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
set(CPM_DOWNLOAD_VERSION 0.40.2)
set(CPM_DOWNLOAD_VERSION 0.42.0)

if(CPM_SOURCE_CACHE)
set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
Expand Down
9 changes: 5 additions & 4 deletions cmake/recipes/ccd_query_io.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ message(STATUS "Third-party: creating target 'ccd_io::ccd_io'")

include(ipc_toolkit_tests_data)

set(CCD_IO_DOWNLOAD_SAMPLE_QUERIES ON CACHE BOOL "Download sample CCD queries" FORCE)
set(CCD_IO_SAMPLE_QUERIES_DIR "${IPC_TOOLKIT_TESTS_DATA_DIR}/ccd-queries/" CACHE PATH "Where should we download sample queries?")

include(CPM)
CPMAddPackage("gh:Continuous-Collision-Detection/CCD-Query-IO#36f6093af81a65acc27d9f05ad32d6b5729e8d15")
CPMAddPackage(
URI "gh:Continuous-Collision-Detection/CCD-Query-IO#36f6093af81a65acc27d9f05ad32d6b5729e8d15"
OPTIONS "CCD_IO_DOWNLOAD_SAMPLE_QUERIES ON"
"CCD_IO_SAMPLE_QUERIES_DIR ${IPC_TOOLKIT_TESTS_DATA_DIR}/ccd-queries/"
)
2 changes: 1 addition & 1 deletion cmake/recipes/finite_diff.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ endif()
message(STATUS "Third-party: creating target 'finitediff::finitediff'")

include(CPM)
CPMAddPackage("gh:zfergus/[email protected].1")
CPMAddPackage("gh:zfergus/[email protected].3")

# Folder name for IDE
set_target_properties(finitediff_finitediff PROPERTIES FOLDER "ThirdParty")
7 changes: 4 additions & 3 deletions cmake/recipes/libigl.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ endif()

message(STATUS "Third-party: creating target 'igl::core'")

set(LIBIGL_PREDICATES ON CACHE BOOL "Use exact predicates" FORCE)

include(eigen)

include(CPM)
CPMAddPackage("gh:libigl/libigl#89267b4a80b1904de3f6f2812a2053e5e9332b7e")
CPMAddPackage(
URI "gh:libigl/libigl#89267b4a80b1904de3f6f2812a2053e5e9332b7e"
OPTIONS "LIBIGL_PREDICATES ON"
)

# Folder name for IDE
foreach(target_name IN ITEMS core predicates)
Expand Down
7 changes: 4 additions & 3 deletions cmake/recipes/scalable_ccd.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ endif()

message(STATUS "Third-party: creating target 'scalable_ccd::scalable_ccd'")

set(SCALABLE_CCD_WITH_CUDA ${IPC_TOOLKIT_WITH_CUDA} CACHE BOOL "Enable CUDA CCD" FORCE)

include(CPM)
CPMAddPackage("gh:continuous-collision-detection/scalable-ccd#4fa806f533b19132e696a2dddeab16537025b5f9")
CPMAddPackage(
URI "gh:continuous-collision-detection/scalable-ccd#4fa806f533b19132e696a2dddeab16537025b5f9"
OPTIONS "SCALABLE_CCD_WITH_CUDA ${IPC_TOOLKIT_WITH_CUDA}"
)

# Folder name for IDE
set_target_properties(scalable_ccd PROPERTIES FOLDER "ThirdParty")
30 changes: 24 additions & 6 deletions src/ipc/broad_phase/broad_phase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,9 @@ void BroadPhase::build(
Eigen::ConstRef<Eigen::MatrixXi> faces,
const double inflation_radius)
{
assert(edges.size() == 0 || edges.cols() == 2);
assert(faces.size() == 0 || faces.cols() == 3);
clear();
build_vertex_boxes(vertices, vertex_boxes, inflation_radius);
build_edge_boxes(vertex_boxes, edges, edge_boxes);
build_face_boxes(vertex_boxes, faces, face_boxes);
build(edges, faces);
}

void BroadPhase::build(
Expand All @@ -26,11 +23,32 @@ void BroadPhase::build(
Eigen::ConstRef<Eigen::MatrixXi> faces,
const double inflation_radius)
{
assert(edges.size() == 0 || edges.cols() == 2);
assert(faces.size() == 0 || faces.cols() == 3);
clear();
build_vertex_boxes(
vertices_t0, vertices_t1, vertex_boxes, inflation_radius);
build(edges, faces);
}

void BroadPhase::build(
const std::vector<AABB>& _vertex_boxes,
Eigen::ConstRef<Eigen::MatrixXi> edges,
Eigen::ConstRef<Eigen::MatrixXi> faces)
{
clear();

assert(&(this->vertex_boxes) != &_vertex_boxes);
this->vertex_boxes = _vertex_boxes;

build(edges, faces);
}

void BroadPhase::build(
Eigen::ConstRef<Eigen::MatrixXi> edges,
Eigen::ConstRef<Eigen::MatrixXi> faces)
{
assert(vertex_boxes.size() > 0);
assert(edges.size() == 0 || edges.cols() == 2);
assert(faces.size() == 0 || faces.cols() == 3);
build_edge_boxes(vertex_boxes, edges, edge_boxes);
build_face_boxes(vertex_boxes, faces, face_boxes);
}
Expand Down
17 changes: 17 additions & 0 deletions src/ipc/broad_phase/broad_phase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ class BroadPhase {
Eigen::ConstRef<Eigen::MatrixXi> faces,
const double inflation_radius = 0);

/// @brief Build the broad phase for collision detection.
/// @param vertex_boxes AABBs for the vertices.
/// @param edges Collision mesh edges
/// @param faces Collision mesh faces
virtual void build(
const std::vector<AABB>& vertex_boxes,
Eigen::ConstRef<Eigen::MatrixXi> edges,
Eigen::ConstRef<Eigen::MatrixXi> faces);

/// @brief Clear any built data.
virtual void clear();

Expand Down Expand Up @@ -91,6 +100,14 @@ class BroadPhase {
default_can_vertices_collide;

protected:
/// @brief Build the broad phase for collision detection.
/// @note Assumes the vertex_boxes have been built.
/// @param edges Collision mesh edges
/// @param faces Collision mesh faces
virtual void build(
Eigen::ConstRef<Eigen::MatrixXi> edges,
Eigen::ConstRef<Eigen::MatrixXi> faces);

virtual bool can_edge_vertex_collide(size_t ei, size_t vi) const;
virtual bool can_edges_collide(size_t eai, size_t ebi) const;
virtual bool can_face_vertex_collide(size_t fi, size_t vi) const;
Expand Down
25 changes: 5 additions & 20 deletions src/ipc/broad_phase/bvh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,10 @@ BVH::BVH()
BVH::~BVH() = default;

void BVH::build(
Eigen::ConstRef<Eigen::MatrixXd> vertices,
Eigen::ConstRef<Eigen::MatrixXi> edges,
Eigen::ConstRef<Eigen::MatrixXi> faces,
const double inflation_radius)
Eigen::ConstRef<Eigen::MatrixXi> faces)
{
BroadPhase::build(vertices, edges, faces, inflation_radius);
init_bvh(vertex_boxes, *vertex_bvh);
init_bvh(edge_boxes, *edge_bvh);
init_bvh(face_boxes, *face_bvh);
}

void BVH::build(
Eigen::ConstRef<Eigen::MatrixXd> vertices_t0,
Eigen::ConstRef<Eigen::MatrixXd> vertices_t1,
Eigen::ConstRef<Eigen::MatrixXi> edges,
Eigen::ConstRef<Eigen::MatrixXi> faces,
const double inflation_radius)
{
BroadPhase::build(vertices_t0, vertices_t1, edges, faces, inflation_radius);
BroadPhase::build(edges, faces); // Build edge_boxes and face_boxes
init_bvh(vertex_boxes, *vertex_bvh);
init_bvh(edge_boxes, *edge_bvh);
init_bvh(face_boxes, *face_bvh);
Expand Down Expand Up @@ -74,9 +59,9 @@ void BVH::detect_candidates(
const std::function<bool(size_t, size_t)>& can_collide,
std::vector<Candidate>& candidates)
{
// O(n^2) or O(n^3) to build
// O(klog(n)) to do a single look up
// O(knlog(n)) to do all look ups
// O(n) or O(n⋅log(n)) to build
// O(k⋅log(n)) to do a single look up
// O(k⋅n⋅log(n)) to do all look ups

tbb::enumerable_thread_specific<std::vector<Candidate>> storage;

Expand Down
32 changes: 9 additions & 23 deletions src/ipc/broad_phase/bvh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,7 @@ class BVH : public BroadPhase {
/// @return The name of the broad phase method.
std::string name() const override { return "BVH"; }

/// @brief Build the broad phase for static collision detection.
/// @param vertices Vertex positions
/// @param edges Collision mesh edges
/// @param faces Collision mesh faces
/// @param inflation_radius Radius of inflation around all elements.
void build(
Eigen::ConstRef<Eigen::MatrixXd> vertices,
Eigen::ConstRef<Eigen::MatrixXi> edges,
Eigen::ConstRef<Eigen::MatrixXi> faces,
const double inflation_radius = 0) override;

/// @brief Build the broad phase for continuous collision detection.
/// @param vertices_t0 Starting vertices of the vertices.
/// @param vertices_t1 Ending vertices of the vertices.
/// @param edges Collision mesh edges
/// @param faces Collision mesh faces
/// @param inflation_radius Radius of inflation around all elements.
void build(
Eigen::ConstRef<Eigen::MatrixXd> vertices_t0,
Eigen::ConstRef<Eigen::MatrixXd> vertices_t1,
Eigen::ConstRef<Eigen::MatrixXi> edges,
Eigen::ConstRef<Eigen::MatrixXi> faces,
const double inflation_radius = 0) override;
using BroadPhase::build;

/// @brief Clear any built data.
void clear() override;
Expand Down Expand Up @@ -78,6 +56,14 @@ class BVH : public BroadPhase {
std::vector<FaceFaceCandidate>& candidates) const override;

protected:
/// @brief Build the broad phase for collision detection.
/// @note Assumes the vertex_boxes have been built.
/// @param edges Collision mesh edges
/// @param faces Collision mesh faces
void build(
Eigen::ConstRef<Eigen::MatrixXi> edges,
Eigen::ConstRef<Eigen::MatrixXi> faces) override;

/// @brief Initialize a BVH from a set of boxes.
/// @param[in] boxes Set of boxes to initialize the BVH with.
/// @param[out] bvh The BVH to initialize.
Expand Down
48 changes: 11 additions & 37 deletions src/ipc/broad_phase/hash_grid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,46 +18,20 @@ using namespace std::placeholders;
namespace ipc {

void HashGrid::build(
Eigen::ConstRef<Eigen::MatrixXd> vertices,
Eigen::ConstRef<Eigen::MatrixXi> edges,
Eigen::ConstRef<Eigen::MatrixXi> faces,
const double inflation_radius)
Eigen::ConstRef<Eigen::MatrixXi> faces)
{
BroadPhase::build(vertices, edges, faces, inflation_radius);
// BroadPhase::build also calls clear()
BroadPhase::build(edges, faces);

ArrayMax3d mesh_min = vertices.colwise().minCoeff().array();
ArrayMax3d mesh_max = vertices.colwise().maxCoeff().array();
AABB::conservative_inflation(mesh_min, mesh_max, inflation_radius);
ArrayMax3d mesh_min = vertex_boxes[0].min;
ArrayMax3d mesh_max = vertex_boxes[0].max;
for (const auto& box : vertex_boxes) {
mesh_min = mesh_min.min(box.min);
mesh_max = mesh_max.max(box.max);
}

const double cell_size =
suggest_good_voxel_size(vertices, edges, inflation_radius);
resize(mesh_min, mesh_max, cell_size);

insert_boxes();
}

void HashGrid::build(
Eigen::ConstRef<Eigen::MatrixXd> vertices_t0,
Eigen::ConstRef<Eigen::MatrixXd> vertices_t1,
Eigen::ConstRef<Eigen::MatrixXi> edges,
Eigen::ConstRef<Eigen::MatrixXi> faces,
const double inflation_radius)
{
BroadPhase::build(vertices_t0, vertices_t1, edges, faces, inflation_radius);
// BroadPhase::build also calls clear()

const ArrayMax3d mesh_min_t0 = vertices_t0.colwise().minCoeff();
const ArrayMax3d mesh_max_t0 = vertices_t0.colwise().maxCoeff();
const ArrayMax3d mesh_min_t1 = vertices_t1.colwise().minCoeff();
const ArrayMax3d mesh_max_t1 = vertices_t1.colwise().maxCoeff();

ArrayMax3d mesh_min = mesh_min_t0.min(mesh_min_t1);
ArrayMax3d mesh_max = mesh_max_t0.max(mesh_max_t1);
AABB::conservative_inflation(mesh_min, mesh_max, inflation_radius);

const double cell_size = suggest_good_voxel_size(
vertices_t0, vertices_t1, edges, inflation_radius);
suggest_good_voxel_size(edges.rows() > 0 ? edge_boxes : vertex_boxes);
resize(mesh_min, mesh_max, cell_size);

insert_boxes();
Expand All @@ -66,9 +40,9 @@ void HashGrid::build(
void HashGrid::resize(
Eigen::ConstRef<ArrayMax3d> domain_min,
Eigen::ConstRef<ArrayMax3d> domain_max,
double cell_size)
const double cell_size)
{
assert(cell_size != 0.0);
assert(cell_size > 0.0);
assert(std::isfinite(cell_size));

m_domain_min = domain_min;
Expand Down
32 changes: 9 additions & 23 deletions src/ipc/broad_phase/hash_grid.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,29 +33,7 @@ class HashGrid : public BroadPhase {
/// @return The name of the broad phase method.
std::string name() const override { return "HashGrid"; }

/// @brief Build the broad phase for static collision detection.
/// @param vertices Vertex positions
/// @param edges Collision mesh edges
/// @param faces Collision mesh faces
/// @param inflation_radius Radius of inflation around all elements.
void build(
Eigen::ConstRef<Eigen::MatrixXd> vertices,
Eigen::ConstRef<Eigen::MatrixXi> edges,
Eigen::ConstRef<Eigen::MatrixXi> faces,
double inflation_radius = 0) override;

/// @brief Build the broad phase for continuous collision detection.
/// @param vertices_t0 Starting vertices of the vertices.
/// @param vertices_t1 Ending vertices of the vertices.
/// @param edges Collision mesh edges
/// @param faces Collision mesh faces
/// @param inflation_radius Radius of inflation around all elements.
void build(
Eigen::ConstRef<Eigen::MatrixXd> vertices_t0,
Eigen::ConstRef<Eigen::MatrixXd> vertices_t1,
Eigen::ConstRef<Eigen::MatrixXi> edges,
Eigen::ConstRef<Eigen::MatrixXi> faces,
double inflation_radius = 0) override;
using BroadPhase::build;

/// @brief Clear the hash grid.
void clear() override
Expand Down Expand Up @@ -101,6 +79,14 @@ class HashGrid : public BroadPhase {
const ArrayMax3d& domain_max() const { return m_domain_max; }

protected:
/// @brief Build the broad phase for collision detection.
/// @note Assumes the vertex_boxes have been built.
/// @param edges Collision mesh edges
/// @param faces Collision mesh faces
void build(
Eigen::ConstRef<Eigen::MatrixXi> edges,
Eigen::ConstRef<Eigen::MatrixXi> faces) override;

void resize(
Eigen::ConstRef<ArrayMax3d> domain_min,
Eigen::ConstRef<ArrayMax3d> domain_max,
Expand Down
Loading
Loading