+
+//=================================================================================================
+std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeTools::fitPlaneToBox(const std::shared_ptr<GeomAPI_Shape> thePlane,
+ const std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints)
+{
+ std::shared_ptr<GeomAPI_Shape> aResultShape;
+
+ if(!thePlane.get()) {
+ return aResultShape;
+ }
+
+ const TopoDS_Shape& aShape = thePlane->impl<TopoDS_Shape>();
+ if(aShape.ShapeType() != TopAbs_FACE) {
+ return aResultShape;
+ }
+
+ TopoDS_Face aFace = TopoDS::Face(aShape);
+ Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
+ if(aSurf.IsNull()) {
+ return aResultShape;
+ }
+
+ GeomLib_IsPlanarSurface isPlanar(aSurf);
+ if(!isPlanar.IsPlanar()) {
+ return aResultShape;
+ }
+
+ if(thePoints.size() != 8) {
+ return aResultShape;
+ }
+
+ const gp_Pln& aFacePln = isPlanar.Plan();
+ Handle(Geom_Plane) aFacePlane = new Geom_Plane(aFacePln);
+ IntAna_Quadric aQuadric(aFacePln);
+ Standard_Real UMin, UMax, VMin, VMax;
+ UMin = UMax = VMin = VMax = 0;
+ for (std::list<std::shared_ptr<GeomAPI_Pnt> >::const_iterator aPointsIt = thePoints.begin(); aPointsIt != thePoints.end(); aPointsIt++) {
+ const gp_Pnt& aPnt = (*aPointsIt)->impl<gp_Pnt>();
+ gp_Lin aLin(aPnt, aFacePln.Axis().Direction());
+ IntAna_IntConicQuad anIntAna(aLin, aQuadric);
+ const gp_Pnt& aPntOnFace = anIntAna.Point(1);
+ Standard_Real aPntU(0), aPntV(0);
+ GeomLib_Tool::Parameters(aFacePlane, aPntOnFace, Precision::Confusion(), aPntU, aPntV);
+ if(aPntU < UMin) UMin = aPntU;
+ if(aPntU > UMax) UMax = aPntU;
+ if(aPntV < VMin) VMin = aPntV;
+ if(aPntV > VMax) VMax = aPntV;
+ }
+ aResultShape.reset(new GeomAPI_Shape);
+ aResultShape->setImpl(new TopoDS_Shape(BRepLib_MakeFace(aFacePln, UMin, UMax, VMin, VMax).Face()));
+
+ return aResultShape;
+}