diff --git a/gmi_cap/CMakeLists.txt b/gmi_cap/CMakeLists.txt index 1ab03efda..5e2cb3ea2 100644 --- a/gmi_cap/CMakeLists.txt +++ b/gmi_cap/CMakeLists.txt @@ -13,7 +13,7 @@ set(HEADERS gmi_cap.h) add_library(gmi_cap ${SOURCES}) -target_link_libraries(gmi_cap PUBLIC gmi pcu capstone_module framework_testing) +target_link_libraries(gmi_cap PUBLIC gmi pcu lion capstone_module framework_testing) # Include directories target_include_directories(gmi_cap PUBLIC diff --git a/gmi_cap/gmi_cap.cc b/gmi_cap/gmi_cap.cc index 851c331ea..ce6495460 100644 --- a/gmi_cap/gmi_cap.cc +++ b/gmi_cap/gmi_cap.cc @@ -13,6 +13,7 @@ #include #include #include +#include gmi_ent* toGmiEntity(M_GTopo topo) @@ -219,7 +220,17 @@ static void closest_point(struct gmi_model* m, struct gmi_ent* e, (void)e; (void)to; (void)to_p; - printf("_closest_point_ not implemented!\n"); + cap_model* cm = reinterpret_cast(m); + M_GTopo topo = fromGmiEntity(e); + vec3d xyz_in, xyz_out, param_out; + xyz_in[0] = from[0]; xyz_in[1] = from[1]; xyz_in[2] = from[2]; + // Capstone recommends replacing nullptr with `seedparam` -- a known nearby + // parametric point. This interface doesn't have that functionality, but if + // it becomes added, this call should be updated. + MG_API_CALL(cm->geomInterface, get_closest_point_param(topo, xyz_in, nullptr, + xyz_out, param_out)); + to[0] = xyz_out[0]; to[1] = xyz_out[1]; to[2] = xyz_out[2]; + to_p[0] = param_out[0]; to_p[1] = param_out[1]; } static void normal(struct gmi_model* m, struct gmi_ent* e, @@ -254,10 +265,14 @@ static void first_derivative(struct gmi_model* m, struct gmi_ent* e, static int is_point_in_region(struct gmi_model* m, struct gmi_ent* e, double point[3]) { - (void)m; - (void)e; - (void)point; - printf("_is_point_in_region_ not implemented!\n"); + cap_model* cm = (cap_model*) m; + std::vector topos; + MG_API_CALL(cm->geomInterface, find_point_containment(vec3d(point), + Geometry::REGION, topos, 0.0)); + M_GTopo gtopo = fromGmiEntity(e); + for (size_t i = 0; i < topos.size(); ++i) { + if (topos[i] == gtopo) return 1; + } return 0; } @@ -267,7 +282,20 @@ static int is_in_closure_of(struct gmi_model* m, struct gmi_ent* e, (void)m; (void)e; (void)et; - printf("_is_in_closure_of_ not implemented!\n"); + if (get_dim(m, e) < get_dim(m, et)) { + cap_model* cm = (cap_model*)m; + M_GTopo ce = fromGmiEntity(e); + M_GTopo cet = fromGmiEntity(et); + GeometryTopo ce_type; + MG_API_CALL(cm->geomInterface, get_topo_type(ce, ce_type)); + std::vector adj; + MG_API_CALL(cm->geomInterface, get_adjacency(cet, ce_type, adj)); + for (size_t i = 0; i < adj.size(); ++i) { + if (ce == adj[i]) { + return 1; + } + } + } return 0; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 36cbaa07b..7c874b151 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -212,6 +212,8 @@ endif() if(ENABLE_CAPSTONE) util_exe_func(capVol capVol.cc) target_include_directories(capVol PRIVATE "${PROJECT_SOURCE_DIR}/capstone_clis") + test_exe_func(cap_inClosureOf cap_inClosureOf.cc) + test_exe_func(cap_closestPoint cap_closestPoint.cc) if(HAVE_CAPSTONE_SIZINGMETRICTOOL) util_exe_func(cap_smooth cap_smooth.cc) endif() diff --git a/test/cap_closestPoint.cc b/test/cap_closestPoint.cc new file mode 100644 index 000000000..dbde459fe --- /dev/null +++ b/test/cap_closestPoint.cc @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include +#include +#include + +int main (int argc, char* argv[]) { + MPI_Init(&argc, &argv); + PCU_Comm_Init(); + lion_set_verbosity(1); + gmi_register_cap(); + + PCU_ALWAYS_ASSERT(argc == 2); + std::string creFile(argv[1]); + // 1. Load model. + CapstoneModule cs("cap_inClosureOf", "Geometry Database : SMLIB", + "Mesh Database : Create", "Attribution Database : Create"); + cs.load_files(v_string(1, creFile)); + // 2. CreateMesh. + apf::Mesh2* m = apf::createMesh(cs.get_mesh(), cs.get_geometry()); + + PCU_ALWAYS_ASSERT(m->canGetClosestPoint()); + + apf::ModelEntity* face = m->findModelEntity(2, 1); + apf::Vector3 from(0.3, 0.4, -0.8), to, p; + m->getClosestPoint(face, from, to, p); + PCU_ALWAYS_ASSERT((to - apf::Vector3(0.3, 0.4, -0.5)).getLength() < 0.0001); + + apf::ModelEntity* edge = m->findModelEntity(1, 1); + from = apf::Vector3(0.6, 0.34, 0.6); + m->getClosestPoint(edge, from, to, p); + PCU_ALWAYS_ASSERT((to - apf::Vector3(0.5, 0.34, 0.5)).getLength() < 0.0001); + + apf::destroyMesh(m); + PCU_Comm_Free(); + MPI_Finalize(); +} diff --git a/test/cap_inClosureOf.cc b/test/cap_inClosureOf.cc new file mode 100644 index 000000000..05a2be88a --- /dev/null +++ b/test/cap_inClosureOf.cc @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include +#include +#include + +int main (int argc, char* argv[]) { + MPI_Init(&argc, &argv); + PCU_Comm_Init(); + lion_set_verbosity(1); + gmi_register_cap(); + + PCU_ALWAYS_ASSERT(argc == 2); + std::string creFile(argv[1]); + // 1. Load model. + CapstoneModule cs("cap_inClosureOf", "Geometry Database : SMLIB", + "Mesh Database : Create", "Attribution Database : Create"); + cs.load_files(v_string(1, creFile)); + // 2. CreateMesh. + apf::Mesh2* m = apf::createMesh(cs.get_mesh(), cs.get_geometry()); + // 3. Get region 1 ModelEntity*. + apf::ModelEntity* rgn = m->findModelEntity(3, 1); + PCU_ALWAYS_ASSERT(rgn); + // 4. Assert each model entity is in the closure of that region. + //FIXME: gmi_iter + for (int d = 0; d < 3; ++d) { + apf::MeshIterator* it = m->begin(d); + for (apf::MeshEntity* e = m->iterate(it); e; e = m->iterate(it)) { + apf::ModelEntity* ge = m->toModel(e); + PCU_ALWAYS_ASSERT(m->isInClosureOf(ge, rgn)); + } + } + // 5. Test face 1 for edges 3, 5, 8, 12 and verts 3, 4, 7, 8. + apf::ModelEntity* f1 = m->findModelEntity(2, 1); + PCU_ALWAYS_ASSERT(m->isInClosureOf(m->findModelEntity(1, 3), f1)); + PCU_ALWAYS_ASSERT(m->isInClosureOf(m->findModelEntity(1, 5), f1)); + PCU_ALWAYS_ASSERT(m->isInClosureOf(m->findModelEntity(1, 8), f1)); + PCU_ALWAYS_ASSERT(m->isInClosureOf(m->findModelEntity(1, 12), f1)); + PCU_ALWAYS_ASSERT(m->isInClosureOf(m->findModelEntity(0, 3), f1)); + PCU_ALWAYS_ASSERT(m->isInClosureOf(m->findModelEntity(0, 4), f1)); + PCU_ALWAYS_ASSERT(m->isInClosureOf(m->findModelEntity(0, 7), f1)); + PCU_ALWAYS_ASSERT(m->isInClosureOf(m->findModelEntity(0, 8), f1)); + + apf::destroyMesh(m); + PCU_Comm_Free(); + MPI_Finalize(); +} diff --git a/test/testing.cmake b/test/testing.cmake index 1d0e617c5..d91f4b0f6 100644 --- a/test/testing.cmake +++ b/test/testing.cmake @@ -895,6 +895,8 @@ if(ENABLE_CAPSTONE) mpi_test(capVolWing 1 ./capVol -vg 2 ${MESHES}/cap/wing_surf_only.cre) mpi_test(capVolCube 1 ./capVol -vg 3 ${MESHES}/cap/cube_surf_only.cre) mpi_test(capVolCyl2 1 ./capVol -vg 4 ${MESHES}/cap/cyl_surf_only.cre) + mpi_test(cap_inClosureOf 1 ./cap_inClosureOf ${MESHES}/cap/cube_surf_only.cre) + mpi_test(cap_closestPoint 1 ./cap_closestPoint ${MESHES}/cap/cube_surf_only.cre) if(HAVE_CAPSTONE_SIZINGMETRICTOOL) mpi_test(cap_smooth 1 ./cap_smooth) endif()