9 const auto owner =
face.lock();
10 if (!owner || !owner->parents.count(regionID))
12 throw std::runtime_error(
"Face incidence does not belong to this region");
14 return owner->outNormal(regionID);
20 const auto owner =
face.lock();
21 if (!owner || !owner->parents.count(regionID))
23 throw std::runtime_error(
"Face incidence does not belong to this region");
25 std::shared_ptr<Polyhedron<dim, 2>> other;
26 for (
const auto &entry :
edge->parents)
28 const auto candidate = entry.second.lock();
29 if (candidate && candidate != owner && candidate->parents.count(regionID))
33 throw std::runtime_error(
"Non-manifold grain edge");
40 throw std::runtime_error(
"Open grain boundary edge");
42 return other->perimeter.at(
edge->faceIncidences.at(other->key));
44 template <>
void PolyhedralMesh<3>::orientMeshFaces()
46 for (
const auto &entry : factory<2>())
48 const auto &face = entry.second;
49 Eigen::Vector3d
area = Eigen::Vector3d::Zero();
50 const auto origin = face->perimeter.front().source()->position;
51 for (
const auto &incidence : face->perimeter)
53 area += (incidence.source()->position - origin).cross(incidence.sink()->position - origin);
55 if (
area.dot(face->asPlane().unitNormal) < 0)
57 std::reverse(face->perimeter.begin(), face->perimeter.end());
58 for (
auto &incidence : face->perimeter)
60 incidence.reversed = !incidence.reversed;
63 for (
size_t k = 0;
k < face->perimeter.size(); ++
k)
65 face->perimeter[
k].index =
k;
66 face->perimeter[
k].edge->faceIncidences.at(face->key) =
k;
75 const auto &
face = *entry.second;
76 if (
face.simplices().empty())
83 for (
const auto &incidence :
face.perimeter)
85 const auto other = incidence.otherFace(
region->key);
86 const auto otherOwner = other.face.lock();
87 if (incidence.sink() != incidence.next().source() || incidence.next().prev().edge != incidence.edge)
89 throw std::runtime_error(
"Disconnected polyhedral perimeter");
91 const bool flipped =
face.regionIDs.first != int(
region->key);
92 const bool otherFlipped = otherOwner->regionIDs.first != int(
region->key);
93 if ((incidence.reversed != flipped) == (other.reversed != otherFlipped))
95 throw std::runtime_error(
"Inconsistent oriented grain incidences");
const Polyhedron< dim, dim - 1 > & face(size_t id) const
const PolyhedronFactory< dim, order > & factory() const
const Polyhedron< dim, dim > & region(size_t id) const
std::weak_ptr< Polyhedron< dim, 2 > > face
Eigen::Matrix< double, dim, 1 > outNormal(size_t regionID) const
PolyhedralFaceIncidence otherFace(size_t regionID) const
std::shared_ptr< Polyhedron< dim, 1 > > edge