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(); }
void AspMainTest::FillPartWithPoints(MainFrame * mainWindow, AspMainTool *tool){ auto iter = tool->product->UnitMap.begin(); auto end = tool->product->UnitMap.end(); Timer timer; timer.Start(); _int fullAmount = 0; _int inPointsAMount = 0; for (_int i = 0; iter != end; ++iter, ++i){ //Status updating QString status = "Pnt gen "; status += std::to_string(i).c_str(); status += " / "; status += std::to_string( tool->product->UnitMap.size()).c_str(); mainWindow->SetStatus(status); static BRepClass3d_SolidClassifier solidClsf; TopoDS_Shape pShape = iter->second->getShape(); gp_Pnt center = iter->second->GetCenter(); Bnd_Box * pBox = iter->second->BndBox(); gp_Pnt pBoxInf = pBox->CornerMin(); gp_Pnt pBoxSup = pBox->CornerMax(); //Points every 3 mm _real step = 2; _real XRange = pBoxSup.X() - pBoxInf.X(); _real YRange = pBoxSup.Y() - pBoxInf.Y(); _real ZRange = pBoxSup.Z() - pBoxInf.Z(); _int nbX = std::ceil(XRange / step); _int nbY = std::ceil(YRange / step); _int nbZ = std::ceil(ZRange / step); _int amount = nbX*nbY*nbZ; fullAmount += amount; nbX = nbX ? nbX : 1; nbY = nbY ? nbY : 1; nbZ = nbZ ? nbZ : 1; _real stpX = XRange / nbX; _real stpY = YRange / nbY; _real stpZ = ZRange / nbZ; std::vector<gp_Pnt> pointsInsidePart; solidClsf.Load(pShape); for (_int i = 1; i <= nbX; ++i){ static gp_XYZ tstPnt; static _real x = pBoxInf.X(); x += stpX; tstPnt.SetX(x); _real y = pBoxInf.Y(); for (_int j = 1; j <= nbY; ++j){ y += stpY; tstPnt.SetY(y); _real z = pBoxInf.Z(); for (_int k = 1; k <= nbZ; ++k){ z += stpZ; tstPnt.SetZ(z); solidClsf.Perform(tstPnt, Precision::Confusion()); if (solidClsf.State() == TopAbs_IN) pointsInsidePart.push_back(tstPnt); } } status.clear(); status += std::to_string(i*nbY*nbZ).c_str(); status += " / "; status += std::to_string(amount).c_str(); status += "T: "; status += timer.WhatTime().c_str(); mainWindow->SetStatus(status); } inPointsAMount += (_int) pointsInsidePart.size(); } timer.Stop(); _real speed = fullAmount / timer.Seconds(); QString status = std::to_string(inPointsAMount).c_str(); status += " / "; status += std::to_string(fullAmount).c_str(); status += " on speed = "; status += std::to_string(speed).c_str(); mainWindow->SetStatus(status); }
//======================================================================= //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; }