Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
PlaneSectionMesh.h
Go to the documentation of this file.
1#ifndef model_PlaneSectionMesh_H_
2#define model_PlaneSectionMesh_H_
3
4#include <SimplicialMesh.h>
5#include <Plane.h>
6#include <TriangularMesh.h>
7#include <algorithm>
8#include <cmath>
9#include <stdexcept>
10
11namespace model
12{
13 // Convex grains may form a non-convex or disconnected overall section.
14 // Triangulate their sections independently rather than ordering the whole
15 // external perimeter by polar angle. Coordinates are local to plane.
17 const Plane<3>& plane,
18 const double maxArea)
19 {
20 if(!std::isfinite(maxArea) || maxArea<=0.0)
21 {
22 throw std::invalid_argument("Plane mesh area must be finite and positive");
23 }
24 const double scale=(mesh.xMax()-mesh.xMin()).norm();
25 const double tolerance=1.e-10*scale;
27 std::vector<std::deque<Eigen::Vector2d>> sections;
28 for(const auto& region : mesh.regions())
29 {
30 std::vector<Eigen::Vector2d> points;
31 const auto addPoint=[&](const Eigen::Vector3d& point)
32 {
33 const Eigen::Vector2d local=plane.localPosition(point);
34 for(const auto& existing : points)
35 {
36 if((existing-local).norm()<=tolerance)
37 {
38 return;
39 }
40 }
41 points.push_back(local);
42 };
43 for(const auto& entry : region.second->faces())
44 {
45 const auto& hull=entry.second->convexHull();
46 for(size_t k=0;k<hull.size();++k)
47 {
48 const auto& a=hull[k]->P0;
49 const auto& b=hull[(k+1)%hull.size()]->P0;
50 const double da=(a-plane.P).dot(plane.unitNormal);
51 const double db=(b-plane.P).dot(plane.unitNormal);
52 if(std::abs(da)<=tolerance)
53 {
54 addPoint(a);
55 }
56 if((da>tolerance && db< -tolerance) || (da< -tolerance && db>tolerance))
57 {
58 addPoint(a+(da/(da-db))*(b-a));
59 }
60 }
61 }
62 if(points.size()<3)
63 {
64 continue;
65 }
66 std::sort(points.begin(),points.end(),[](const auto& a,const auto& b)
67 {
68 return a.x()<b.x() || (a.x()==b.x() && a.y()<b.y());
69 });
70 const auto cross=[](const Eigen::Vector2d& a,const Eigen::Vector2d& b,const Eigen::Vector2d& c)
71 {
72 return (b.x()-a.x())*(c.y()-a.y())-(b.y()-a.y())*(c.x()-a.x());
73 };
74 std::deque<Eigen::Vector2d> hull;
75 for(const auto& point : points)
76 {
77 while(hull.size()>1 && cross(hull[hull.size()-2],hull.back(),point)<=tolerance*tolerance)
78 {
79 hull.pop_back();
80 }
81 hull.push_back(point);
82 }
83 const auto lowerSize=hull.size();
84 for(auto it=points.rbegin()+1;it!=points.rend();++it)
85 {
86 while(hull.size()>lowerSize && cross(hull[hull.size()-2],hull.back(),*it)<=tolerance*tolerance)
87 {
88 hull.pop_back();
89 }
90 hull.push_back(*it);
91 }
92 hull.pop_back();
93 if(hull.size()<3)
94 {
95 continue;
96 }
97 // A cut coincident with an internal face belongs to both grains.
98 // Keep just one copy to avoid overlapping rendered triangles.
99 bool duplicate=false;
100 for(const auto& previous : sections)
101 {
102 if(previous.size()!=hull.size())
103 {
104 continue;
105 }
106 bool same=true;
107 for(const auto& point : hull)
108 {
109 same=same && std::any_of(previous.begin(),previous.end(),[&](const auto& other)
110 {
111 return (point-other).norm()<=tolerance;
112 });
113 }
114 duplicate=duplicate || same;
115 }
116 if(duplicate)
117 {
118 continue;
119 }
120 sections.push_back(hull);
121 TriangularMesh part;
122 part.reMesh(hull,std::deque<Eigen::Vector2d>(),maxArea,"pazqQ");
123 const int offset=result.vertices().size();
124 result.vertices().insert(result.vertices().end(),part.vertices().begin(),part.vertices().end());
125 for(const auto& triangle : part.triangles())
126 {
127 result.triangles().push_back(triangle+Eigen::Vector3i::Constant(offset));
128 }
129 }
130 return result;
131 }
132}
133#endif
void reMesh(const std::deque< Eigen::Matrix< double, 2, 1 > > &boundaryPts, const std::deque< Eigen::Matrix< double, 2, 1 > > &internalPts, const double &meshSize, const std::string &flags)
std::deque< Eigen::Vector2d > & vertices()
std::deque< Eigen::Vector3i > & triangles()
c
Definition int_R.m:15
a
Definition int_R.m:14
b
Definition int_R.m:16
TriangularMesh planeSectionMesh(const SimplicialMesh< 3 > &mesh, const Plane< 3 > &plane, const double maxArea)
int regions
Definition triangle.cpp:696
REAL ** triangle
Definition triangle.cpp:508
int k
result