Skip to content

#extraction sites intersected with both meshes #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
build
.ipynb_checkpoints
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
cmake_minimum_required(VERSION 3.9)
project(HTTP_SERVICE)

set(CMAKE_BUILD_TYPE "Release")

find_package(CGAL REQUIRED)
find_package(cpprestsdk REQUIRED)
find_package (Eigen3 REQUIRED NO_MODULE)


add_executable(server2 server2.cpp)

file(GLOB GEOMETRY_SRC_FILES geometry/*.cpp)
add_library(geometry ${GEOMETRY_SRC_FILES})
target_include_directories(geometry PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/geometry)
target_link_libraries(geometry PUBLIC Eigen3::Eigen)
target_link_libraries(geometry PUBLIC CGAL::CGAL)
# target_link_libraries(geometry PUBLIC ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES})
target_link_libraries(server2 Eigen3::Eigen)
target_link_libraries(server2 CGAL::CGAL)
target_link_libraries(server2 geometry)
target_link_libraries(server2 cpprestsdk::cpprest)
# add_executable(server server.cpp)
# target_link_libraries(server PRIVATE cpprestsdk::cpprest)
# target_link_libraries (server Eigen3::Eigen)
# target_link_libraries(server PRIVATE geometry)
## target_link_libraries(server ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES})

set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost 1.45.0 COMPONENTS filesystem)

if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(server2 ${Boost_LIBRARIES})
endif()


add_executable(client client.cpp)
target_link_libraries(client PRIVATE cpprestsdk::cpprest)

Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#include <cpprest/http_client.h>
#include <cpprest/json.h>
#pragma comment(lib, "cpprest_2_10")

using namespace web;
using namespace web::http;
using namespace web::http::client;

#include <iostream>
using namespace std;

void display_json(json::value const & jvalue, utility::string_t const & prefix)
{
cout << prefix << jvalue.serialize() << endl;
}

pplx::task<http_response> make_task_request(
http_client & client,
method mtd,
json::value const & jvalue)
{
return (mtd == methods::GET || mtd == methods::HEAD) ?
client.request(mtd, "/restdemo") :
client.request(mtd, "/restdemo", jvalue);
}

void make_request(http_client & client, method mtd, json::value const & jvalue)
{
make_task_request(client, mtd, jvalue)
.then([](http_response response)
{
if (response.status_code() == status_codes::OK)
{
return response.extract_json();
}
return pplx::task_from_result(json::value());
}
)
.then([] (pplx::task<json::value> previousTask)
{
try
{
display_json(previousTask.get(), "R: ");
}
catch(const std::exception& e)
{
std::cerr << e.what() << '\n';
}

}
)
.wait();
}

json::value readJsonFile(std::string const & jsonFileName)
{
json::value output; // JSON read from input file

try
{
// Open the file stream
std::ifstream f(jsonFileName);
// String stream for holding the JSON file
std::stringstream strStream;

// Stream file stream into string stream
strStream << f.rdbuf();
f.close(); // Close the filestream

// Parse the string stream into a JSON object
output = json::value::parse(strStream);
}
catch (json::json_exception excep)
{
throw json::json_exception("Error Parsing JSON file " + jsonFileName);
}

return output;
}

int main()
{

http_client client(U("http://192.168.1.100:12345"));

// auto getvalue = json::value::array();
// getvalue[0] = json::value::string("one");
// getvalue[1] = json::value::string("two");
// getvalue[2] = json::value::string("three");

auto getvalue = readJsonFile("../request.json");
cout << "\nPOST (get some values)\n";
display_json(getvalue, "S: ");
make_request(client, methods::POST, getvalue);

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
rm -rf model
mkdir -p model

as_url=https://grlc.io/api-git/hubmapconsortium/ccf-grlc/subdir/mesh-collision/anatomical-structures.csv
patch_url=https://grlc.io/api-git/hubmapconsortium/ccf-grlc/subdir/mesh-collision/placement-patches.csv

curl $as_url -o model/asct-b-grlc.csv
curl $patch_url -o model/reference-organ-grlc.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
#include "algo.h"

std::vector<std::pair<std::string, double>> collision_detection_single_tissue(std::vector<Mymesh> &organ, Mymesh &tissue, std::vector<Point> &points)
{
auto aabbtree_tissue = tissue.get_aabb_tree();
std::vector<std::pair<std::string, double>> result;

// std::cout << "organ size: " << organ.size() << std::endl;
for (int i = 0; i < organ.size(); i++)
{
auto AS = organ[i];

if (!AS.is_surface) {std::cout << "not surface: " << AS.label << std::endl; continue;}

auto aabbtree_AS = AS.get_aabb_tree();
if (aabbtree_AS->do_intersect(*aabbtree_tissue))
{

if (AS.is_closed)
{
double percentage = AS.percentage_points_inside(points);
result.push_back({AS.label, percentage});
}
else
result.push_back({AS.label, -1.0});
}
else
{

Surface_mesh &mesh = tissue.get_raw_mesh();

// the tissue block is wholely inside the anatomical structure.
bool is_contain_1 = true;
for (auto vd: mesh.vertices())
{
Point p = mesh.point(vd);
if (!AS.point_inside(p))
{
is_contain_1 = false;
break;
}
}

// the anatomical structure is wholely inside the tissue block, still use the voxel-based algorithm, can be simplified to use the volume of the anatomical structure.
// must use the volume of the anatomical structure when the tissue block is really large. Haven't implemented it yet because tissue block cannot be very large in reality.
bool is_contain_2 = true;
Surface_mesh &AS_raw_mesh = AS.get_raw_mesh();

for (auto vd: AS_raw_mesh.vertices())
{
Point p = AS_raw_mesh.point(vd);

if (!tissue.point_inside(p))
is_contain_2 = false;
break;
}


if (is_contain_1)
result.push_back({AS.label, 1.0});
else if (is_contain_2)
{
double percentage = AS.percentage_points_inside(points);
result.push_back({AS.label, percentage});
}
}
}

return result;
}

std::vector<std::string> collision_detection_bb(std::vector<Mymesh> &organ, Mymesh &tissue)
{
std::vector<std::string> result;

CGAL::Bbox_3 bb_tissue = PMP::bbox(tissue.get_raw_mesh());

for (auto &AS: organ)
{
CGAL::Bbox_3 bb_AS = PMP::bbox(AS.get_raw_mesh());
if (CGAL::do_overlap(bb_AS, bb_tissue))
result.push_back(AS.label);
}

return result;
}

std::vector<std::pair<int, double>> collision_detection_single_tissue_2(std::vector<Mymesh> &organ, Mymesh &tissue, std::vector<Point> &points)
{
auto aabbtree_tissue = tissue.get_aabb_tree();
std::vector<std::pair<int, double>> result;

// std::cout << "organ size: " << organ.size() << std::endl;
for (int i = 0; i < organ.size(); i++)
{
auto &AS = organ[i];

if (!AS.is_surface) {std::cout << "not surface: " << AS.label << std::endl; continue;}

auto aabbtree_AS = AS.get_aabb_tree();
if (aabbtree_AS->do_intersect(*aabbtree_tissue))
{

if (AS.is_closed)
{
double percentage = AS.percentage_points_inside(points);
result.push_back({i, percentage});
}
else
result.push_back({i, -1.0});
}
else
{

Surface_mesh &mesh = tissue.get_raw_mesh();

// the tissue block is wholely inside the anatomical structure.
bool is_contain_1 = true;
for (auto vd: mesh.vertices())
{
Point p = mesh.point(vd);
if (!AS.point_inside(p))
{
is_contain_1 = false;
break;
}
}

// the anatomical structure is wholely inside the tissue block, still use the voxel-based algorithm, can be simplified to use the volume of the anatomical structure.
bool is_contain_2 = true;
Surface_mesh &AS_raw_mesh = AS.get_raw_mesh();

for (auto vd: AS_raw_mesh.vertices())
{
Point p = AS_raw_mesh.point(vd);

if (!tissue.point_inside(p))
is_contain_2 = false;
break;
}


if (is_contain_1)
result.push_back({i, 1.0});
else if (is_contain_2)
{
double percentage = AS.percentage_points_inside(points);
result.push_back({i, percentage});
}
}
}

return result;
}


bool collision_detection_single_pair(Mymesh &mesh, Mymesh &tissue) {

auto aabbtree_tissue = tissue.get_aabb_tree();
auto aabbtree_mesh = mesh.get_aabb_tree();

if (aabbtree_mesh->do_intersect(*aabbtree_tissue)) return true;
return false;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef ALGO_H
#define ALGO_H

#include <iostream>
#include <vector>

#include "mymesh.h"

// mesh collision detection
std::vector<std::pair<std::string, double>> collision_detection_single_tissue(std::vector<Mymesh> &organ, Mymesh &tissue, std::vector<Point> &points);

//bb collision detection
std::vector<std::string> collision_detection_bb(std::vector<Mymesh> &organ, Mymesh &tissue);

std::vector<std::pair<int, double>> collision_detection_single_tissue_2(std::vector<Mymesh> &organ, Mymesh &tissue, std::vector<Point> &points);

bool collision_detection_single_pair(Mymesh &mesh, Mymesh &tissue);

#endif
Loading