16 #include <deal.II/opencascade/utilities.h> 18 #ifdef DEAL_II_WITH_OPENCASCADE 20 #include <deal.II/base/point.h> 21 #include <deal.II/base/utilities.h> 22 #include <deal.II/base/exceptions.h> 29 #include <IGESControl_Controller.hxx> 30 #include <IGESControl_Reader.hxx> 31 #include <IGESControl_Writer.hxx> 33 #include <STEPControl_Controller.hxx> 34 #include <STEPControl_Reader.hxx> 35 #include <STEPControl_Writer.hxx> 38 #include <TopoDS_Shape.hxx> 39 #include <TopoDS_Face.hxx> 40 #include <TopoDS_Edge.hxx> 41 #include <TopExp_Explorer.hxx> 43 #include <Standard_Version.hxx> 44 #if (OCC_VERSION_MAJOR < 7) 45 # include <Handle_Standard_Transient.hxx> 47 # include <Standard_Transient.hxx> 50 #include <TColStd_SequenceOfTransient.hxx> 51 #include <TColStd_HSequenceOfTransient.hxx> 52 #include <TColgp_HArray1OfPnt.hxx> 57 #include <GeomAPI_ProjectPointOnSurf.hxx> 58 #include <GeomAPI_ProjectPointOnCurve.hxx> 59 #include <IntCurvesFace_ShapeIntersector.hxx> 61 #include <BRepTools.hxx> 62 #include <BRepAdaptor_Curve.hxx> 63 #include <BRepAdaptor_HCurve.hxx> 64 #include <BRepAdaptor_HCompCurve.hxx> 65 #include <BRepAdaptor_Surface.hxx> 66 #include <BRep_Builder.hxx> 67 #include <BRepBuilderAPI_Transform.hxx> 68 #include <BRepBuilderAPI_MakeEdge.hxx> 69 #include <BRepAlgo_Section.hxx> 71 #include <Geom_Plane.hxx> 72 #include <Geom_BoundedCurve.hxx> 73 #include <GeomAPI_Interpolate.hxx> 74 #include <GeomConvert_CompCurveToBSplineCurve.hxx> 75 #include <GeomLProp_SLProps.hxx> 77 #include <GCPnts_AbscissaPoint.hxx> 78 #include <ShapeAnalysis_Surface.hxx> 84 DEAL_II_NAMESPACE_OPEN
88 std::tuple<unsigned int, unsigned int, unsigned int>
92 unsigned int n_faces=0, n_edges=0, n_vertices=0;
93 for (exp.Init(shape, TopAbs_FACE);
94 exp.More(); exp.Next(), ++n_faces)
96 for (exp.Init(shape, TopAbs_EDGE);
97 exp.More(); exp.Next(), ++n_edges)
99 for (exp.Init(shape, TopAbs_VERTEX);
100 exp.More(); exp.Next(), ++n_vertices)
102 return std::tuple<unsigned int, unsigned int, unsigned int>(n_faces, n_edges, n_vertices);
106 std::vector<TopoDS_Face> &faces,
107 std::vector<TopoDS_Edge> &edges,
108 std::vector<TopoDS_Vertex> &vertices)
115 for (exp.Init(shape, TopAbs_FACE); exp.More(); exp.Next())
117 faces.push_back(TopoDS::Face(exp.Current()));
119 for (exp.Init(shape, TopAbs_EDGE); exp.More(); exp.Next())
121 edges.push_back(TopoDS::Edge(exp.Current()));
123 for (exp.Init(shape, TopAbs_VERTEX); exp.More(); exp.Next())
125 vertices.push_back(TopoDS::Vertex(exp.Current()));
131 std::vector<TopoDS_Compound> &compounds,
132 std::vector<TopoDS_CompSolid> &compsolids,
133 std::vector<TopoDS_Solid> &solids,
134 std::vector<TopoDS_Shell> &shells,
135 std::vector<TopoDS_Wire> &wires)
138 compsolids.resize(0);
144 for (exp.Init(shape, TopAbs_COMPOUND); exp.More(); exp.Next())
146 compounds.push_back(TopoDS::Compound(exp.Current()));
148 for (exp.Init(shape, TopAbs_COMPSOLID); exp.More(); exp.Next())
150 compsolids.push_back(TopoDS::CompSolid(exp.Current()));
152 for (exp.Init(shape, TopAbs_SOLID); exp.More(); exp.Next())
154 solids.push_back(TopoDS::Solid(exp.Current()));
156 for (exp.Init(shape, TopAbs_SHELL); exp.More(); exp.Next())
158 shells.push_back(TopoDS::Shell(exp.Current()));
160 for (exp.Init(shape, TopAbs_WIRE); exp.More(); exp.Next())
162 wires.push_back(TopoDS::Wire(exp.Current()));
166 template <
int spacedim>
172 return gp_Pnt(p[0], 0, 0);
174 return gp_Pnt(p[0], p[1], 0);
176 return gp_Pnt(p[0], p[1], p[2]);
182 template <
int spacedim>
189 Assert(std::abs(p.Y()) <= tolerance,
190 ExcMessage(
"Cannot convert OpenCASCADE point to 1d if p.Y() != 0."));
191 Assert(std::abs(p.Z()) <= tolerance,
192 ExcMessage(
"Cannot convert OpenCASCADE point to 1d if p.Z() != 0."));
195 Assert(std::abs(p.Z()) <= tolerance,
196 ExcMessage(
"Cannot convert OpenCASCADE point to 2d if p.Z() != 0."));
209 const double tolerance)
211 const double rel_tol=std::max(tolerance, std::max(p1.
norm(), p2.
norm())*tolerance);
212 if (direction.
norm() > 0.0)
213 return (p1*direction < p2*direction-rel_tol);
215 for (
int d=dim; d>=0; --d)
216 if (p1[d] < p2[d]-rel_tol)
218 else if (p2[d] < p1[d]-rel_tol)
228 const double scale_factor)
230 IGESControl_Reader reader;
231 IFSelect_ReturnStatus stat;
232 stat = reader.ReadFile(filename.c_str());
236 Standard_Boolean failsonly = Standard_False;
237 IFSelect_PrintCount mode = IFSelect_ItemsByEntity;
238 reader.PrintCheckLoad (failsonly, mode);
240 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 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 const double scale_factor)
273 STEPControl_Reader reader;
274 IFSelect_ReturnStatus stat;
275 stat = reader.ReadFile(filename.c_str());
279 Standard_Boolean failsonly = Standard_False;
280 IFSelect_PrintCount mode = IFSelect_ItemsByEntity;
281 reader.PrintCheckLoad (failsonly, mode);
283 Standard_Integer nRoots = reader.TransferRoots();
293 scale.SetScale (Origin, scale_factor);
295 TopoDS_Shape sh = reader.OneShape();
296 BRepBuilderAPI_Transform trans(sh, scale);
298 return trans.Shape();
302 const std::string &filename)
304 STEPControl_Controller::Init();
305 STEPControl_Writer SCW;
306 IFSelect_ReturnStatus status;
307 status = SCW.Transfer(shape, STEPControl_AsIs);
310 status = SCW.Write(filename.c_str());
312 AssertThrow(status == IFSelect_RetDone,
ExcMessage(
"Failed to write translated shape to STEP file."));
317 double tolerance = 0.0;
319 std::vector<TopoDS_Face> faces;
320 std::vector<TopoDS_Edge> edges;
321 std::vector<TopoDS_Vertex> vertices;
328 for (
unsigned int i=0; i<vertices.size(); ++i)
329 tolerance = fmax(tolerance,BRep_Tool::Tolerance(vertices[i]));
331 for (
unsigned int i=0; i<edges.size(); ++i)
332 tolerance = fmax(tolerance,BRep_Tool::Tolerance(edges[i]));
334 for (
unsigned int i=0; i<faces.size(); ++i)
335 tolerance = fmax(tolerance,BRep_Tool::Tolerance(faces[i]));
348 Handle(Geom_Plane) plane =
new Geom_Plane(c_x,c_y,c_z,c);
349 BRepAlgo_Section section(in_shape, plane);
350 TopoDS_Shape edges = section.Shape();
355 const double tolerance)
357 TopoDS_Edge out_shape;
358 const TopoDS_Shape &edges = in_shape;
359 std::vector<Handle_Geom_BoundedCurve> intersections;
363 gp_Pnt PIn(0.0,0.0,0.0);
364 gp_Pnt PFin(0.0,0.0,0.0);
365 gp_Pnt PMid(0.0,0.0,0.0);
366 TopExp_Explorer edgeExplorer(edges, TopAbs_EDGE);
368 while (edgeExplorer.More())
370 edge = TopoDS::Edge(edgeExplorer.Current());
371 Handle(Geom_Curve) curve = BRep_Tool::Curve(edge,L,First,Last);
372 intersections.push_back(Handle(Geom_BoundedCurve)::DownCast(curve));
378 unsigned int numIntersEdges = intersections.size();
381 GeomConvert_CompCurveToBSplineCurve convert_bspline(intersections[0]);
383 bool check =
false, one_added =
true, one_failed=
true;
384 std::vector<bool> added(numIntersEdges,
false);
386 while (one_added ==
true)
390 for (
unsigned int i=1; i<numIntersEdges; ++i)
391 if (added[i] ==
false)
393 Handle(Geom_Curve) curve = intersections[i];
394 Handle(Geom_BoundedCurve) bcurve = Handle(Geom_BoundedCurve)::DownCast(curve);
395 check = convert_bspline.Add(bcurve,tolerance,
false,
true,0);
399 Handle(Geom_BoundedCurve) bcurve = Handle(Geom_BoundedCurve)::DownCast(curve);
400 check = convert_bspline.Add(bcurve,tolerance,
false,
true,0);
402 one_failed = one_failed || (check ==
false);
403 one_added = one_added || (check ==
true);
408 Assert(one_failed ==
false,
409 ExcMessage(
"Joining some of the Edges failed."));
411 Handle(Geom_Curve) bspline = convert_bspline.BSplineCurve();
413 out_shape = BRepBuilderAPI_MakeEdge(bspline);
421 const double tolerance)
425 gp_Pnt P0 =
point(origin);
426 gp_Ax1 gpaxis(P0, gp_Dir(direction[0], dim > 1 ? direction[1] : 0, dim>2 ? direction[2] : 0));
430 gp_Pnt Pproj(0.0,0.0,0.0);
434 IntCurvesFace_ShapeIntersector Inters;
435 Inters.Load(in_shape,tolerance);
439 Inters.Perform(line,-RealLast(),+RealLast());
442 double minDistance = 1e7;
444 for (
int i=0; i<Inters.NbPnt(); ++i)
446 const double distance =
point(origin).Distance(Inters.Pnt(i+1));
448 if (distance < minDistance)
450 minDistance = distance;
451 result = point<dim>(Inters.Pnt(i+1));
462 const double tolerance)
465 unsigned int n_vertices = curve_points.size();
467 if (direction*direction > 0)
469 std::sort(curve_points.begin(), curve_points.end(),
477 Handle(TColgp_HArray1OfPnt) vertices =
new TColgp_HArray1OfPnt(1,n_vertices);
478 for (
unsigned int vertex=0; vertex<n_vertices; ++vertex)
480 vertices->SetValue(vertex+1,
point(curve_points[vertex]));
484 GeomAPI_Interpolate bspline_generator(vertices, closed, tolerance);
485 bspline_generator.Perform();
486 Assert( (bspline_generator.IsDone()),
ExcMessage(
"Interpolated bspline generation failed"));
488 Handle(Geom_BSplineCurve) bspline = bspline_generator.Curve();
489 TopoDS_Edge out_shape = BRepBuilderAPI_MakeEdge(bspline);
495 template<
int spacedim>
503 std::map<unsigned int, std::pair<unsigned int,unsigned int> > vert_to_faces;
504 std::map<unsigned int, std::pair<unsigned int,unsigned int> > face_to_verts;
505 std::map<unsigned int, bool> visited_faces;
506 std::map<unsigned int, Point<spacedim> > vert_to_point;
508 unsigned int face_index;
510 for (
auto cell: triangulation.active_cell_iterators())
511 for (
unsigned int f=0; f<GeometryInfo<2>::faces_per_cell; ++f)
512 if (cell->face(f)->at_boundary())
515 face_index = cell->face(f)->index();
516 const unsigned int v0 = cell->face(f)->vertex_index(0);
517 const unsigned int v1 = cell->face(f)->vertex_index(1);
518 face_to_verts[face_index].first = v0;
519 face_to_verts[face_index].second = v1;
520 visited_faces[face_index] =
false;
528 if (vert_to_faces.find(v0) == vert_to_faces.end())
530 vert_to_faces[v0].first = face_index;
534 vert_to_faces[v0].second = face_index;
536 if (vert_to_faces.find(v1) == vert_to_faces.end())
538 vert_to_faces[v1].first = face_index;
542 vert_to_faces[v1].second = face_index;
548 std::vector<TopoDS_Edge> interpolation_curves;
549 bool finished = (face_to_verts.size() == 0);
550 face_index = finished ? 0 : face_to_verts.begin()->first;
552 while (finished ==
false)
554 const unsigned int start_point_index = face_to_verts[face_index].first;
555 unsigned int point_index = start_point_index;
558 std::vector<Point<spacedim> > pointlist;
561 visited_faces[face_index] =
true;
562 auto current_point = vert_to_point[point_index];
563 pointlist.push_back(current_point);
566 if (face_to_verts[face_index].first != point_index )
567 point_index = face_to_verts[face_index].first;
569 point_index = face_to_verts[face_index].second;
572 if (vert_to_faces[point_index].first != face_index)
573 face_index = vert_to_faces[point_index].first;
575 face_index = vert_to_faces[point_index].second;
577 while (point_index != start_point_index);
582 for (
const auto &f : visited_faces)
583 if (f.second ==
false)
585 face_index = f.first;
590 return interpolation_curves;
597 const double tolerance)
600 gp_Pnt Pproj =
point(origin);
602 double minDistance = 1e7;
603 gp_Pnt tmp_proj(0.0,0.0,0.0);
605 unsigned int counter = 0;
606 unsigned int face_counter = 0;
608 TopoDS_Shape out_shape;
612 for (exp.Init(in_shape, TopAbs_FACE); exp.More(); exp.Next())
614 TopoDS_Face face = TopoDS::Face(exp.Current());
618 Handle(Geom_Surface) SurfToProj = BRep_Tool::Surface(face);
620 ShapeAnalysis_Surface projector(SurfToProj);
621 gp_Pnt2d proj_params = projector.ValueOfUV(
point(origin), tolerance);
623 SurfToProj->D0(proj_params.X(),proj_params.Y(),tmp_proj);
625 double distance = point<dim>(tmp_proj).distance(origin);
626 if (distance < minDistance)
628 minDistance = distance;
643 for (exp.Init(in_shape, TopAbs_EDGE); exp.More(); exp.Next())
645 TopoDS_Edge edge = TopoDS::Edge(exp.Current());
646 if (!BRep_Tool::Degenerated(edge))
654 Handle(Geom_Curve) CurveToProj = BRep_Tool::Curve(edge,L,First,Last);
656 GeomAPI_ProjectPointOnCurve Proj(
point(origin),CurveToProj);
657 unsigned int num_proj_points = Proj.NbPoints();
658 if ((num_proj_points > 0) && (Proj.LowerDistance() < minDistance))
660 minDistance = Proj.LowerDistance();
661 Pproj = Proj.NearestPoint();
663 u=Proj.LowerDistanceParameter();
670 return std::tuple<Point<dim>, TopoDS_Shape, double,
double>
671 (point<dim>(Pproj),out_shape, u, v);
678 const double tolerance)
680 std::tuple<Point<dim>, TopoDS_Shape, double,
double>
682 return std::get<0>(ref);
688 const double tolerance)
691 std::tuple<Point<3>, TopoDS_Shape, double,
double>
696 TopoDS_Shape &out_shape = std::get<1>(shape_and_params);
697 double &u = std::get<2>(shape_and_params);
698 double &v = std::get<3>(shape_and_params);
702 std::tuple<unsigned int, unsigned int, unsigned int>
numbers =
707 ExcMessage(
"Could not find normal: the shape containing the closest point has 0 faces."));
709 ExcMessage(
"Could not find normal: the shape containing the closest point has more than 1 face."));
713 exp.Init(out_shape, TopAbs_FACE);
714 TopoDS_Face face = TopoDS::Face(exp.Current());
723 switch (in_shape.ShapeType())
727 BRepAdaptor_Surface surf(TopoDS::Face(in_shape));
728 return point<dim>(surf.Value(u,v));
732 BRepAdaptor_Curve curve(TopoDS::Edge(in_shape));
733 return point<dim>(curve.Value(u));
747 Handle(Geom_Surface) SurfToProj = BRep_Tool::Surface(face);
748 GeomLProp_SLProps props(SurfToProj, u, v, 1, 1e-7);
749 gp_Pnt Value = props.Value();
751 gp_Dir Normal = props.Normal();
752 Assert(props.IsCurvatureDefined(),
ExcMessage(
"Curvature is not well defined!"));
753 Standard_Real Min_Curvature = props.MinCurvature();
754 Standard_Real Max_Curvature = props.MaxCurvature();
761 if (face.Orientation()==TopAbs_REVERSED)
768 return std::tuple<Point<3>,
Tensor<1,3>, double,
double>(point<3>(Value), normal, Min_Curvature, Max_Curvature);
773 template<
int spacedim>
777 BRepAdaptor_Surface surf(face);
778 const double u0 = surf.FirstUParameter();
779 const double u1 = surf.LastUParameter();
780 const double v0 = surf.FirstVParameter();
781 const double v1 = surf.LastVParameter();
783 std::vector<CellData<2> > cells;
784 std::vector<Point<spacedim> > vertices;
787 vertices.push_back(point<spacedim>(surf.Value(u0,v0)));
788 vertices.push_back(point<spacedim>(surf.Value(u1,v0)));
789 vertices.push_back(point<spacedim>(surf.Value(u0,v1)));
790 vertices.push_back(point<spacedim>(surf.Value(u1,v1)));
793 for (
unsigned int i=0; i<4; ++i)
796 cells.push_back(cell);
800 #include "utilities.inst" 804 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)
Point< spacedim > point(const gp_Pnt &p, const double &tolerance=1e-10)
TopoDS_Shape read_STEP(const std::string &filename, const double scale_factor=1e-3)
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)
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)
#define AssertThrow(cond, exc)
numbers::NumberTraits< Number >::real_type norm() const
void write_IGES(const TopoDS_Shape &shape, const std::string &filename)
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)
#define Assert(cond, exc)
Abstract base class for mapping classes.
virtual void create_triangulation(const std::vector< Point< spacedim > > &vertices, const std::vector< CellData< dim > > &cells, const SubCellData &subcelldata)
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)
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]