+bool GeomAPI_Shape::isPlanar() const
+{
+ TopoDS_Shape aShape = impl<TopoDS_Shape>();
+
+ if(aShape.IsNull()) {
+ return false;
+ }
+
+ TopAbs_ShapeEnum aShapeType = aShape.ShapeType();
+ if(aShapeType == TopAbs_COMPOUND) {
+ TopoDS_Iterator anIt(aShape);
+ int aShNum = 0;
+ for(; anIt.More(); anIt.Next()) {
+ ++aShNum;
+ }
+ if(aShNum == 1) {
+ anIt.Initialize(aShape);
+ aShape = anIt.Value();
+ }
+ }
+
+ aShapeType = aShape.ShapeType();
+ if(aShapeType == TopAbs_VERTEX) {
+ return true;
+ } else if(aShapeType == TopAbs_FACE) {
+ Handle(Geom_Surface) aSurface = BRep_Tool::Surface(TopoDS::Face(aShape));
+ if(aSurface->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
+ Handle(Geom_RectangularTrimmedSurface) aTrimSurface =
+ Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface);
+ aSurface = aTrimSurface->BasisSurface();
+ }
+ return GeomLib_IsPlanarSurface(aSurface).IsPlanar();
+ } else {
+ BRepBuilderAPI_FindPlane aFindPlane(aShape);
+ bool isFound = aFindPlane.Found() == Standard_True;
+
+ if(!isFound && aShapeType == TopAbs_EDGE) {
+ Standard_Real aFirst, aLast;
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(aShape), aFirst, aLast);
+ Handle(Standard_Type) aType = aCurve->DynamicType();
+
+ if(aType == STANDARD_TYPE(Geom_TrimmedCurve)) {
+ Handle(Geom_TrimmedCurve) aTrimCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve);
+ aType = aTrimCurve->BasisCurve()->DynamicType();
+ }
+
+ if(aType == STANDARD_TYPE(Geom_Line)
+ || aType == STANDARD_TYPE(Geom_Conic)
+ || aType == STANDARD_TYPE(Geom_Circle)
+ || aType == STANDARD_TYPE(Geom_Ellipse)
+ || aType == STANDARD_TYPE(Geom_Hyperbola)
+ || aType == STANDARD_TYPE(Geom_Parabola)) {
+ isFound = true;
+ }
+ }
+
+ return isFound;
+ }
+
+ return false;
+}
+
+std::shared_ptr<GeomAPI_Vertex> GeomAPI_Shape::vertex() const
+{
+ GeomVertexPtr aVertex;
+ if (isVertex()) {
+ const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
+ aVertex = GeomVertexPtr(new GeomAPI_Vertex);
+ aVertex->setImpl(new TopoDS_Shape(aShape));
+ }
+ return aVertex;
+}
+
+std::shared_ptr<GeomAPI_Edge> GeomAPI_Shape::edge() const
+{
+ GeomEdgePtr anEdge;
+ if (isEdge()) {
+ const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
+ anEdge = GeomEdgePtr(new GeomAPI_Edge);
+ anEdge->setImpl(new TopoDS_Shape(aShape));
+ }
+ return anEdge;
+}
+
+std::shared_ptr<GeomAPI_Wire> GeomAPI_Shape::wire() const
+{
+ GeomWirePtr aWire;
+ if (isWire()) {
+ const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
+ aWire = GeomWirePtr(new GeomAPI_Wire);
+ aWire->setImpl(new TopoDS_Shape(aShape));
+ }
+ return aWire;
+}
+
+std::shared_ptr<GeomAPI_Face> GeomAPI_Shape::face() const
+{
+ GeomFacePtr aFace;
+ if (isFace()) {
+ const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
+ aFace = GeomFacePtr(new GeomAPI_Face);
+ aFace->setImpl(new TopoDS_Shape(aShape));
+ }
+ return aFace;
+}
+
+std::shared_ptr<GeomAPI_Shell> GeomAPI_Shape::shell() const
+{
+ GeomShellPtr aShell;
+ if (isShell()) {
+ const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
+ aShell = GeomShellPtr(new GeomAPI_Shell);
+ aShell->setImpl(new TopoDS_Shape(aShape));
+ }
+ return aShell;
+}
+
+std::shared_ptr<GeomAPI_Solid> GeomAPI_Shape::solid() const
+{
+ GeomSolidPtr aSolid;
+ if (isSolid()) {
+ const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
+ aSolid = GeomSolidPtr(new GeomAPI_Solid);
+ aSolid->setImpl(new TopoDS_Shape(aShape));
+ }
+ return aSolid;
+}
+
+std::list<std::shared_ptr<GeomAPI_Shape> >
+GeomAPI_Shape::subShapes(const ShapeType theSubShapeType, const bool theOnlyUnique) const
+{
+ ListOfShape aSubs;
+ const TopoDS_Shape& aShape = impl<TopoDS_Shape>();
+ if (aShape.IsNull())
+ return aSubs;
+
+ TopTools_MapOfShape alreadyThere;
+
+ // process multi-level compounds
+ if (shapeType() == COMPOUND && theSubShapeType == COMPOUND) {
+ for (TopoDS_Iterator anIt(aShape); anIt.More(); anIt.Next()) {
+ const TopoDS_Shape& aCurrent = anIt.Value();
+ if (aCurrent.ShapeType() == TopAbs_COMPOUND) {
+ if (!theOnlyUnique || alreadyThere.Add(aCurrent)) {
+ GeomShapePtr aSub(new GeomAPI_Shape);
+ aSub->setImpl(new TopoDS_Shape(aCurrent));
+ aSubs.push_back(aSub);
+ }
+ }
+ }
+ // add self
+ GeomShapePtr aSub(new GeomAPI_Shape);
+ aSub->setImpl(new TopoDS_Shape(aShape));
+ aSubs.push_back(aSub);
+ }
+ else {
+ for (TopExp_Explorer anExp(aShape, (TopAbs_ShapeEnum)theSubShapeType);
+ anExp.More(); anExp.Next()) {
+ if (!theOnlyUnique || alreadyThere.Add(anExp.Current())) {
+ GeomShapePtr aSub(new GeomAPI_Shape);
+ aSub->setImpl(new TopoDS_Shape(anExp.Current()));
+ aSubs.push_back(aSub);
+ }
+ }
+ }
+ return aSubs;
+}
+