17 #include <deal.II/opencascade/manifold_lib.h> 19 #ifdef DEAL_II_WITH_OPENCASCADE 22 # include <BRepAdaptor_CompCurve.hxx> 23 # include <BRepAdaptor_Curve.hxx> 24 # include <BRepAdaptor_HCompCurve.hxx> 25 # include <BRepAdaptor_HCurve.hxx> 26 # include <BRepTools.hxx> 27 # include <BRep_Tool.hxx> 28 # include <GCPnts_AbscissaPoint.hxx> 29 # include <ShapeAnalysis_Curve.hxx> 30 # include <ShapeAnalysis_Surface.hxx> 31 # include <Standard_Version.hxx> 32 # include <TopoDS.hxx> 33 # if (OCC_VERSION_MAJOR < 7) 34 # include <Handle_Adaptor3d_HCurve.hxx> 38 DEAL_II_NAMESPACE_OPEN
50 Handle_Adaptor3d_HCurve
51 curve_adaptor(
const TopoDS_Shape &shape)
53 Assert((shape.ShapeType() == TopAbs_WIRE) ||
54 (shape.ShapeType() == TopAbs_EDGE),
56 if (shape.ShapeType() == TopAbs_WIRE)
57 return Handle(BRepAdaptor_HCompCurve)(
58 new BRepAdaptor_HCompCurve(TopoDS::Wire(shape)));
59 else if (shape.ShapeType() == TopAbs_EDGE)
60 return Handle(BRepAdaptor_HCurve)(
61 new BRepAdaptor_HCurve(TopoDS::Edge(shape)));
64 return Handle(BRepAdaptor_HCurve)(
new BRepAdaptor_HCurve());
71 shape_length(
const TopoDS_Shape &sh)
73 Handle_Adaptor3d_HCurve adapt = curve_adaptor(sh);
74 return GCPnts_AbscissaPoint::Length(adapt->GetCurve());
80 template <
int dim,
int spacedim>
82 const TopoDS_Shape &sh,
83 const double tolerance)
85 , tolerance(tolerance)
92 template <
int dim,
int spacedim>
93 std::unique_ptr<Manifold<dim, spacedim>>
96 return std::unique_ptr<Manifold<dim, spacedim>>(
102 template <
int dim,
int spacedim>
108 (void)surrounding_points;
110 for (
unsigned int i = 0; i < surrounding_points.size(); ++i)
113 std::max(tolerance * surrounding_points[i].norm(), tolerance),
114 ExcPointNotOnManifold<spacedim>(surrounding_points[i]));
122 template <
int dim,
int spacedim>
124 const TopoDS_Shape & sh,
126 const double tolerance)
128 , direction(direction)
129 , tolerance(tolerance)
136 template <
int dim,
int spacedim>
137 std::unique_ptr<Manifold<dim, spacedim>>
140 return std::unique_ptr<Manifold<dim, spacedim>>(
146 template <
int dim,
int spacedim>
152 (void)surrounding_points;
154 for (
unsigned int i = 0; i < surrounding_points.size(); ++i)
157 std::max(tolerance * surrounding_points[i].norm(), tolerance),
158 ExcPointNotOnManifold<spacedim>(surrounding_points[i]));
167 template <
int dim,
int spacedim>
169 const TopoDS_Shape &sh,
170 const double tolerance)
172 , tolerance(tolerance)
178 "NormalToMeshProjectionManifold needs a shape containing faces to operate."));
181 template <
int dim,
int spacedim>
182 std::unique_ptr<Manifold<dim, spacedim>>
185 return std::unique_ptr<Manifold<dim, spacedim>>(
190 template <
int dim,
int spacedim>
196 TopoDS_Shape out_shape;
199 for (
unsigned int i = 0; i < surrounding_points.size(); ++i)
202 .distance(surrounding_points[i]) <
203 std::max(tolerance * surrounding_points[i].norm(), tolerance),
204 ExcPointNotOnManifold<spacedim>(surrounding_points[i]));
208 switch (surrounding_points.size())
212 for (
unsigned int i = 0; i < surrounding_points.size(); ++i)
217 surrounding_points[i],
219 average_normal += std::get<1>(p_and_diff_forms);
222 average_normal /= 2.0;
225 average_normal.
norm() > 1e-4,
227 "Failed to refine cell: the average of the surface normals at the surrounding edge turns out to be a null vector, making the projection direction undetermined."));
229 Tensor<1, 3> T = surrounding_points[0] - surrounding_points[1];
231 average_normal = average_normal - (average_normal * T) * T;
232 average_normal /= average_normal.
norm();
237 Tensor<1, 3> u = surrounding_points[1] - surrounding_points[0];
238 Tensor<1, 3> v = surrounding_points[2] - surrounding_points[0];
239 const double n1_coords[3] = {u[1] * v[2] - u[2] * v[1],
240 u[2] * v[0] - u[0] * v[2],
241 u[0] * v[1] - u[1] * v[0]};
244 u = surrounding_points[2] - surrounding_points[3];
245 v = surrounding_points[1] - surrounding_points[3];
246 const double n2_coords[3] = {u[1] * v[2] - u[2] * v[1],
247 u[2] * v[0] - u[0] * v[2],
248 u[0] * v[1] - u[1] * v[0]};
252 average_normal = (n1 + n2) / 2.0;
255 average_normal.
norm() > tolerance,
257 "Failed to refine cell: the normal estimated via the surrounding points turns out to be a null vector, making the projection direction undetermined."));
259 average_normal /= average_normal.
norm();
264 Tensor<1, 3> u = surrounding_points[1] - surrounding_points[0];
265 Tensor<1, 3> v = surrounding_points[2] - surrounding_points[0];
266 const double n1_coords[3] = {u[1] * v[2] - u[2] * v[1],
267 u[2] * v[0] - u[0] * v[2],
268 u[0] * v[1] - u[1] * v[0]};
271 u = surrounding_points[2] - surrounding_points[3];
272 v = surrounding_points[1] - surrounding_points[3];
273 const double n2_coords[3] = {u[1] * v[2] - u[2] * v[1],
274 u[2] * v[0] - u[0] * v[2],
275 u[0] * v[1] - u[1] * v[0]};
278 u = surrounding_points[4] - surrounding_points[7];
279 v = surrounding_points[6] - surrounding_points[7];
280 const double n3_coords[3] = {u[1] * v[2] - u[2] * v[1],
281 u[2] * v[0] - u[0] * v[2],
282 u[0] * v[1] - u[1] * v[0]};
285 u = surrounding_points[6] - surrounding_points[7];
286 v = surrounding_points[5] - surrounding_points[7];
287 const double n4_coords[3] = {u[1] * v[2] - u[2] * v[1],
288 u[2] * v[0] - u[0] * v[2],
289 u[0] * v[1] - u[1] * v[0]};
293 average_normal = (n1 + n2 + n3 + n4) / 4.0;
296 average_normal.
norm() > tolerance,
298 "Failed to refine cell: the normal estimated via the surrounding points turns out to be a null vector, making the projection direction undetermined."));
300 average_normal /= average_normal.
norm();
316 template <
int dim,
int spacedim>
319 const double tolerance)
325 , curve(curve_adaptor(sh))
326 , tolerance(tolerance)
327 , length(shape_length(sh))
334 template <
int dim,
int spacedim>
335 std::unique_ptr<Manifold<dim, spacedim>>
338 return std::unique_ptr<Manifold<dim, spacedim>>(
344 template <
int dim,
int spacedim>
350 ShapeAnalysis_Curve curve_analysis;
352 const double dist = curve_analysis.Project(
353 curve->GetCurve(),
point(space_point), tolerance, proj, t,
true);
354 Assert(dist < tolerance * length,
355 ExcPointNotOnManifold<spacedim>(space_point));
357 return Point<1>(GCPnts_AbscissaPoint::Length(
358 curve->GetCurve(), curve->GetCurve().FirstParameter(), t));
363 template <
int dim,
int spacedim>
368 GCPnts_AbscissaPoint AP(curve->GetCurve(),
370 curve->GetCurve().FirstParameter());
371 gp_Pnt P = curve->GetCurve().Value(AP.Parameter());
372 return point<spacedim>(P);
375 template <
int dim,
int spacedim>
377 const double tolerance)
379 , tolerance(tolerance)
384 template <
int dim,
int spacedim>
385 std::unique_ptr<Manifold<dim, spacedim>>
388 return std::unique_ptr<Manifold<dim, spacedim>>(
394 template <
int dim,
int spacedim>
399 Handle(Geom_Surface) SurfToProj = BRep_Tool::Surface(face);
401 ShapeAnalysis_Surface projector(SurfToProj);
402 gp_Pnt2d proj_params = projector.ValueOfUV(
point(space_point), tolerance);
404 double u = proj_params.X();
405 double v = proj_params.Y();
410 template <
int dim,
int spacedim>
415 return ::OpenCASCADE::push_forward<spacedim>(face,
420 template <
int dim,
int spacedim>
426 Handle(Geom_Surface) surf = BRep_Tool::Surface(face);
430 surf->D1(chart_point[0], chart_point[1], q, Du, Dv);
437 Assert(std::abs(Du.Z()) < tolerance,
439 "Expecting derivative along Z to be zero! Bailing out."));
445 Assert(std::abs(Dv.Z()) < tolerance,
447 "Expecting derivative along Z to be zero! Bailing out."));
451 template <
int dim,
int spacedim>
452 std::tuple<double, double, double, double>
455 Standard_Real umin, umax, vmin, vmax;
456 BRepTools::UVBounds(face, umin, umax, vmin, vmax);
457 return std::make_tuple(umin, umax, vmin, vmax);
461 # include "manifold_lib.inst" 464 DEAL_II_NAMESPACE_CLOSE
NormalToMeshProjectionManifold(const TopoDS_Shape &sh, const double tolerance=1e-7)
virtual Point< 2 > pull_back(const Point< spacedim > &space_point) const override
std::tuple< unsigned int, unsigned int, unsigned int > count_elements(const TopoDS_Shape &shape)
static ::ExceptionBase & ExcImpossibleInDimSpacedim(int arg1, int arg2)
virtual Point< spacedim > push_forward(const Point< 1 > &chart_point) const override
NormalProjectionManifold(const TopoDS_Shape &sh, const double tolerance=1e-7)
Point< dim > line_intersection(const TopoDS_Shape &in_shape, const Point< dim > &origin, const Tensor< 1, dim > &direction, const double tolerance=1e-7)
virtual std::unique_ptr< Manifold< dim, spacedim > > clone() const override
#define AssertThrow(cond, exc)
virtual Point< spacedim > project_to_manifold(const ArrayView< const Point< spacedim >> &surrounding_points, const Point< spacedim > &candidate) const override
numbers::NumberTraits< Number >::real_type norm() const
virtual Point< spacedim > push_forward(const Point< 2 > &chart_point) const override
static ::ExceptionBase & ExcMessage(std::string arg1)
virtual Point< spacedim > project_to_manifold(const ArrayView< const Point< spacedim >> &surrounding_points, const Point< spacedim > &candidate) const override
#define Assert(cond, exc)
virtual std::unique_ptr< Manifold< dim, spacedim > > clone() const override
virtual std::unique_ptr< Manifold< dim, spacedim > > clone() const override
virtual std::unique_ptr< Manifold< dim, spacedim > > clone() const override
Point< dim > closest_point(const TopoDS_Shape &in_shape, const Point< dim > &origin, const double tolerance=1e-7)
Point< spacedim > point(const gp_Pnt &p, const double tolerance=1e-10)
numbers::NumberTraits< Number >::real_type distance(const Point< dim, Number > &p) const
virtual Point< spacedim > project_to_manifold(const ArrayView< const Point< spacedim >> &surrounding_points, const Point< spacedim > &candidate) const override
virtual std::unique_ptr< Manifold< dim, spacedim > > clone() const override
static ::ExceptionBase & ExcNotImplemented()
ArclengthProjectionLineManifold(const TopoDS_Shape &sh, const double tolerance=1e-7)
virtual Point< 1 > pull_back(const Point< spacedim > &space_point) const override
static ::ExceptionBase & ExcUnsupportedShape()
std::tuple< double, double, double, double > get_uv_bounds() const
virtual DerivativeForm< 1, 2, spacedim > push_forward_gradient(const Point< 2 > &chart_point) const override
DirectionalProjectionManifold(const TopoDS_Shape &sh, const Tensor< 1, spacedim > &direction, const double tolerance=1e-7)
std::tuple< Point< 3 >, Tensor< 1, 3 >, double, double > closest_point_and_differential_forms(const TopoDS_Shape &in_shape, const Point< 3 > &origin, const double tolerance=1e-7)
static ::ExceptionBase & ExcInternalError()