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
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ target_sources( openemsh
"${CMAKE_CURRENT_SOURCE_DIR}/domain/geometrics/relation.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/domain/geometrics/bounding.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/domain/geometrics/coord.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/domain/geometrics/normal.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/domain/geometrics/point.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/domain/geometrics/segment.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/domain/geometrics/edge.cpp"
Expand All @@ -28,6 +29,7 @@ target_sources( openemsh
"${CMAKE_CURRENT_SOURCE_DIR}/domain/mesh/interval.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/domain/mesh/meshline.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/domain/mesh/meshline_policy.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/domain/material.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/domain/meshline_policy_manager.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/domain/conflict_manager.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/domain/board.cpp"
Expand Down
55 changes: 30 additions & 25 deletions src/app/openemsh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,19 @@ using namespace std;
//******************************************************************************
optional<Step> next(Step step) {
switch(step) {
case Step::ADJUST_EDGE_TO_MATERIAL:
return Step::DETECT_CONFLICT_EIP;
case Step::DETECT_CONFLICT_EIP:
return Step::DETECT_CONFLICT_CE;
case Step::DETECT_CONFLICT_CE:
return Step::DETECT_NON_CONFLICTING_EDGES;
case Step::DETECT_NON_CONFLICTING_EDGES:
return Step::ADD_FIXED_MLP;
case Step::ADD_FIXED_MLP:
return Step::SOLVE_ALL_EIP;
case Step::SOLVE_ALL_EIP:
return Step::SOLVE_ALL_CE;
case Step::SOLVE_ALL_CE:
return Step::DETECT_INDIVIDUAL_EDGES;
case Step::DETECT_INDIVIDUAL_EDGES:
return Step::DETECT_AND_SOLVE_TCMLP;
case Step::DETECT_AND_SOLVE_TCMLP:
return Step::DETECT_INTERVALS;
Expand All @@ -40,7 +42,7 @@ optional<Step> next(Step step) {
case Step::MESH:
return nullopt;
default:
unreachable();
::unreachable();
}
}

Expand All @@ -50,16 +52,17 @@ set<Step> that_and_after(Step step) {

using enum Step;
switch(step) {
case DETECT_CONFLICT_EIP: out.emplace(DETECT_CONFLICT_EIP); [[fallthrough]];
case DETECT_CONFLICT_CE: out.emplace(DETECT_CONFLICT_CE); [[fallthrough]];
case DETECT_NON_CONFLICTING_EDGES: out.emplace(DETECT_NON_CONFLICTING_EDGES); [[fallthrough]];
case ADD_FIXED_MLP: out.emplace(ADD_FIXED_MLP); [[fallthrough]];
case SOLVE_ALL_EIP: out.emplace(SOLVE_ALL_EIP); [[fallthrough]];
case SOLVE_ALL_CE: out.emplace(SOLVE_ALL_CE); [[fallthrough]];
case DETECT_AND_SOLVE_TCMLP: out.emplace(DETECT_AND_SOLVE_TCMLP); [[fallthrough]];
case DETECT_INTERVALS: out.emplace(DETECT_INTERVALS); [[fallthrough]];
case MESH: out.emplace(MESH); break;
default: unreachable();
case ADJUST_EDGE_TO_MATERIAL: out.emplace(ADJUST_EDGE_TO_MATERIAL); [[fallthrough]];
case DETECT_CONFLICT_EIP: out.emplace(DETECT_CONFLICT_EIP); [[fallthrough]];
case DETECT_CONFLICT_CE: out.emplace(DETECT_CONFLICT_CE); [[fallthrough]];
case ADD_FIXED_MLP: out.emplace(ADD_FIXED_MLP); [[fallthrough]];
case SOLVE_ALL_EIP: out.emplace(SOLVE_ALL_EIP); [[fallthrough]];
case SOLVE_ALL_CE: out.emplace(SOLVE_ALL_CE); [[fallthrough]];
case DETECT_INDIVIDUAL_EDGES: out.emplace(DETECT_INDIVIDUAL_EDGES); [[fallthrough]];
case DETECT_AND_SOLVE_TCMLP: out.emplace(DETECT_AND_SOLVE_TCMLP); [[fallthrough]];
case DETECT_INTERVALS: out.emplace(DETECT_INTERVALS); [[fallthrough]];
case MESH: out.emplace(MESH); break;
default: ::unreachable();
}

return out;
Expand Down Expand Up @@ -117,7 +120,7 @@ void OpenEMSH::write() const {
cerr << SerializerToPrettyprint::run(*board);
break;
default:
unreachable();
::unreachable();
};
}

Expand All @@ -131,28 +134,30 @@ void OpenEMSH::run(std::set<Step> const& steps) const {
};

using enum Step;
handle(DETECT_CONFLICT_EIP, [&] { board->detect_edges_in_polygons(); });
handle(DETECT_CONFLICT_CE, [&] { board->detect_colinear_edges(); });
handle(DETECT_NON_CONFLICTING_EDGES, [&] { board->detect_non_conflicting_edges(); });
handle(ADD_FIXED_MLP, [&] { board->add_fixed_meshline_policies(); });
handle(SOLVE_ALL_EIP, [&] { board->auto_solve_all_edge_in_polygon(); });
handle(SOLVE_ALL_CE, [&] { board->auto_solve_all_colinear_edges(); });
handle(DETECT_AND_SOLVE_TCMLP, [&] { board->detect_and_solve_too_close_meshline_policies(); });
handle(DETECT_INTERVALS, [&] { board->detect_intervals(); });
handle(MESH, [&] { board->mesh(); });
handle(ADJUST_EDGE_TO_MATERIAL, [&] { board->adjust_edges_to_materials(); });
handle(DETECT_CONFLICT_EIP, [&] { board->detect_edges_in_polygons(); });
handle(DETECT_CONFLICT_CE, [&] { board->detect_colinear_edges(); });
handle(ADD_FIXED_MLP, [&] { board->add_fixed_meshline_policies(); });
handle(SOLVE_ALL_EIP, [&] { board->auto_solve_all_edge_in_polygon(); });
handle(SOLVE_ALL_CE, [&] { board->auto_solve_all_colinear_edges(); });
handle(DETECT_INDIVIDUAL_EDGES, [&] { board->detect_individual_edges(); });
handle(DETECT_AND_SOLVE_TCMLP, [&] { board->detect_and_solve_too_close_meshline_policies(); });
handle(DETECT_INTERVALS, [&] { board->detect_intervals(); });
handle(MESH, [&] { board->mesh(); });

Caretaker::singleton().remember_current_timepoint();
}

//******************************************************************************
void OpenEMSH::run_all_steps() const {
run({
Step::ADJUST_EDGE_TO_MATERIAL,
Step::DETECT_CONFLICT_EIP,
Step::DETECT_CONFLICT_CE,
Step::DETECT_NON_CONFLICTING_EDGES,
Step::ADD_FIXED_MLP,
Step::SOLVE_ALL_EIP,
Step::SOLVE_ALL_CE,
Step::DETECT_INDIVIDUAL_EDGES,
Step::DETECT_AND_SOLVE_TCMLP,
Step::DETECT_INTERVALS,
Step::MESH
Expand All @@ -168,7 +173,7 @@ void OpenEMSH::run_next_step() const {
; step)
run({ step.value() });
} else {
run({ Step::DETECT_CONFLICT_EIP });
run({ Step::ADJUST_EDGE_TO_MATERIAL });
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/app/openemsh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,12 @@ class OpenEMSH {
PRETTYPRINT
} output_format = OutputFormat::CSX;

bool with_step_adjust_edges_to_material = true;
bool with_step_detect_edges_in_polygons = true;
bool with_step_detect_colinear_edges = true;
bool with_step_detect_non_conflicting_edges = true;
bool with_step_auto_solve_all_edge_in_polygon = true;
bool with_step_auto_solve_all_colinear_edges = true;
bool with_step_detect_individual_edges = true;
bool with_step_detect_and_solve_too_close_meshline_policies = true;
bool with_step_detect_intervals = true;
bool with_step_mesh = true;
Expand Down
3 changes: 2 additions & 1 deletion src/app/steps.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ namespace app {

//******************************************************************************
enum class Step {
ADJUST_EDGE_TO_MATERIAL,
DETECT_CONFLICT_EIP,
DETECT_CONFLICT_CE,
DETECT_NON_CONFLICTING_EDGES,
ADD_FIXED_MLP,
SOLVE_ALL_EIP,
SOLVE_ALL_CE,
DETECT_INDIVIDUAL_EDGES,
DETECT_AND_SOLVE_TCMLP,
DETECT_INTERVALS,
MESH
Expand Down
112 changes: 100 additions & 12 deletions src/domain/board.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,24 +88,24 @@
}

//******************************************************************************
void Board::Builder::add_polygon(Plane const plane, Polygon::Type const type, string const& name, initializer_list<Point> points) {
polygons[plane].push_back(make_shared<Polygon>(plane, type, name, from_init_list(points), Caretaker::singleton().get_history_root()));
void Board::Builder::add_polygon(Plane plane, shared_ptr<Material> const& material, string const& name, size_t priority, Polygon::RangeZ const& z_placement, initializer_list<Point> points) {
polygons[plane].push_back(make_shared<Polygon>(plane, material, name, priority, z_placement, from_init_list(points), Caretaker::singleton().get_history_root()));
}

//******************************************************************************
void Board::Builder::add_polygon(Plane const plane, Polygon::Type const type, string const& name, vector<unique_ptr<Point const>>&& points) {
polygons[plane].push_back(make_shared<Polygon>(plane, type, name, std::move(points), Caretaker::singleton().get_history_root()));
void Board::Builder::add_polygon(Plane plane, shared_ptr<Material> const& material, string const& name, size_t priority, Polygon::RangeZ const& z_placement, vector<unique_ptr<Point const>>&& points) {
polygons[plane].push_back(make_shared<Polygon>(plane, material, name, priority, z_placement, std::move(points), Caretaker::singleton().get_history_root()));
}

//******************************************************************************
void Board::Builder::add_polygon_from_box(Plane const plane, Polygon::Type const type, string const& name, Point const p1, Point const p3) {
void Board::Builder::add_polygon_from_box(Plane plane, shared_ptr<Material> const& material, string const& name, size_t priority, Polygon::RangeZ const& z_placement, Point const p1, Point const p3) {
vector<unique_ptr<Point const>> points(4);
points[0] = make_unique<Point const>(p1.x, p1.y);
points[1] = make_unique<Point const>(p1.x, p3.y);
points[2] = make_unique<Point const>(p3.x, p3.y);
points[3] = make_unique<Point const>(p3.x, p1.y);

polygons[plane].push_back(make_shared<Polygon>(plane, type, name, std::move(points), Caretaker::singleton().get_history_root()));
polygons[plane].push_back(make_shared<Polygon>(plane, material, name, priority, z_placement, std::move(points), Caretaker::singleton().get_history_root()));
}

//******************************************************************************
Expand Down Expand Up @@ -160,6 +160,76 @@
get_caretaker().take_care_of(polygon);
}

//******************************************************************************
shared_ptr<Material> Board::find_ambient_material(Plane plane, Segment const& segment) const {
return find_ambient_material(plane, segment, nullptr).first;
}

/// Check among all Polygons that match segment and current_polygon->z_placement.
/// Choose Material following this rule: CONDUCTOR>DIELECTRIC>AIR
///*****************************************************************************
pair<shared_ptr<Material>, remove_const_t<decltype(Polygon::priority)>> Board::find_ambient_material(Plane plane, Segment const& segment, shared_ptr<Polygon> const& current_polygon) const {
Bounding2D const segment_bounding = bounding(segment);

vector<pair<shared_ptr<Material>, remove_const_t<decltype(Polygon::priority)>>> materials;
for(shared_ptr<Polygon> const& polygon : get_current_state().polygons[plane]) {
if(polygon->material
&& (!current_polygon // Bypass self & z_overlap checks if not relevant.
|| (polygon != current_polygon
&& does_overlap(polygon->z_placement, current_polygon->z_placement)))
&& does_overlap(polygon->bounding, segment_bounding))
materials.emplace_back(shared_ptr<Material>(polygon->material), polygon->priority);
}

ranges::sort(materials, [](auto const& a, auto const& b) {
auto const& [material_a, priority_a] = a;

Check notice

Code scanning / CodeQL

Unused local variable Note

Variable (unnamed local variable) is not used.
auto const& [material_b, priority_b] = b;

Check notice

Code scanning / CodeQL

Unused local variable Note

Variable (unnamed local variable) is not used.
return priority_a != priority_b
? priority_a < priority_b
: *material_a < *material_b;
});

if(!materials.empty())
return materials.back();
else
// TODO if no material return Board::background_material
return {};
}

//******************************************************************************
void Board::adjust_edges_to_materials(Plane const plane) {
for(shared_ptr<Polygon> const& polygon : get_current_state().polygons[plane]) {
for(shared_ptr<Edge> const& edge : polygon->edges) {
auto const& inner_material = polygon->material;
auto const& [immediate_ambient_outer_material, outer_priority] = [&]() -> pair<shared_ptr<Material>, remove_const_t<decltype(Polygon::priority)>> {

Check notice

Code scanning / CodeQL

Unused local variable Note

Variable outer_priority is not used.
Point const translate_x(2 * equality_tolerance, 0);
Point const translate_y(0, 2 * equality_tolerance);
switch(edge->normal) {
case Normal::NONE:
return {};
case Normal::XMIN:
return find_ambient_material(plane, Range(edge->p0() - translate_x, edge->p1() - translate_x), polygon);
case Normal::XMAX:
return find_ambient_material(plane, Range(edge->p0() + translate_x, edge->p1() + translate_x), polygon);
case Normal::YMIN:
return find_ambient_material(plane, Range(edge->p0() - translate_y, edge->p1() - translate_y), polygon);
case Normal::YMAX:
return find_ambient_material(plane, Range(edge->p0() + translate_y, edge->p1() + translate_y), polygon);
default:
::unreachable();
}
} ();

if(immediate_ambient_outer_material
&& *immediate_ambient_outer_material > *inner_material) {
auto state = edge->get_current_state();
state.to_reverse = true;
edge->set_next_state(state);
}
}
}
}

/// Detect all EDGE_IN_POLYGON. Will also detect some COLINEAR_EDGES.
/// Overlapping edges should be EDGE_IN_POLYGON and not COLINEAR_EDGES.
///*****************************************************************************
Expand All @@ -169,6 +239,13 @@
if(poly_b == poly_a)
continue;

// Same priority : no reason to dismiss one.
if(poly_a->priority > poly_b->priority)
continue;

if(!does_overlap(poly_b->z_placement, poly_a->z_placement))
continue;

for(auto const& edge_a : poly_a->edges) {

struct RangeBtwIntersections {
Expand Down Expand Up @@ -307,18 +384,23 @@
}

//******************************************************************************
void Board::detect_non_conflicting_edges(Plane const plane) {
void Board::detect_individual_edges(Plane const plane) {
for(Edge* edge : get_current_state().edges[plane]) {
optional<Coord> const coord = domain::coord(edge->p0(), edge->axis);
optional<Axis> const axis = transpose(plane, edge->axis);
optional<MeshlinePolicy::Normal> const normal = cast(edge->normal);
if(coord && axis && normal && edge->get_current_state().conflicts.empty()) {
Normal const normal = edge->get_current_state().to_reverse
? reverse(edge->normal)
: edge->normal;
if(coord && axis
&& (edge->get_current_state().conflicts.empty()
|| ranges::none_of(edge->get_current_state().conflicts, [](auto const& conflict) { return conflict ? conflict->kind == Conflict::Kind::COLINEAR_EDGES : false; }))
&& edge->get_current_state().to_mesh) {
auto [t, state_e] = edge->make_next_state();
state_e.meshline_policy = line_policy_manager->add_meshline_policy(
{ edge },
axis.value(),
MeshlinePolicy::Policy::THIRDS,
normal.value(),
cast(normal),
coord.value(),
state_e.to_mesh,
t);
Expand All @@ -334,6 +416,12 @@
create_meshline_policy(this, t);
}

//******************************************************************************
void Board::adjust_edges_to_materials() {
for(auto const& plane : AllPlane)
adjust_edges_to_materials(plane);
}

//******************************************************************************
void Board::detect_edges_in_polygons() {
for(auto const& plane : AllPlane)
Expand All @@ -347,9 +435,9 @@
}

//******************************************************************************
void Board::detect_non_conflicting_edges() {
void Board::detect_individual_edges() {
for(auto const& plane : AllPlane)
detect_non_conflicting_edges(plane);
detect_individual_edges(plane);
}

//******************************************************************************
Expand Down
18 changes: 13 additions & 5 deletions src/domain/board.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include <array>
//#include <initializer_list>
#include <memory>
#include <type_traits>
#include <utility>
#include <vector>

#include "conflicts/conflict.hpp"
Expand Down Expand Up @@ -56,9 +58,9 @@ class Board
public:

void add_fixed_meshline_policy(Axis axis, Coord coord);
void add_polygon(Plane plane, Polygon::Type type, std::string const& name, std::initializer_list<Point> points);
void add_polygon(Plane plane, Polygon::Type type, std::string const& name, std::vector<std::unique_ptr<Point const>>&& points);
void add_polygon_from_box(Plane plane, Polygon::Type type, std::string const& name, Point const p1, Point const p3);
void add_polygon(Plane plane, std::shared_ptr<Material> const& material, std::string const& name, std::size_t priority, Polygon::RangeZ const& z_placement, std::initializer_list<Point> points);
void add_polygon(Plane plane, std::shared_ptr<Material> const& material, std::string const& name, std::size_t priority, Polygon::RangeZ const& z_placement, std::vector<std::unique_ptr<Point const>>&& points);
void add_polygon_from_box(Plane plane, std::shared_ptr<Material> const& material, std::string const& name, std::size_t priority, Polygon::RangeZ const& z_placement, Point const p1, Point const p3);

[[nodiscard]] std::shared_ptr<Board> build(Params&& params = Params());

Expand All @@ -78,14 +80,16 @@ class Board

/// Mesh resolution independant detection tasks
///*************************************************************************
void adjust_edges_to_materials(Plane const plane);
void detect_edges_in_polygons(Plane const plane);
void detect_colinear_edges(Plane plane);
void detect_non_conflicting_edges(Plane const plane);
void detect_individual_edges(Plane const plane);
void add_fixed_meshline_policies(Axis axis);

void adjust_edges_to_materials();
void detect_edges_in_polygons();
void detect_colinear_edges();
void detect_non_conflicting_edges();
void detect_individual_edges();
void add_fixed_meshline_policies();

/// Mesh resolution dependant detection tasks
Expand All @@ -104,6 +108,10 @@ class Board
std::vector<std::shared_ptr<ConflictEdgeInPolygon>> const& get_conflicts_edge_in_polygons(Plane const plane) const;
std::vector<std::shared_ptr<ConflictColinearEdges>> const& get_conflicts_colinear_edges(Axis const axis) const;
std::vector<std::shared_ptr<ConflictTooCloseMeshlinePolicies>> const& get_conflicts_too_close_meshline_policies(Axis const axis) const;

private:
std::shared_ptr<Material> find_ambient_material(Plane plane, Segment const& segment) const;
std::pair<std::shared_ptr<Material>, std::remove_const_t<decltype(Polygon::priority)>> find_ambient_material(Plane plane, Segment const& segment, std::shared_ptr<Polygon> const& current_polygon) const;
};

#ifdef UNITTEST
Expand Down
Loading