33 #include <BRepBuilderAPI_MakeEdge.hxx> 34 #include <BRepBuilderAPI_MakeFace.hxx> 35 #include <BRepBuilderAPI_MakeVertex.hxx> 36 #include <BRepBuilderAPI_MakeWire.hxx> 37 #include <TopoDS_Edge.hxx> 38 #include <TopoDS_Face.hxx> 39 #include <TopoDS_Vertex.hxx> 40 #include <TopoDS_Wire.hxx> 41 #include <gce_MakeCirc.hxx> 42 #include <gce_MakePln.hxx> 43 #include <gp_Circ.hxx> 54 constexpr
double increment(
int numSides) {
return 360. / numSides; }
56 constexpr
double baseRotation(
int numSides) {
57 return -1. * (180 - increment(numSides)) / 2.;
60 std::array<double, 3> getRingPoint(
const std::array<double, 3> ¢er,
61 int numSides,
double radius,
double rotation,
64 center, {radius, (pointIdx * increment(numSides) + rotation +
65 baseRotation(numSides))});
68 double modRotation(
int numSides,
double rotation) {
69 return std::fmod(rotation, increment(numSides));
72 gp_Pnt coords2Point(
const std::array<double, 3> &
points) {
73 return {points[0], points[1], points[2]};
76 std::pair<std::vector<TopoDS_Vertex>, std::vector<TopoDS_Edge>>
77 getRingVerticesAndCircEdges(
78 const std::array<double, 3> ¢er,
const int numSides,
79 const double radius,
double rotation,
81 std::vector<TopoDS_Vertex> verts;
82 std::vector<TopoDS_Edge> edges;
83 assert(verts.empty() && edges.empty());
84 verts.reserve(numSides);
85 rotation = modRotation(numSides, rotation);
86 for (
int i = 0; i < numSides; ++i) {
87 auto coords = getRingPoint(center, numSides, radius, rotation, i);
88 verts.emplace_back(BRepBuilderAPI_MakeVertex{coords2Point(coords)});
91 gp_Pnt centerPt{center[0], center[1], center[2]};
92 auto circlePoint1 = getRingPoint(center, 2, radius, 0, 0);
93 auto circlePoint2 = getRingPoint(center, 2, radius, 90., 0);
95 gce_MakeCirc{centerPt,
96 gce_MakePln{coords2Point(circlePoint1),
97 coords2Point(circlePoint2), centerPt}
100 for (
int i = 0; i < numSides; ++i) {
101 edges.emplace_back(BRepBuilderAPI_MakeEdge{
102 circle, verts[i], verts[i == numSides - 1 ? 0 : i + 1]});
106 for (
int i = 0; i < numSides; ++i) {
107 edges.emplace_back(BRepBuilderAPI_MakeEdge{
108 verts[i], verts[i == numSides - 1 ? 0 : i + 1]});
111 return {std::move(verts), std::move(edges)};
114 std::vector<TopoDS_Edge> getRadialEdges(
115 const std::vector<TopoDS_Vertex> &innerVerts,
116 const std::vector<TopoDS_Vertex> &outerVerts) {
117 assert(innerVerts.size() == outerVerts.size());
118 std::vector<TopoDS_Edge> radialEdges;
119 radialEdges.reserve(innerVerts.size());
120 for (std::size_t i = 0; i < innerVerts.size(); ++i) {
121 radialEdges.emplace_back(
122 BRepBuilderAPI_MakeEdge{innerVerts[i], outerVerts[i]});
127 std::vector<TopoDS_Face> getFaces(
const std::vector<TopoDS_Edge> &innerEdges,
128 const std::vector<TopoDS_Edge> &outerEdges,
129 const std::vector<TopoDS_Edge> &radialEdges) {
130 assert(innerEdges.size() == outerEdges.size() &&
131 innerEdges.size() == radialEdges.size());
132 std::vector<TopoDS_Face> faces;
133 faces.reserve(innerEdges.size());
134 for (std::size_t i = 0; i < innerEdges.size(); ++i) {
136 faces.emplace_back(BRepBuilderAPI_MakeFace{BRepBuilderAPI_MakeWire{
137 outerEdges[i], radialEdges[i == innerEdges.size() - 1 ? 0 : i + 1],
138 innerEdges[i], radialEdges[i]}});
146 : meshingType(
MeshingType::STRUCT), numSegments(numElems) {}
152 const std::array<double, 3> ¢er)
153 :
ShapeBase(center), numSides_(numSides), rings_(
std::move(rings)) {}
164 this->
rings_ = std::move(rings);
168 this->
rings_.emplace_back(ring);
171 template <
typename RingT,
typename FVertCirc>
173 const std::array<double, 3> ¢er,
174 FVertCirc funcVertsCircEdges) {
176 if (rings.empty()) {
return output; }
178 TopoDS_Vertex centerVert{BRepBuilderAPI_MakeVertex{coords2Point(center)}};
180 std::vector<std::vector<TopoDS_Vertex>> vertices{};
181 vertices.reserve(rings.size());
182 std::vector<std::vector<TopoDS_Edge>> circumferentialEdges{};
183 circumferentialEdges.reserve(rings.size());
184 for (
const auto &ring : rings) {
185 auto vertsAndEdges = funcVertsCircEdges(ring);
186 vertices.emplace_back(std::move(vertsAndEdges.first));
187 circumferentialEdges.emplace_back(std::move(vertsAndEdges.second));
190 std::vector<std::vector<TopoDS_Edge>> radialEdges{};
191 radialEdges.reserve(rings.size());
192 std::vector<std::vector<TopoDS_Face>> faces{};
193 faces.reserve(rings.size());
195 auto prevVerts = vertices.begin();
196 auto iterVerts = rings.size() >= 2 ? prevVerts + 1 : vertices.end();
197 auto prevCircEdges = circumferentialEdges.begin();
199 rings.size() >= 2 ? prevCircEdges + 1 : circumferentialEdges.end();
201 radialEdges.emplace_back();
202 faces.emplace_back();
203 auto &innerEdges = circumferentialEdges[0];
204 BRepBuilderAPI_MakeWire wireBuilder{};
205 for (
const auto &edge : innerEdges) { wireBuilder.Add(edge); }
206 faces.back().emplace_back(BRepBuilderAPI_MakeFace{wireBuilder});
208 for (; iterVerts != vertices.end();
209 ++prevVerts, ++iterVerts, ++prevCircEdges, ++iterCircEdges) {
210 radialEdges.emplace_back(getRadialEdges(*prevVerts, *iterVerts));
212 getFaces(*prevCircEdges, *iterCircEdges, radialEdges.back()));
218 switch (rings[0].meshType.meshingType) {
230 if (!rings[0].sideset.empty()) {
231 auto &ssetName = rings[0].sideset;
232 for (
int i = 0; i < numSides; ++i) {
233 output.insertConstruct<
SideSetEdge>(circumferentialEdges[0][i],
238 auto prevCircEdges = circumferentialEdges.begin();
240 rings.size() >= 2 ? prevCircEdges + 1 : circumferentialEdges.end();
241 auto iterRadialEdges = radialEdges.begin() + 1;
242 auto iterFaces = faces.begin() + 1;
243 auto prevRing = rings.begin();
244 auto iterRing = rings.size() >= 2 ? prevRing + 1 : rings.end();
245 for (; iterRing != rings.end(); prevCircEdges = iterCircEdges,
246 ++iterCircEdges, ++iterRadialEdges,
247 ++iterFaces, ++iterRing, ++prevRing) {
250 auto &prevMeshingParams = prevRing->meshType;
251 for (
int i = 0; i < numSides; ++i) {
252 switch (meshingType) {
265 if (prevMeshingParams.meshingType ==
267 prevMeshingParams.numSegments[1] !=
meshingParams.numSegments[1]) {
268 std::cerr <<
"Different number of nodes in circumferential direction " 269 "in adjacent rings may cause mesh errors.\n";
271 for (
int i = 0; i < numSides; ++i) {
273 if (prevMeshingParams.meshingType !=
276 output.getMap()[prevCircEdges->at(i)].reset(
new EdgeSegments{
279 output.insertConstruct<
EdgeSegments>(iterCircEdges->at(i),
282 output.insertConstruct<
EdgeSegments>(iterRadialEdges->at(i),
"",
286 if (!iterRing->sideset.empty()) {
287 auto &ssetName = iterRing->sideset;
288 for (
int i = 0; i < numSides; ++i) {
289 output.insertConstruct<
SideSetEdge>(iterCircEdges->at(i), ssetName);
313 this->
rings_ = std::move(rings);
320 return getRingVerticesAndCircEdges(this->
getCenter(), 2, ring.
radius, 0);
Class to manage TopoDS_Shapes along with metadata.
void addRing(const Ring &ring)
RingMeshOption(MeshingType type)
Class to describe meshing an edge by StdMeshers_NumberOfSegments.
std::vector< Ring > rings_
NEM::GEO::GeoManager createGeo() const override
Construct a NEM::GEO::GeoManager.
NEM::GEO::GeoManager drawNested(int numSides, const std::vector< RingT > &rings, const std::array< double, 3 > ¢er, FVertCirc funcVertsCircEdges)
void setRings(std::vector< Ring > rings)
void addRing(const PolyRing &ring)
static constexpr auto shapeType
void setNumSides(int numSides)
static std::array< double, 3 > getRotatedPoint(const std::array< double, 3 > ¢er, const std::array< double, 2 > &rotation)
CirclesAndPolys(int numSides, std::vector< PolyRing > rings, const std::array< double, 3 > ¢er={0, 0, 0})
Container to describe a set of concentric circles/polygons.
std::array< int, 2 > numSegments
const std::array< double, 3 > & getCenter() const
std::vector< PolyRing > rings_
Abstract base class for types that create NEM::GEO::GeoManager.
NEM::GEO::GeoManager createGeo() const override
Construct a NEM::GEO::GeoManager.
std::vector< vtkIdType > points
points given by id in .inp file
Apply a tri mesh to a face.
Structured quad mesh (assuming edges meshed appropriately) or quad-dominant mesh. ...
Circles(std::vector< Ring > rings, const std::array< double, 3 > ¢er={0, 0, 0})
Container to describe a set of concentric circles (note circles treated as two 180 degree arcs) ...
void setRings(std::vector< PolyRing > rings)
const std::vector< Ring > & getRings() const
const std::vector< PolyRing > & getRings() const