16 #include <deal.II/opencascade/utilities.h> 18 #ifdef DEAL_II_WITH_OPENCASCADE 20 # include <deal.II/base/exceptions.h> 21 # include <deal.II/base/point.h> 22 # include <deal.II/base/utilities.h> 24 # include <IGESControl_Controller.hxx> 25 # include <IGESControl_Reader.hxx> 26 # include <IGESControl_Writer.hxx> 27 # include <STEPControl_Controller.hxx> 28 # include <STEPControl_Reader.hxx> 29 # include <STEPControl_Writer.hxx> 30 # include <Standard_Version.hxx> 31 # include <TopExp_Explorer.hxx> 32 # include <TopoDS.hxx> 33 # include <TopoDS_Edge.hxx> 34 # include <TopoDS_Face.hxx> 35 # include <TopoDS_Shape.hxx> 40 # if (OCC_VERSION_MAJOR < 7) 41 # include <Handle_Standard_Transient.hxx> 43 # include <Standard_Transient.hxx> 46 # include <BRepAdaptor_Curve.hxx> 47 # include <BRepAdaptor_HCompCurve.hxx> 48 # include <BRepAdaptor_HCurve.hxx> 49 # include <BRepAdaptor_Surface.hxx> 50 # include <BRepAlgo_Section.hxx> 51 # include <BRepBuilderAPI_MakeEdge.hxx> 52 # include <BRepBuilderAPI_Transform.hxx> 53 # include <BRepTools.hxx> 54 # include <BRep_Builder.hxx> 55 # include <GCPnts_AbscissaPoint.hxx> 56 # include <GeomAPI_Interpolate.hxx> 57 # include <GeomAPI_ProjectPointOnCurve.hxx> 58 # include <GeomAPI_ProjectPointOnSurf.hxx> 59 # include <GeomConvert_CompCurveToBSplineCurve.hxx> 60 # include <GeomLProp_SLProps.hxx> 61 # include <Geom_BoundedCurve.hxx> 62 # include <Geom_Plane.hxx> 63 # include <IntCurvesFace_ShapeIntersector.hxx> 64 # include <ShapeAnalysis_Surface.hxx> 65 # include <TColStd_HSequenceOfTransient.hxx> 66 # include <TColStd_SequenceOfTransient.hxx> 67 # include <TColgp_HArray1OfPnt.hxx> 68 # include <gp_Lin.hxx> 69 # include <gp_Pnt.hxx> 70 # include <gp_Vec.hxx> 75 DEAL_II_NAMESPACE_OPEN
79 std::tuple<unsigned int, unsigned int, unsigned int>
83 unsigned int n_faces = 0, n_edges = 0, n_vertices = 0;
84 for (exp.Init(shape, TopAbs_FACE); exp.More(); exp.Next(), ++n_faces)
87 for (exp.Init(shape, TopAbs_EDGE); exp.More(); exp.Next(), ++n_edges)
90 for (exp.Init(shape, TopAbs_VERTEX); exp.More(); exp.Next(), ++n_vertices)
93 return std::tuple<unsigned int, unsigned int, unsigned int>(n_faces,
100 std::vector<TopoDS_Face> & faces,
101 std::vector<TopoDS_Edge> & edges,
102 std::vector<TopoDS_Vertex> &vertices)
109 for (exp.Init(shape, TopAbs_FACE); exp.More(); exp.Next())
111 faces.push_back(TopoDS::Face(exp.Current()));
113 for (exp.Init(shape, TopAbs_EDGE); exp.More(); exp.Next())
115 edges.push_back(TopoDS::Edge(exp.Current()));
117 for (exp.Init(shape, TopAbs_VERTEX); exp.More(); exp.Next())
119 vertices.push_back(TopoDS::Vertex(exp.Current()));
126 std::vector<TopoDS_Compound> & compounds,
127 std::vector<TopoDS_CompSolid> &compsolids,
128 std::vector<TopoDS_Solid> & solids,
129 std::vector<TopoDS_Shell> & shells,
130 std::vector<TopoDS_Wire> & wires)
133 compsolids.resize(0);
139 for (exp.Init(shape, TopAbs_COMPOUND); exp.More(); exp.Next())
141 compounds.push_back(TopoDS::Compound(exp.Current()));
143 for (exp.Init(shape, TopAbs_COMPSOLID); exp.More(); exp.Next())
145 compsolids.push_back(TopoDS::CompSolid(exp.Current()));
147 for (exp.Init(shape, TopAbs_SOLID); exp.More(); exp.Next())
149 solids.push_back(TopoDS::Solid(exp.Current()));
151 for (exp.Init(shape, TopAbs_SHELL); exp.More(); exp.Next())
153 shells.push_back(TopoDS::Shell(exp.Current()));
155 for (exp.Init(shape, TopAbs_WIRE); exp.More(); exp.Next())
157 wires.push_back(TopoDS::Wire(exp.Current()));
161 template <
int spacedim>
168 return gp_Pnt(p[0], 0, 0);
170 return gp_Pnt(p[0], p[1], 0);
172 return gp_Pnt(p[0], p[1], p[2]);
178 template <
int spacedim>
180 point(
const gp_Pnt &p,
const double tolerance)
186 Assert(std::abs(p.Y()) <= tolerance,
188 "Cannot convert OpenCASCADE point to 1d if p.Y() != 0."));
189 Assert(std::abs(p.Z()) <= tolerance,
191 "Cannot convert OpenCASCADE point to 1d if p.Z() != 0."));
194 Assert(std::abs(p.Z()) <= tolerance,
196 "Cannot convert OpenCASCADE point to 2d if p.Z() != 0."));
210 const double tolerance)
212 const double rel_tol =
213 std::max(tolerance, std::max(p1.
norm(), p2.
norm()) * tolerance);
214 if (direction.
norm() > 0.0)
215 return (p1 * direction < p2 * direction - rel_tol);
217 for (
int d = dim; d >= 0; --d)
218 if (p1[d] < p2[d] - rel_tol)
220 else if (p2[d] < p1[d] - rel_tol)
230 read_IGES(
const std::string &filename,
const double scale_factor)
232 IGESControl_Reader reader;
233 IFSelect_ReturnStatus stat;
234 stat = reader.ReadFile(filename.c_str());
237 Standard_Boolean failsonly = Standard_False;
238 IFSelect_PrintCount mode = IFSelect_ItemsByEntity;
239 reader.PrintCheckLoad(failsonly, mode);
241 Standard_Integer nRoots = reader.TransferRoots();
250 scale.SetScale(Origin, scale_factor);
252 TopoDS_Shape sh = reader.OneShape();
253 BRepBuilderAPI_Transform trans(sh,
scale);
255 return trans.Shape();
259 write_IGES(
const TopoDS_Shape &shape,
const std::string &filename)
261 IGESControl_Controller::Init();
262 IGESControl_Writer ICW(
"MM", 0);
263 Standard_Boolean ok = ICW.AddShape(shape);
266 Standard_Boolean OK = ICW.Write(filename.c_str());
271 read_STEP(
const std::string &filename,
const double scale_factor)
273 STEPControl_Reader reader;
274 IFSelect_ReturnStatus stat;
275 stat = reader.ReadFile(filename.c_str());
278 Standard_Boolean failsonly = Standard_False;
279 IFSelect_PrintCount mode = IFSelect_ItemsByEntity;
280 reader.PrintCheckLoad(failsonly, mode);
282 Standard_Integer nRoots = reader.TransferRoots();
291 scale.SetScale(Origin, scale_factor);
293 TopoDS_Shape sh = reader.OneShape();
294 BRepBuilderAPI_Transform trans(sh,
scale);
296 return trans.Shape();
300 write_STEP(
const TopoDS_Shape &shape,
const std::string &filename)
302 STEPControl_Controller::Init();
303 STEPControl_Writer SCW;
304 IFSelect_ReturnStatus status;
305 status = SCW.Transfer(shape, STEPControl_AsIs);
307 ExcMessage(
"Failed to add shape to STEP controller."));
309 status = SCW.Write(filename.c_str());
312 ExcMessage(
"Failed to write translated shape to STEP file."));
318 double tolerance = 0.0;
320 std::vector<TopoDS_Face> faces;
321 std::vector<TopoDS_Edge> edges;
322 std::vector<TopoDS_Vertex> vertices;
326 for (
const auto &vertex : vertices)
327 tolerance = std::fmax(tolerance, BRep_Tool::Tolerance(vertex));
329 for (
const auto &edge : edges)
330 tolerance = std::fmax(tolerance, BRep_Tool::Tolerance(edge));
332 for (
const auto &face : faces)
333 tolerance = std::fmax(tolerance, BRep_Tool::Tolerance(face));
347 Handle(Geom_Plane) plane =
new Geom_Plane(c_x, c_y, c_z, c);
348 BRepAlgo_Section section(in_shape, plane);
349 TopoDS_Shape edges = section.Shape();
354 join_edges(
const TopoDS_Shape &in_shape,
const double tolerance)
356 TopoDS_Edge out_shape;
357 const TopoDS_Shape & edges = in_shape;
358 std::vector<Handle_Geom_BoundedCurve> intersections;
362 gp_Pnt PIn(0.0, 0.0, 0.0);
363 gp_Pnt PFin(0.0, 0.0, 0.0);
364 gp_Pnt PMid(0.0, 0.0, 0.0);
365 TopExp_Explorer edgeExplorer(edges, TopAbs_EDGE);
367 while (edgeExplorer.More())
369 edge = TopoDS::Edge(edgeExplorer.Current());
370 Handle(Geom_Curve) curve = BRep_Tool::Curve(edge, L, First, Last);
371 intersections.push_back(Handle(Geom_BoundedCurve)::DownCast(curve));
377 unsigned int numIntersEdges = intersections.size();
380 GeomConvert_CompCurveToBSplineCurve convert_bspline(intersections[0]);
382 bool check =
false, one_added =
true, one_failed =
true;
383 std::vector<bool> added(numIntersEdges,
false);
385 while (one_added ==
true)
389 for (
unsigned int i = 1; i < numIntersEdges; ++i)
390 if (added[i] ==
false)
392 Handle(Geom_Curve) curve = intersections[i];
393 Handle(Geom_BoundedCurve) bcurve =
394 Handle(Geom_BoundedCurve)::DownCast(curve);
395 check = convert_bspline.Add(bcurve, tolerance,
false,
true, 0);
400 Handle(Geom_BoundedCurve) bcurve =
401 Handle(Geom_BoundedCurve)::DownCast(curve);
403 convert_bspline.Add(bcurve, tolerance,
false,
true, 0);
405 one_failed = one_failed || (check ==
false);
406 one_added = one_added || (check ==
true);
411 Assert(one_failed ==
false,
412 ExcMessage(
"Joining some of the Edges failed."));
414 Handle(Geom_Curve) bspline = convert_bspline.BSplineCurve();
416 out_shape = BRepBuilderAPI_MakeEdge(bspline);
425 const double tolerance)
429 gp_Pnt P0 =
point(origin);
432 dim > 1 ? direction[1] : 0,
433 dim > 2 ? direction[2] : 0));
437 gp_Pnt Pproj(0.0, 0.0, 0.0);
441 IntCurvesFace_ShapeIntersector Inters;
442 Inters.Load(in_shape, tolerance);
446 Inters.Perform(line, -RealLast(), +RealLast());
449 double minDistance = 1e7;
451 for (
int i = 0; i < Inters.NbPnt(); ++i)
453 const double distance =
point(origin).Distance(Inters.Pnt(i + 1));
456 if (distance < minDistance)
458 minDistance = distance;
459 result = point<dim>(Inters.Pnt(i + 1));
471 const double tolerance)
473 unsigned int n_vertices = curve_points.size();
475 if (direction * direction > 0)
477 std::sort(curve_points.begin(),
488 Handle(TColgp_HArray1OfPnt) vertices =
489 new TColgp_HArray1OfPnt(1, n_vertices);
490 for (
unsigned int vertex = 0; vertex < n_vertices; ++vertex)
492 vertices->SetValue(vertex + 1,
point(curve_points[vertex]));
496 GeomAPI_Interpolate bspline_generator(vertices, closed, tolerance);
497 bspline_generator.Perform();
498 Assert((bspline_generator.IsDone()),
499 ExcMessage(
"Interpolated bspline generation failed"));
501 Handle(Geom_BSplineCurve) bspline = bspline_generator.Curve();
502 TopoDS_Edge out_shape = BRepBuilderAPI_MakeEdge(bspline);
508 template <
int spacedim>
509 std::vector<TopoDS_Edge>
517 std::map<unsigned int, std::pair<unsigned int, unsigned int>> vert_to_faces;
518 std::map<unsigned int, std::pair<unsigned int, unsigned int>> face_to_verts;
519 std::map<unsigned int, bool> visited_faces;
520 std::map<unsigned int, Point<spacedim>> vert_to_point;
522 unsigned int face_index;
524 for (
const auto &cell : triangulation.active_cell_iterators())
525 for (
unsigned int f = 0; f < GeometryInfo<2>::faces_per_cell; ++f)
526 if (cell->face(f)->at_boundary())
529 face_index = cell->face(f)->index();
530 const unsigned int v0 = cell->face(f)->vertex_index(0);
531 const unsigned int v1 = cell->face(f)->vertex_index(1);
532 face_to_verts[face_index].first = v0;
533 face_to_verts[face_index].second = v1;
534 visited_faces[face_index] =
false;
540 f, 0,
true,
false,
false)];
542 f, 1,
true,
false,
false)];
545 if (vert_to_faces.find(v0) == vert_to_faces.end())
547 vert_to_faces[v0].first = face_index;
551 vert_to_faces[v0].second = face_index;
553 if (vert_to_faces.find(v1) == vert_to_faces.end())
555 vert_to_faces[v1].first = face_index;
559 vert_to_faces[v1].second = face_index;
565 std::vector<TopoDS_Edge> interpolation_curves;
566 bool finished = (face_to_verts.size() == 0);
567 face_index = finished ? 0 : face_to_verts.begin()->first;
569 while (finished ==
false)
571 const unsigned int start_point_index = face_to_verts[face_index].first;
572 unsigned int point_index = start_point_index;
575 std::vector<Point<spacedim>> pointlist;
578 visited_faces[face_index] =
true;
579 auto current_point = vert_to_point[point_index];
580 pointlist.push_back(current_point);
583 if (face_to_verts[face_index].first != point_index)
584 point_index = face_to_verts[face_index].first;
586 point_index = face_to_verts[face_index].second;
589 if (vert_to_faces[point_index].first != face_index)
590 face_index = vert_to_faces[point_index].first;
592 face_index = vert_to_faces[point_index].second;
594 while (point_index != start_point_index);
596 interpolation_curves.push_back(
600 for (
const auto &f : visited_faces)
601 if (f.second ==
false)
603 face_index = f.first;
608 return interpolation_curves;
613 std::tuple<Point<dim>, TopoDS_Shape, double,
double>
616 const double tolerance)
619 gp_Pnt Pproj =
point(origin);
621 double minDistance = 1e7;
622 gp_Pnt tmp_proj(0.0, 0.0, 0.0);
624 unsigned int counter = 0;
625 unsigned int face_counter = 0;
627 TopoDS_Shape out_shape;
631 for (exp.Init(in_shape, TopAbs_FACE); exp.More(); exp.Next())
633 TopoDS_Face face = TopoDS::Face(exp.Current());
637 Handle(Geom_Surface) SurfToProj = BRep_Tool::Surface(face);
639 ShapeAnalysis_Surface projector(SurfToProj);
640 gp_Pnt2d proj_params = projector.ValueOfUV(
point(origin), tolerance);
642 SurfToProj->D0(proj_params.X(), proj_params.Y(), tmp_proj);
644 double distance = point<dim>(tmp_proj).distance(origin);
645 if (distance < minDistance)
647 minDistance = distance;
661 if (face_counter == 0)
662 for (exp.Init(in_shape, TopAbs_EDGE); exp.More(); exp.Next())
664 TopoDS_Edge edge = TopoDS::Edge(exp.Current());
665 if (!BRep_Tool::Degenerated(edge))
673 Handle(Geom_Curve) CurveToProj =
674 BRep_Tool::Curve(edge, L, First, Last);
676 GeomAPI_ProjectPointOnCurve Proj(
point(origin), CurveToProj);
677 unsigned int num_proj_points = Proj.NbPoints();
678 if ((num_proj_points > 0) && (Proj.LowerDistance() < minDistance))
680 minDistance = Proj.LowerDistance();
681 Pproj = Proj.NearestPoint();
683 u = Proj.LowerDistanceParameter();
690 return std::tuple<Point<dim>, TopoDS_Shape, double,
double>(
691 point<dim>(Pproj), out_shape, u, v);
699 const double tolerance)
701 std::tuple<Point<dim>, TopoDS_Shape, double,
double> ref =
703 return std::get<0>(ref);
709 const double tolerance)
712 std::tuple<Point<3>, TopoDS_Shape, double,
double> shape_and_params =
715 TopoDS_Shape &out_shape = std::get<1>(shape_and_params);
716 double & u = std::get<2>(shape_and_params);
717 double & v = std::get<3>(shape_and_params);
721 std::tuple<unsigned int, unsigned int, unsigned int>
numbers =
728 "Could not find normal: the shape containing the closest point has 0 faces."));
732 "Could not find normal: the shape containing the closest point has more than 1 face."));
736 exp.Init(out_shape, TopAbs_FACE);
737 TopoDS_Face face = TopoDS::Face(exp.Current());
743 push_forward(
const TopoDS_Shape &in_shape,
const double u,
const double v)
745 switch (in_shape.ShapeType())
749 BRepAdaptor_Surface surf(TopoDS::Face(in_shape));
750 return point<dim>(surf.Value(u, v));
754 BRepAdaptor_Curve curve(TopoDS::Edge(in_shape));
755 return point<dim>(curve.Value(u));
769 Handle(Geom_Surface) SurfToProj = BRep_Tool::Surface(face);
770 GeomLProp_SLProps props(SurfToProj, u, v, 1, 1e-7);
771 gp_Pnt Value = props.Value();
773 gp_Dir Normal = props.Normal();
774 Assert(props.IsCurvatureDefined(),
775 ExcMessage(
"Curvature is not well defined!"));
776 Standard_Real Min_Curvature = props.MinCurvature();
777 Standard_Real Max_Curvature = props.MaxCurvature();
784 if (face.Orientation() == TopAbs_REVERSED)
791 return std::tuple<Point<3>,
Tensor<1, 3>, double,
double>(point<3>(Value),
799 template <
int spacedim>
804 BRepAdaptor_Surface surf(face);
805 const double u0 = surf.FirstUParameter();
806 const double u1 = surf.LastUParameter();
807 const double v0 = surf.FirstVParameter();
808 const double v1 = surf.LastVParameter();
810 std::vector<CellData<2>> cells;
811 std::vector<Point<spacedim>> vertices;
814 vertices.push_back(point<spacedim>(surf.Value(u0, v0)));
815 vertices.push_back(point<spacedim>(surf.Value(u1, v0)));
816 vertices.push_back(point<spacedim>(surf.Value(u0, v1)));
817 vertices.push_back(point<spacedim>(surf.Value(u1, v1)));
820 for (
unsigned int i = 0; i < 4; ++i)
823 cells.push_back(cell);
827 # include "utilities.inst" 831 DEAL_II_NAMESPACE_CLOSE
std::tuple< unsigned int, unsigned int, unsigned int > count_elements(const TopoDS_Shape &shape)
TopoDS_Shape read_IGES(const std::string &filename, const double scale_factor=1e-3)
Point< dim > push_forward(const TopoDS_Shape &in_shape, const double u, const double v)
static unsigned int face_to_cell_vertices(const unsigned int face, const unsigned int vertex, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false)
TopoDS_Shape intersect_plane(const TopoDS_Shape &in_shape, const double c_x, const double c_y, const double c_z, const double c, const double tolerance=1e-7)
TopoDS_Shape read_STEP(const std::string &filename, const double scale_factor=1e-3)
virtual std::array< Point< spacedim >, GeometryInfo< dim >::vertices_per_cell > get_vertices(const typename Triangulation< dim, spacedim >::cell_iterator &cell) const
Point< dim > line_intersection(const TopoDS_Shape &in_shape, const Point< dim > &origin, const Tensor< 1, dim > &direction, const double tolerance=1e-7)
bool point_compare(const Point< dim > &p1, const Point< dim > &p2, const Tensor< 1, dim > &direction=Tensor< 1, dim >(), const double tolerance=1e-10)
std::tuple< Point< 3 >, Tensor< 1, 3 >, double, double > push_forward_and_differential_forms(const TopoDS_Face &face, const double u, const double v, const double tolerance=1e-7)
TopoDS_Edge interpolation_curve(std::vector< Point< dim >> &curve_points, const Tensor< 1, dim > &direction=Tensor< 1, dim >(), const bool closed=false, const double tolerance=1e-7)
#define AssertThrow(cond, exc)
numbers::NumberTraits< Number >::real_type norm() const
void write_IGES(const TopoDS_Shape &shape, const std::string &filename)
__global__ void scale(Number *val, const Number *V_val, const size_type N)
void create_triangulation(const TopoDS_Face &face, Triangulation< 2, spacedim > &tria)
static ::ExceptionBase & ExcMessage(std::string arg1)
void write_STEP(const TopoDS_Shape &shape, const std::string &filename)
virtual void create_triangulation(const std::vector< Point< spacedim >> &vertices, const std::vector< CellData< dim >> &cells, const SubCellData &subcelldata)
#define Assert(cond, exc)
Abstract base class for mapping classes.
Point< dim > closest_point(const TopoDS_Shape &in_shape, const Point< dim > &origin, const double tolerance=1e-7)
void extract_compound_shapes(const TopoDS_Shape &shape, std::vector< TopoDS_Compound > &compounds, std::vector< TopoDS_CompSolid > &compsolids, std::vector< TopoDS_Solid > &solids, std::vector< TopoDS_Shell > &shells, std::vector< TopoDS_Wire > &wires)
Point< spacedim > point(const gp_Pnt &p, const double tolerance=1e-10)
std::tuple< Point< dim >, TopoDS_Shape, double, double > project_point_and_pull_back(const TopoDS_Shape &in_shape, const Point< dim > &origin, const double tolerance=1e-7)
double get_shape_tolerance(const TopoDS_Shape &shape)
TopoDS_Edge join_edges(const TopoDS_Shape &in_shape, const double tolerance=1e-7)
void extract_geometrical_shapes(const TopoDS_Shape &shape, std::vector< TopoDS_Face > &faces, std::vector< TopoDS_Edge > &edges, std::vector< TopoDS_Vertex > &vertices)
std::vector< TopoDS_Edge > create_curves_from_triangulation_boundary(const Triangulation< 2, spacedim > &triangulation, const Mapping< 2, spacedim > &mapping=StaticMappingQ1< 2, spacedim >::mapping)
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & ExcUnsupportedShape()
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)
unsigned int vertices[GeometryInfo< structdim >::vertices_per_cell]