bool operator <(const gp_XYZ& a, const gp_XYZ& b) { if (a.X() == b.X()) { if (a.Y() == b.Y()) { return a.Z() < b.Z(); } return a.Y() < b.Y(); } return a.X() < b.X(); }
//======================================================================= //function : PreciseBoundingBox //purpose : //======================================================================= Standard_Boolean GEOMUtils::PreciseBoundingBox (const TopoDS_Shape &theShape, Bnd_Box &theBox) { if ( theBox.IsVoid() ) BRepBndLib::Add( theShape, theBox ); if ( theBox.IsVoid() ) return Standard_False; Standard_Real aBound[6]; theBox.Get(aBound[0], aBound[2], aBound[4], aBound[1], aBound[3], aBound[5]); Standard_Integer i; const gp_Pnt aMid(0.5*(aBound[1] + aBound[0]), // XMid 0.5*(aBound[3] + aBound[2]), // YMid 0.5*(aBound[5] + aBound[4])); // ZMid const gp_XYZ aSize(aBound[1] - aBound[0], // DX aBound[3] - aBound[2], // DY aBound[5] - aBound[4]); // DZ const gp_Pnt aPnt[6] = { gp_Pnt(aBound[0] - (aBound[1] - aBound[0]), aMid.Y(), aMid.Z()), // XMin gp_Pnt(aBound[1] + (aBound[1] - aBound[0]), aMid.Y(), aMid.Z()), // XMax gp_Pnt(aMid.X(), aBound[2] - (aBound[3] - aBound[2]), aMid.Z()), // YMin gp_Pnt(aMid.X(), aBound[3] + (aBound[3] - aBound[2]), aMid.Z()), // YMax gp_Pnt(aMid.X(), aMid.Y(), aBound[4] - (aBound[5] - aBound[4])), // ZMin gp_Pnt(aMid.X(), aMid.Y(), aBound[5] + (aBound[5] - aBound[4])) // ZMax }; const gp_Dir aDir[3] = { gp::DX(), gp::DY(), gp::DZ() }; const Standard_Real aPlnSize[3] = { 0.5*Max(aSize.Y(), aSize.Z()), // XMin, XMax planes 0.5*Max(aSize.X(), aSize.Z()), // YMin, YMax planes 0.5*Max(aSize.X(), aSize.Y()) // ZMin, ZMax planes }; gp_Pnt aPMin[2]; for (i = 0; i < 6; i++) { const Standard_Integer iHalf = i/2; const gp_Pln aPln(aPnt[i], aDir[iHalf]); BRepBuilderAPI_MakeFace aMkFace(aPln, -aPlnSize[iHalf], aPlnSize[iHalf], -aPlnSize[iHalf], aPlnSize[iHalf]); if (!aMkFace.IsDone()) { return Standard_False; } TopoDS_Shape aFace = aMkFace.Shape(); // Get minimal distance between planar face and shape. Standard_Real aMinDist = GEOMUtils::GetMinDistance(aFace, theShape, aPMin[0], aPMin[1]); if (aMinDist < 0.) { return Standard_False; } aBound[i] = aPMin[1].Coord(iHalf + 1); } // Update Bounding box with the new values. theBox.SetVoid(); theBox.Update(aBound[0], aBound[2], aBound[4], aBound[1], aBound[3], aBound[5]); return Standard_True; }