16#include <boost/range/irange.hpp>
18#include "../utils/interpolation.hpp"
51 longTranElement().getMidpoint(),
57 return mesh.vertAxis->at(
vertIndex) <= p.vert() && p.vert() <= mesh.vertAxis->at(
vertIndex+1)
62 Box2D ltBox = longTranElement().getBoundingBox();
88 object.attr(
"type",
"extrudedtriangular3d");
89 {
auto a =
object.addTag(
"vert");
vertAxis->writeXML(
a); }
97 for (
int i = 0; i < 2; ++i) {
103 else if (
node ==
"long_tran")
112static RegisterMeshReader extrudedtriangular3d_reader(
"extrudedtriangular3d", readExtrudedTriangularMesh3D);
154 if (geometry.objectIncludes(object, path,
this->
at(el.getNodeIndex(0), layer)) &&
155 geometry.objectIncludes(object, path,
this->
at(el.getNodeIndex(1), layer)) &&
156 geometry.objectIncludes(object, path,
this->
at(el.getNodeIndex(2), layer)))
161template<ExtrudedTriangularMesh3D::S
ideBoundaryDir boundaryDir>
162std::set<std::size_t> ExtrudedTriangularMesh3D::boundaryNodes(
163 const ExtrudedTriangularMesh3D::LayersIntervalSet&
layers,
165 const GeometryObject&
object,
166 const PathHints *path)
const
168 std::set<std::size_t>
result;
178ExtrudedTriangularMesh3D::LayersInterval ExtrudedTriangularMesh3D::layersIn(
const Box3D &
box)
const {
179 return LayersInterval(this->
vertAxis->findIndex(box.lower.vert()),
this->vertAxis->findUpIndex(
box.upper.vert()));
182ExtrudedTriangularMesh3D::LayersIntervalSet ExtrudedTriangularMesh3D::layersIn(
const std::vector<Box3D>&
boxes)
const {
192template <ExtrudedTriangularMesh3D::S
ideBoundaryDir boundaryDir>
194 return Boundary( [=](
const ExtrudedTriangularMesh3D& mesh,
const shared_ptr<
const GeometryD<3>>& geometry) {
195 if (mesh.empty())
return BoundaryNodeSet(
new EmptyBoundaryImpl());
196 LayersIntervalSet
layers = mesh.layersIn(
geometry->getObjectBoundingBoxes(
object, path));
197 if (
layers.empty())
return BoundaryNodeSet(
new EmptyBoundaryImpl());
198 return BoundaryNodeSet(
new StdSetBoundaryImpl(mesh.boundaryNodes<
boundaryDir>(
layers, *geometry, *
object, &path)));
202template <ExtrudedTriangularMesh3D::S
ideBoundaryDir boundaryDir>
204 return Boundary( [=](
const ExtrudedTriangularMesh3D& mesh,
const shared_ptr<
const GeometryD<3>>& geometry) {
205 if (mesh.empty())
return BoundaryNodeSet(
new EmptyBoundaryImpl());
206 LayersIntervalSet
layers = mesh.layersIn(
geometry->getObjectBoundingBoxes(
object));
207 if (
layers.empty())
return BoundaryNodeSet(
new EmptyBoundaryImpl());
208 return BoundaryNodeSet(
new StdSetBoundaryImpl(mesh.boundaryNodes<
boundaryDir>(
layers, *geometry, *
object)));
212template<ExtrudedTriangularMesh3D::S
ideBoundaryDir boundaryDir>
215 return Boundary( [=](
const ExtrudedTriangularMesh3D& mesh,
const shared_ptr<
const GeometryD<3>>&) {
216 if (mesh.empty())
return BoundaryNodeSet(
new EmptyBoundaryImpl());
217 return BoundaryNodeSet(
new ExtrudedTriangularBoundaryImpl(
219 mesh.longTranMesh.boundaryNodes<ExtrudedTriangularMesh3D::boundaryDir3Dto2D(
boundaryDir)>(mesh.longTranMesh.countSegments()),
220 LayersInterval(0, mesh.vertAxis->size()-1)));
224template<ExtrudedTriangularMesh3D::S
ideBoundaryDir boundaryDir>
227 return Boundary( [=](
const ExtrudedTriangularMesh3D& mesh,
const shared_ptr<
const GeometryD<3>>&) {
228 if (mesh.empty())
return BoundaryNodeSet(
new EmptyBoundaryImpl());
229 LayersInterval
layers = mesh.layersIn(
box);
230 if (
layers.lower() >=
layers.upper())
return BoundaryNodeSet(
new EmptyBoundaryImpl());
231 return BoundaryNodeSet(
new ExtrudedTriangularBoundaryImpl(
233 mesh.longTranMesh.boundaryNodes<ExtrudedTriangularMesh3D::boundaryDir3Dto2D(
boundaryDir)>(mesh.longTranMesh.countSegmentsIn(
to_longTran(
box))),
238BoundaryNodeSet ExtrudedTriangularMesh3D::topOrBottomBoundaryNodeSet(
const Box3D &
box,
bool top)
const {
240 if (
layers.lower() >=
layers.upper())
return new EmptyBoundaryImpl();
247 return new StdSetBoundaryImpl(std::move(
nodes3d));
250BoundaryNodeSet ExtrudedTriangularMesh3D::topOrBottomBoundaryNodeSet(
const GeometryD<3>& geometry,
const GeometryObject&
object,
const PathHints *path,
bool top)
const {
251 if (this->
empty())
return BoundaryNodeSet(
new EmptyBoundaryImpl());
252 LayersIntervalSet
layers = layersIn(
geometry.getObjectBoundingBoxes(
object, path));
253 if (
layers.empty())
return new EmptyBoundaryImpl();
255 std::fill_n(
index2d_to_layer.get(),
this->longTranMesh.size(), std::numeric_limits<std::size_t>::max());
273 return new StdSetBoundaryImpl(std::move(
nodes3d));
295 return BoundaryNodeSet(
new ExtrudedTriangularWholeLayerBoundaryImpl(mesh, 0));
328 return mesh.topOrBottomBoundaryNodeSet(
box,
false);
334 return mesh.topOrBottomBoundaryNodeSet(
box,
true);
380 return mesh.topOrBottomBoundaryNodeSet(*geometry, *
object, &path,
true);
386 return mesh.topOrBottomBoundaryNodeSet(*geometry, *
object,
nullptr,
true);
392 return mesh.topOrBottomBoundaryNodeSet(*geometry, *
object, &path,
false);
398 return mesh.topOrBottomBoundaryNodeSet(*geometry, *
object,
nullptr,
false);
405template<
typename DstT,
typename SrcT>
407 const shared_ptr<const ExtrudedTriangularMesh3D> &src_mesh,
409 const shared_ptr<
const MeshD<3> > &dst_mesh,
418template <
typename DstT,
typename SrcT>
421 const auto point = this->dst_mesh->
at(index);
424 for (
auto v: nodesIndex | boost::geometry::index::adaptors::queried(boost::geometry::index::nearest(
wrapped_longTran, 1)))
425 return this->flags.postprocess(point,
427 this->src_mesh->index(
449template<
typename DstT,
typename SrcT>
451 const shared_ptr<const ExtrudedTriangularMesh3D> &src_mesh,
453 const shared_ptr<
const MeshD<3> > &dst_mesh,
457 elementIndex(src_mesh->longTranMesh)
461template <
typename DstT,
typename SrcT>
463 const auto point = this->dst_mesh->
at(index);
467 for (
auto v: elementIndex.rtree | boost::geometry::index::adaptors::queried(boost::geometry::index::intersects(
wrapped_longTran))) {
468 const auto el = this->src_mesh->longTranMesh.getElement(
v.second);
470 if (
b.c0 < 0.0 ||
b.c1 < 0.0 ||
b.c2 < 0.0)
continue;
480 *this->src_mesh->vertAxis,
this->flags,
486 typename std::remove_const<
typename std::remove_reference<
decltype(this->src_vec[0])>::type>::type
499 return NaN<
decltype(this->src_vec[0])>();
516template<
typename DstT,
typename SrcT>
518 const shared_ptr<const ExtrudedTriangularMesh3D::ElementMesh> &src_mesh,
520 const shared_ptr<
const MeshD<3> > &dst_mesh,
523 elementIndex(src_mesh->getOriginalMesh().longTranMesh)
527template<
typename DstT,
typename SrcT>
529 const auto point = this->dst_mesh->
at(index);
535 return NaN<
decltype(this->src_vec[0])>();
541 return NaN<
decltype(this->src_vec[0])>();
543 return this->flags.postprocess(point,
563 if (this->originalMesh == c->originalMesh)
return true;