15 Cut3DCell(
const std::vector<ECI> &global_cut_edges,
16 const std::set<uint64_t> &global_cut_vertices,
24 const auto& p = plane_point;
25 const auto& n = plane_normal;
26 const size_t cell_num_faces = cell.
faces_.size();
29 auto NumberInSet = [](uint64_t number,
const std::set<uint64_t>& the_set)
31 if (the_set.find(number) != the_set.end())
return true;
37 auto EdgeIsCut = [](
const Edge& edge,
const std::vector<ECI>& cut_edges)
39 Edge edge_set(std::min(edge.first,edge.second),
40 std::max(edge.first,edge.second));
42 constexpr auto Arg1 = std::placeholders::_1;
43 constexpr auto Comparator = &ECI::Comparator;
45 auto result = std::find_if(cut_edges.begin(),
47 std::bind(Comparator,Arg1,edge_set));
49 if (result != cut_edges.end())
50 return std::make_pair(
true,*result);
52 return std::make_pair(
false,*result);
56 auto NumberInList = [](uint64_t number,
const std::vector<uint64_t>& list)
58 auto result = std::find(list.begin(), list.end(), number);
60 if (result != list.end())
return true;
64 auto NumberInList_t = [](
size_t number,
const std::vector<size_t>& list)
66 auto result = std::find(list.begin(), list.end(), number);
68 if (result != list.end())
return true;
74 auto FlipEdge = [](
const Edge& in_edge)
76 return Edge(in_edge.second, in_edge.first);
80 auto PopulateFragment = [NumberInList](std::vector<uint64_t>& frag,
81 const std::vector<Edge>& frag_edges)
83 for (
auto edge : frag_edges)
85 if (not NumberInList(edge.first , frag)) frag.push_back(edge.first );
86 if (not NumberInList(edge.second, frag)) frag.push_back(edge.second);
94 std::vector<ECI> local_cut_edges;
95 const std::set<uint64_t> local_vertex_id_set(cell.
vertex_ids_.begin(),
98 for (
auto& eci : global_cut_edges)
99 if (NumberInSet(eci.vertex_ids.first , local_vertex_id_set) and
100 NumberInSet(eci.vertex_ids.second, local_vertex_id_set))
101 local_cut_edges.push_back(eci);
105 std::stringstream outstr;
106 outstr <<
"Local cut edges:\n";
107 for (
const auto& eci : local_cut_edges)
108 outstr << eci.vertex_ids.first <<
"->"
109 << eci.vertex_ids.second <<
" "
110 <<
"cut at vertex " << eci.cut_point_id <<
" "
111 << mesh.
vertices[eci.cut_point_id].PrintStr()
119 std::vector<size_t> cut_faces_indices;
120 std::vector<size_t> uncut_faces_indices_A;
121 std::vector<size_t> uncut_faces_indices_B;
122 cut_faces_indices.reserve(cell_num_faces);
125 for (
const auto& face : cell.
faces_)
127 size_t num_neg_senses = 0;
128 size_t num_pos_senses = 0;
129 for (
auto vid : face.vertex_ids_)
132 double new_sense = n.Dot(x-p);
134 if (new_sense < (0.0-float_compare)) ++num_neg_senses;
135 if (new_sense > (0.0+float_compare)) ++num_pos_senses;
137 if (num_neg_senses>0 && num_pos_senses>0)
138 { cut_faces_indices.push_back(face_index);
break; }
141 if (num_neg_senses > 0 and num_pos_senses == 0)
142 uncut_faces_indices_A.push_back(face_index);
143 if (num_neg_senses == 0 and num_pos_senses > 0)
144 uncut_faces_indices_B.push_back(face_index);
152 std::stringstream outstr;
153 outstr <<
"Cut faces:\n";
154 for (
const auto& f : cut_faces_indices)
158 outstr <<
"Uncut faces A:\n";
159 for (
const auto& f : uncut_faces_indices_A)
162 outstr <<
"Uncut faces B:\n";
163 for (
const auto& f : uncut_faces_indices_B)
173 std::map<size_t, std::vector<uint64_t>> cut_faces_fragments_A;
174 std::map<size_t, std::vector<uint64_t>> cut_faces_fragments_B;
176 for (
const auto& cut_face_id : cut_faces_indices)
178 const auto& cut_face = cell.
faces_[cut_face_id];
180 if (verbose)
Chi::log.
Log() <<
"cut face " << cut_face_id;
183 std::vector<Edge> fragment_edges_A;
184 std::vector<Edge> fragment_edges_B;
185 const size_t face_num_verts = cut_face.vertex_ids_.size();
186 for (
size_t e=0; e<face_num_verts; ++e)
190 auto edge_cut_state = EdgeIsCut(edge, local_cut_edges);
191 bool edge_is_cut = edge_cut_state.first;
192 ECI& edge_cut_info = edge_cut_state.second;
195 std::vector<Edge> extracted_edges;
196 extracted_edges.reserve(2);
199 extracted_edges.push_back(
200 std::make_pair(edge.first, edge_cut_info.
cut_point_id));
201 extracted_edges.push_back(
202 std::make_pair(edge_cut_info.
cut_point_id, edge.second));
205 extracted_edges.push_back(edge);
209 std::stringstream outstr;
210 for (
const auto& eedge : extracted_edges)
211 outstr << eedge.first <<
"->" << eedge.second <<
" ";
213 << edge.first <<
"->" << edge.second
214 <<
" cut? " << ((edge_is_cut)?
"yes" :
"no")
215 <<
" " << outstr.str();
219 for (
const auto& extracted_edge : extracted_edges)
221 if (n.Dot(
GetEdgeCentroid(extracted_edge, mesh) - p) < 0.0 - float_compare)
222 fragment_edges_A.push_back(extracted_edge);
224 fragment_edges_B.push_back(extracted_edge);
229 std::vector<uint64_t> fragment_A;
230 std::vector<uint64_t> fragment_B;
232 fragment_A.reserve(fragment_edges_A.size() + 1);
233 fragment_B.reserve(fragment_edges_B.size() + 1);
235 PopulateFragment(fragment_A, fragment_edges_A);
236 PopulateFragment(fragment_B, fragment_edges_B);
239 cut_faces_fragments_A[cut_face_id] = fragment_A;
240 cut_faces_fragments_B[cut_face_id] = fragment_B;
246 std::stringstream outstr;
247 outstr <<
"Cut faces fragments A:\n";
248 for (
const auto& f_fragment : cut_faces_fragments_A)
250 outstr <<
" face " << f_fragment.first <<
": ";
251 for (uint64_t vid : f_fragment.second)
252 outstr << vid <<
" ";
256 outstr <<
"Cut faces fragments B:\n";
257 for (
const auto& f_fragment : cut_faces_fragments_B)
259 outstr <<
" face " << f_fragment.first <<
": ";
260 for (uint64_t vid : f_fragment.second)
261 outstr << vid <<
" ";
271 auto MakeProxyFaces = [NumberInList_t, cut_faces_indices, FlipEdge,
274 const std::vector<size_t>& uncut_faces_indices,
275 const std::map<size_t, std::vector<uint64_t>>& cut_face_fragments)
279 std::vector<std::vector<uint64_t>> proxy_faces;
280 proxy_faces.reserve(parent_cell.faces_.size());
283 for (
const auto& face : parent_cell.faces_)
285 if (NumberInList_t(f, uncut_faces_indices))
286 proxy_faces.push_back(face.vertex_ids_);
287 else if (NumberInList_t(f, cut_faces_indices))
288 proxy_faces.push_back(cut_face_fragments.at(f));
297 for (
auto& edge : non_manifold_edges)
298 edge = FlipEdge(edge);
303 std::vector<uint64_t> interface_proxy_face;
304 PopulateFragment(interface_proxy_face, stitched_nm_edges);
306 proxy_faces.push_back(std::move(interface_proxy_face));
312 MakeProxyFaces(cell, uncut_faces_indices_A, cut_faces_fragments_A);
314 MakeProxyFaces(cell, uncut_faces_indices_B, cut_faces_fragments_B);
316 chi_mesh::Cell cell_A(CellType::POLYHEDRON, CellType::POLYHEDRON);
317 auto cell_A_ptr = &cell_A;
318 auto cell_B_ptr = std::make_unique<chi_mesh::Cell>(CellType::POLYHEDRON,
319 CellType::POLYHEDRON);
334 std::set<uint64_t> verts;
335 for (uint64_t vid : cell_A_ptr->vertex_ids_)
337 for (uint64_t vid : cell_B_ptr->vertex_ids_)
341 for (uint64_t vid : verts)
345 << cell_A_ptr->ToString()
346 << cell_B_ptr->ToString();
LogStream Log(LOG_LVL level=LOG_0)
std::vector< CellFace > faces_
std::string ToString() const
std::vector< uint64_t > vertex_ids_
void push_back(std::unique_ptr< chi_mesh::Cell > new_cell)
LocalCellHandler local_cells
Edge MakeEdgeFromPolygonEdgeIndex(const std::vector< uint64_t > &vertex_ids, size_t edge_index)
std::vector< Edge > FindNonManifoldEdges(const std::vector< std::vector< uint64_t > > &proxy_faces)
void Cut3DCell(const std::vector< ECI > &global_cut_edges, const std::set< uint64_t > &number, const Vector3 &plane_point, const Vector3 &plane_normal, double float_compare, MeshContinuum &mesh, chi_mesh::Cell &cell, bool verbose=false)
void PopulatePolyhedronFromFaces(const MeshContinuum &mesh, const std::vector< std::vector< uint64_t > > &raw_faces, chi_mesh::Cell &cell)
std::vector< Edge > StitchEdgesEndToEnd(const std::vector< Edge > &edges)
chi_mesh::Vector3 GetEdgeCentroid(const Edge &edge, const chi_mesh::MeshContinuum &grid)
std::pair< uint64_t, uint64_t > Edge