Commit 6681ac51 authored by Deepak Rangarajan's avatar Deepak Rangarajan Committed by Mark Meredith
Browse files

Resolve "support CsgIF complement"

parent e4fc822b
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ std::shared_ptr<Tree> parse_csg(std::string);

class CsgIF : GPUable {
public:
  CsgIF(std::shared_ptr<Tree> a_state);
  CsgIF(std::shared_ptr<Tree> a_state, bool is_internal_flow = false);
  CsgIF(const CsgIF &rhs);
  CsgIF(CsgIF &&rhs) noexcept;
  CsgIF &operator=(const CsgIF &rhs) = delete;
@@ -42,13 +42,18 @@ public:

private:
  std::shared_ptr<Tree> m_state;
  bool m_is_internal_flow;

  class Impl;
  std::unique_ptr<Impl> m_pimpl;
};

std::shared_ptr<csg::Tree> get_csgtree_from_filename(std::string);
std::unique_ptr<CsgIF> get_csgif_from_filename(std::string geom_file);
std::unique_ptr<CsgIF>
get_csgif_from_filename(std::string geom_file); // TODO: Deprecate once mfix has
                                                // stopped using this call
std::unique_ptr<CsgIF> get_csgif(const std::string &geom_file,
                                 bool is_internal_flow = false);

} // namespace csg

+23 −4
Original line number Diff line number Diff line
@@ -42,16 +42,22 @@ public:
};

CsgIF::CsgIF(const CsgIF &rhs)
    : m_state(rhs.m_state), m_pimpl(std::make_unique<Impl>(*rhs.m_pimpl)) {}
    : m_state(rhs.m_state), m_is_internal_flow(rhs.m_is_internal_flow),
      m_pimpl(std::make_unique<Impl>(*rhs.m_pimpl)) {}

CsgIF::CsgIF(std::shared_ptr<Tree> a_state)
    : m_state(a_state), m_pimpl(std::make_unique<Impl>()) {}
CsgIF::CsgIF(std::shared_ptr<Tree> a_state, bool is_internal_flow)
    : m_state(a_state), m_is_internal_flow(is_internal_flow),
      m_pimpl(std::make_unique<Impl>()) {}

CsgIF::CsgIF(CsgIF &&rhs) noexcept = default;
CsgIF::~CsgIF() = default;

double CsgIF::operator()(double xx, double yy, double zz) const noexcept {
  return m_pimpl->call_signed_distance(m_state, xx, yy, zz);
  auto sd = m_pimpl->call_signed_distance(m_state, xx, yy, zz);
  if (m_is_internal_flow) {
    return -sd;
  }
  return sd;
}

std::shared_ptr<csg::Tree> get_csgtree_from_filename(std::string geom_file) {
@@ -75,4 +81,17 @@ std::unique_ptr<CsgIF> get_csgif_from_filename(std::string geom_file) {
  return std::make_unique<CsgIF>(csg_if);
}

std::unique_ptr<CsgIF> get_csgif(const std::string &geom_file,
                                 bool is_internal_flow) {
  auto csg_obj = get_csgtree_from_filename(geom_file);

  if (!csg_obj) {
    std::cout << "Failed to parse .csg file:  " << geom_file << std::endl;
    return nullptr;
  }

  csg::CsgIF csg_if(csg_obj, is_internal_flow);
  return std::make_unique<CsgIF>(csg_if);
}

} // namespace csg
+1 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ add_executable(unit_tests_csg EXCLUDE_FROM_ALL
  levelset/extrude.t.cpp
  levelset/primitives.t.cpp
  levelset/transform.t.cpp
  levelset/internal_flow.t.cpp
  parser/boolean.t.cpp
  parser/extrude.t.cpp
  parser/nest.cpp
+71 −0
Original line number Diff line number Diff line
#include "catch2/catch.hpp"

#include <csg.hpp>
#include <csg_types.hpp>

#include <memory>

namespace {

TEST_CASE("union internal flow", "[Levelset Internal Flow]") {
  // Create a union of a cube of size 12 and a sphere of radius 8
  csg::Cube my_cub{.name = std::nullopt, .size = {12, 12, 12}, .center = true};
  csg::Sphere my_sph{.name = std::nullopt, .radius = 8};

  auto my_union = csg::Union3D();
  my_union.objs.push_back(my_cub);
  my_union.objs.push_back(my_sph);

  auto my_tree = std::make_shared<csg::Tree>();
  my_tree->top.objs.push_back(my_union);
  csg::CsgIF my_ls(my_tree);
  csg::CsgIF my_ls_comp(my_tree, true);

  auto check = [&my_ls, &my_ls_comp](double xx, double yy, double zz) {
    CHECK(my_ls(xx, yy, zz) == -my_ls_comp(xx, yy, zz));
  };

  SECTION("Inside") {
    check(0, 7, 0);
    check(0, 0, -7.5);
  }
  SECTION("Outside") {
    check(0, -9, 0);
    check(9, 0, 0);
  }
}

TEST_CASE("CsgIF copy constructor", "[Levelset Internal Flow]") {

  csg::Sphere my_sph{.name = std::nullopt, .radius = 10};

  auto my_tree = std::make_shared<csg::Tree>();
  my_tree->top.objs.push_back(my_sph);
  csg::CsgIF my_ls1(my_tree);
  csg::CsgIF my_ls2(my_ls1);
  csg::CsgIF my_ls_comp1(my_tree, true);
  csg::CsgIF my_ls_comp2(my_ls_comp1);

  auto check = [&my_ls1, &my_ls2, &my_ls_comp1,
                &my_ls_comp2](double xx, double yy, double zz) {
    CHECK(my_ls1(xx, yy, zz) == my_ls2(xx, yy, zz));
    CHECK(my_ls_comp1(xx, yy, zz) == my_ls_comp2(xx, yy, zz));
    CHECK(my_ls1(xx, yy, zz) == -my_ls_comp1(xx, yy, zz));
    CHECK(my_ls2(xx, yy, zz) == -my_ls_comp2(xx, yy, zz));
  };

  SECTION("Outside") {
    check(0, 8, 8);
    check(-8, 0, 8);
    check(0, 8, -8);
  }
  SECTION("Inside") {
    check(0, 0, 0);
    check(0, 7, 7);
    check(-7, 0, 7);
    check(-7, 0, 7);
    check(0, 7, -7);
  }
}

} // namespace
+1 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ test_csg = executable(
  'levelset/extrude.t.cpp',
  'levelset/primitives.t.cpp',
  'levelset/transform.t.cpp',
  'levelset/internal_flow.t.cpp',
  'parser/boolean.t.cpp',
  'parser/extrude.t.cpp',
  'parser/nest.cpp',