mirror of
https://git.salome-platform.org/gitpub/modules/geom.git
synced 2024-12-24 08:20:35 +05:00
0021866: [CEA 670] Returning exact coordinates of the bounding box
This commit is contained in:
parent
18129b41a4
commit
e6a58b5819
@ -14,9 +14,10 @@ faces (by iterating through all faces of a shape).
|
||||
This functionallity is implemented in such a way to have
|
||||
a satisfactory performance.
|
||||
|
||||
\n <b>TUI Commands:</b> <em>[Xmin,Xmax, Ymin,Ymax, Zmin,Zmax] = geompy.BoundingBox(Shape)</em>,
|
||||
<em>BBox = geompy.MakeBoundingBox(Shape)</em>, where \em Shape
|
||||
is the shape for which the bounding box is computed.
|
||||
\n <b>TUI Commands:</b> <em>[Xmin,Xmax, Ymin,Ymax, Zmin,Zmax] = geompy.BoundingBox(Shape, precise)</em>,
|
||||
<em>BBox = geompy.MakeBoundingBox(Shape, precise)</em>, where \em Shape
|
||||
is the shape for which the bounding box is computed. \em precise TRUE
|
||||
for precise computation; FALSE for fast one. Default value is False.
|
||||
|
||||
See also a \ref tui_bounding_box_page "TUI example".
|
||||
|
||||
|
@ -3640,12 +3640,14 @@ module GEOM
|
||||
/*!
|
||||
* \brief Get parameters of bounding box of the given shape
|
||||
* \param theShape Shape to obtain bounding box of.
|
||||
* \param precise TRUE for precise computation; FALSE for fast one.
|
||||
* \param Xmin,Xmax Output. Limits of shape along OX axis.
|
||||
* \param Ymin,Ymax Output. Limits of shape along OY axis.
|
||||
* \param Zmin,Zmax Output. Limits of shape along OZ axis.
|
||||
* \return Returns parameters of bounding box through the last six arguments.
|
||||
*/
|
||||
void GetBoundingBox (in GEOM_Object theShape,
|
||||
in boolean precise,
|
||||
out double Xmin, out double Xmax,
|
||||
out double Ymin, out double Ymax,
|
||||
out double Zmin, out double Zmax);
|
||||
@ -3653,9 +3655,11 @@ module GEOM
|
||||
/*!
|
||||
* \brief Get bounding box of the given shape
|
||||
* \param theShape Shape to obtain bounding box of.
|
||||
* \param precise TRUE for precise computation; FALSE for fast one.
|
||||
* \return New GEOM_Object, containing the created bounding box.
|
||||
*/
|
||||
GEOM_Object MakeBoundingBox (in GEOM_Object theShape);
|
||||
GEOM_Object MakeBoundingBox (in GEOM_Object theShape,
|
||||
in boolean precise);
|
||||
|
||||
/*!
|
||||
* \brief Get min and max tolerances of sub-shapes of theShape
|
||||
|
@ -91,27 +91,14 @@
|
||||
|
||||
#include <ShapeAnalysis.hxx>
|
||||
#include <ShapeAnalysis_Surface.hxx>
|
||||
#include <ShapeFix_Shape.hxx>
|
||||
|
||||
#include <GeomAPI_IntSS.hxx>
|
||||
#include <GeomAPI_ProjectPointOnCurve.hxx>
|
||||
|
||||
#include <GeomAbs_SurfaceType.hxx>
|
||||
|
||||
#include <Geom_BezierSurface.hxx>
|
||||
#include <Geom_BSplineSurface.hxx>
|
||||
#include <Geom_Circle.hxx>
|
||||
#include <Geom_ConicalSurface.hxx>
|
||||
#include <Geom_CylindricalSurface.hxx>
|
||||
#include <Geom_Line.hxx>
|
||||
#include <Geom_OffsetSurface.hxx>
|
||||
#include <Geom_Plane.hxx>
|
||||
#include <Geom_RectangularTrimmedSurface.hxx>
|
||||
#include <Geom_SphericalSurface.hxx>
|
||||
#include <Geom_Surface.hxx>
|
||||
#include <Geom_SurfaceOfLinearExtrusion.hxx>
|
||||
#include <Geom_SurfaceOfRevolution.hxx>
|
||||
#include <Geom_ToroidalSurface.hxx>
|
||||
|
||||
#include <GeomLProp_CLProps.hxx>
|
||||
#include <GeomLProp_SLProps.hxx>
|
||||
@ -1120,6 +1107,7 @@ void GEOMImpl_IMeasureOperations::GetInertia
|
||||
//=============================================================================
|
||||
void GEOMImpl_IMeasureOperations::GetBoundingBox
|
||||
(Handle(GEOM_Object) theShape,
|
||||
const Standard_Boolean precise,
|
||||
Standard_Real& Xmin, Standard_Real& Xmax,
|
||||
Standard_Real& Ymin, Standard_Real& Ymax,
|
||||
Standard_Real& Zmin, Standard_Real& Zmax)
|
||||
@ -1156,6 +1144,14 @@ void GEOMImpl_IMeasureOperations::GetBoundingBox
|
||||
BRepTools::Clean(aShape);
|
||||
|
||||
BRepBndLib::Add(aShape, B);
|
||||
|
||||
if (precise) {
|
||||
if (!GEOMUtils::PreciseBoundingBox(aShape, B)) {
|
||||
SetErrorCode("GetBoundingBox Error: Bounding box cannot be precised");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
@ -1173,7 +1169,8 @@ void GEOMImpl_IMeasureOperations::GetBoundingBox
|
||||
*/
|
||||
//=============================================================================
|
||||
Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetBoundingBox
|
||||
(Handle(GEOM_Object) theShape)
|
||||
(Handle(GEOM_Object) theShape,
|
||||
const Standard_Boolean precise)
|
||||
{
|
||||
SetErrorCode(KO);
|
||||
|
||||
@ -1183,8 +1180,9 @@ Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetBoundingBox
|
||||
Handle(GEOM_Object) aBnd = GetEngine()->AddObject(GetDocID(), GEOM_BOX);
|
||||
|
||||
//Add a new BoundingBox function
|
||||
const int aType = (precise ? BND_BOX_MEASURE_PRECISE : BND_BOX_MEASURE);
|
||||
Handle(GEOM_Function) aFunction =
|
||||
aBnd->AddFunction(GEOMImpl_MeasureDriver::GetID(), BND_BOX_MEASURE);
|
||||
aBnd->AddFunction(GEOMImpl_MeasureDriver::GetID(), aType);
|
||||
if (aFunction.IsNull()) return NULL;
|
||||
|
||||
//Check if the function is set correctly
|
||||
@ -1214,7 +1212,15 @@ Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetBoundingBox
|
||||
}
|
||||
|
||||
//Make a Python command
|
||||
GEOM::TPythonDump(aFunction) << aBnd << " = geompy.MakeBoundingBox(" << theShape << ")";
|
||||
GEOM::TPythonDump aPd(aFunction);
|
||||
|
||||
aPd << aBnd << " = geompy.MakeBoundingBox(" << theShape;
|
||||
|
||||
if (precise) {
|
||||
aPd << ", True";
|
||||
}
|
||||
|
||||
aPd << ")";
|
||||
|
||||
SetErrorCode(OK);
|
||||
return aBnd;
|
||||
@ -1584,308 +1590,6 @@ std::vector<bool> GEOMImpl_IMeasureOperations::AreCoordsInside(Handle(GEOM_Objec
|
||||
return res;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : CheckSingularCase
|
||||
//purpose : auxilary for GetMinDistance()
|
||||
// workaround for bugs 19899, 19908 and 19910 from Mantis
|
||||
//=======================================================================
|
||||
static double CheckSingularCase(const TopoDS_Shape& aSh1,
|
||||
const TopoDS_Shape& aSh2,
|
||||
gp_Pnt& Ptmp1, gp_Pnt& Ptmp2)
|
||||
{
|
||||
bool IsChange1 = false;
|
||||
double AddDist1 = 0.0;
|
||||
TopExp_Explorer anExp;
|
||||
TopoDS_Shape tmpSh1, tmpSh2;
|
||||
int nbf = 0;
|
||||
for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
|
||||
nbf++;
|
||||
tmpSh1 = anExp.Current();
|
||||
}
|
||||
if(nbf==1) {
|
||||
TopoDS_Shape sh = aSh1;
|
||||
while(sh.ShapeType()==TopAbs_COMPOUND) {
|
||||
TopoDS_Iterator it(sh);
|
||||
sh = it.Value();
|
||||
}
|
||||
Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(tmpSh1));
|
||||
if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
|
||||
S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
|
||||
if( sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE ) {
|
||||
// non solid case
|
||||
double U1,U2,V1,V2;
|
||||
// changes for 0020677: EDF 1219 GEOM: MinDistance gives 0 instead of 20.88
|
||||
//S->Bounds(U1,U2,V1,V2); changed by
|
||||
ShapeAnalysis::GetFaceUVBounds(TopoDS::Face(tmpSh1),U1,U2,V1,V2);
|
||||
// end of changes for 020677 (dmv)
|
||||
Handle(Geom_RectangularTrimmedSurface) TrS1 =
|
||||
new Geom_RectangularTrimmedSurface(S,U1,(U1+U2)/2.,V1,V2);
|
||||
Handle(Geom_RectangularTrimmedSurface) TrS2 =
|
||||
new Geom_RectangularTrimmedSurface(S,(U1+U2)/2.,U2,V1,V2);
|
||||
BRep_Builder B;
|
||||
TopoDS_Face F1,F2;
|
||||
TopoDS_Compound Comp;
|
||||
B.MakeCompound(Comp);
|
||||
B.MakeFace(F1,TrS1,1.e-7);
|
||||
B.Add(Comp,F1);
|
||||
B.MakeFace(F2,TrS2,1.e-7);
|
||||
B.Add(Comp,F2);
|
||||
Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
|
||||
sfs->Init(Comp);
|
||||
sfs->SetPrecision(1.e-6);
|
||||
sfs->SetMaxTolerance(1.0);
|
||||
sfs->Perform();
|
||||
tmpSh1 = sfs->Shape();
|
||||
IsChange1 = true;
|
||||
}
|
||||
else {
|
||||
if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) {
|
||||
Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(S);
|
||||
gp_Pnt PC = SS->Location();
|
||||
BRep_Builder B;
|
||||
TopoDS_Vertex V;
|
||||
B.MakeVertex(V,PC,1.e-7);
|
||||
tmpSh1 = V;
|
||||
AddDist1 = SS->Radius();
|
||||
IsChange1 = true;
|
||||
}
|
||||
else {
|
||||
Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(S);
|
||||
gp_Ax3 ax3 = TS->Position();
|
||||
Handle(Geom_Circle) C = new Geom_Circle(ax3.Ax2(),TS->MajorRadius());
|
||||
BRep_Builder B;
|
||||
TopoDS_Edge E;
|
||||
B.MakeEdge(E,C,1.e-7);
|
||||
tmpSh1 = E;
|
||||
AddDist1 = TS->MinorRadius();
|
||||
IsChange1 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
tmpSh1 = aSh1;
|
||||
}
|
||||
else
|
||||
tmpSh1 = aSh1;
|
||||
bool IsChange2 = false;
|
||||
double AddDist2 = 0.0;
|
||||
nbf = 0;
|
||||
for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
|
||||
nbf++;
|
||||
tmpSh2 = anExp.Current();
|
||||
}
|
||||
if(nbf==1) {
|
||||
TopoDS_Shape sh = aSh2;
|
||||
while(sh.ShapeType()==TopAbs_COMPOUND) {
|
||||
TopoDS_Iterator it(sh);
|
||||
sh = it.Value();
|
||||
}
|
||||
Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(tmpSh2));
|
||||
if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
|
||||
S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
|
||||
if( sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE ) {
|
||||
// non solid case
|
||||
double U1,U2,V1,V2;
|
||||
//S->Bounds(U1,U2,V1,V2);
|
||||
ShapeAnalysis::GetFaceUVBounds(TopoDS::Face(tmpSh2),U1,U2,V1,V2);
|
||||
Handle(Geom_RectangularTrimmedSurface) TrS1 =
|
||||
new Geom_RectangularTrimmedSurface(S,U1,(U1+U2)/2.,V1,V2);
|
||||
Handle(Geom_RectangularTrimmedSurface) TrS2 =
|
||||
new Geom_RectangularTrimmedSurface(S,(U1+U2)/2.,U2,V1,V2);
|
||||
BRep_Builder B;
|
||||
TopoDS_Face F1,F2;
|
||||
TopoDS_Compound Comp;
|
||||
B.MakeCompound(Comp);
|
||||
B.MakeFace(F1,TrS1,1.e-7);
|
||||
B.Add(Comp,F1);
|
||||
B.MakeFace(F2,TrS2,1.e-7);
|
||||
B.Add(Comp,F2);
|
||||
Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
|
||||
sfs->Init(Comp);
|
||||
sfs->SetPrecision(1.e-6);
|
||||
sfs->SetMaxTolerance(1.0);
|
||||
sfs->Perform();
|
||||
tmpSh2 = sfs->Shape();
|
||||
IsChange2 = true;
|
||||
}
|
||||
else {
|
||||
if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) {
|
||||
Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(S);
|
||||
gp_Pnt PC = SS->Location();
|
||||
BRep_Builder B;
|
||||
TopoDS_Vertex V;
|
||||
B.MakeVertex(V,PC,1.e-7);
|
||||
tmpSh2 = V;
|
||||
AddDist2 = SS->Radius();
|
||||
IsChange2 = true;
|
||||
}
|
||||
else if( S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
|
||||
Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(S);
|
||||
gp_Ax3 ax3 = TS->Position();
|
||||
Handle(Geom_Circle) C = new Geom_Circle(ax3.Ax2(),TS->MajorRadius());
|
||||
BRep_Builder B;
|
||||
TopoDS_Edge E;
|
||||
B.MakeEdge(E,C,1.e-7);
|
||||
tmpSh2 = E;
|
||||
AddDist2 = TS->MinorRadius();
|
||||
IsChange2 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
tmpSh2 = aSh2;
|
||||
}
|
||||
else
|
||||
tmpSh2 = aSh2;
|
||||
|
||||
if( !IsChange1 && !IsChange2 )
|
||||
return -2.0;
|
||||
|
||||
BRepExtrema_DistShapeShape dst(tmpSh1,tmpSh2);
|
||||
if (dst.IsDone()) {
|
||||
double MinDist = 1.e9;
|
||||
gp_Pnt PMin1, PMin2, P1, P2;
|
||||
for (int i = 1; i <= dst.NbSolution(); i++) {
|
||||
P1 = dst.PointOnShape1(i);
|
||||
P2 = dst.PointOnShape2(i);
|
||||
Standard_Real Dist = P1.Distance(P2);
|
||||
if (MinDist > Dist) {
|
||||
MinDist = Dist;
|
||||
PMin1 = P1;
|
||||
PMin2 = P2;
|
||||
}
|
||||
}
|
||||
if(MinDist<1.e-7) {
|
||||
Ptmp1 = PMin1;
|
||||
Ptmp2 = PMin2;
|
||||
}
|
||||
else {
|
||||
gp_Dir aDir(gp_Vec(PMin1,PMin2));
|
||||
if( MinDist > (AddDist1+AddDist2) ) {
|
||||
Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1,
|
||||
PMin1.Y() + aDir.Y()*AddDist1,
|
||||
PMin1.Z() + aDir.Z()*AddDist1 );
|
||||
Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2,
|
||||
PMin2.Y() - aDir.Y()*AddDist2,
|
||||
PMin2.Z() - aDir.Z()*AddDist2 );
|
||||
return (MinDist - AddDist1 - AddDist2);
|
||||
}
|
||||
else {
|
||||
if( AddDist1 > 0 ) {
|
||||
Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1,
|
||||
PMin1.Y() + aDir.Y()*AddDist1,
|
||||
PMin1.Z() + aDir.Z()*AddDist1 );
|
||||
Ptmp2 = Ptmp1;
|
||||
}
|
||||
else {
|
||||
Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2,
|
||||
PMin2.Y() - aDir.Y()*AddDist2,
|
||||
PMin2.Z() - aDir.Z()*AddDist2 );
|
||||
Ptmp1 = Ptmp2;
|
||||
}
|
||||
}
|
||||
}
|
||||
double res = MinDist - AddDist1 - AddDist2;
|
||||
if(res<0.) res = 0.0;
|
||||
return res;
|
||||
}
|
||||
return -2.0;
|
||||
}
|
||||
/* old variant
|
||||
static bool CheckSingularCase(const TopoDS_Shape& aSh1,
|
||||
const TopoDS_Shape& aSh2,
|
||||
gp_Pnt& Ptmp)
|
||||
{
|
||||
TopExp_Explorer anExp;
|
||||
TopoDS_Shape tmpSh1, tmpSh2;
|
||||
int nbf = 0;
|
||||
for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
|
||||
nbf++;
|
||||
tmpSh1 = anExp.Current();
|
||||
}
|
||||
if(nbf==1) {
|
||||
Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(tmpSh1));
|
||||
if( S1->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
|
||||
S1->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
|
||||
nbf = 0;
|
||||
for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
|
||||
nbf++;
|
||||
tmpSh2 = anExp.Current();
|
||||
Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(tmpSh2));
|
||||
GeomAPI_IntSS ISS(S1,S2,1.e-7);
|
||||
if(ISS.IsDone()) {
|
||||
for(int i=1; i<=ISS.NbLines(); i++) {
|
||||
Handle(Geom_Curve) C3d = ISS.Line(i);
|
||||
BRep_Builder B;
|
||||
TopoDS_Edge E;
|
||||
B.MakeEdge(E,C3d,1.e-7);
|
||||
BRepExtrema_DistShapeShape dst(tmpSh2,E);
|
||||
if (dst.IsDone()) {
|
||||
gp_Pnt PMin1, PMin2, P1, P2;
|
||||
double MinDist = 1.e9;
|
||||
for (int i = 1; i <= dst.NbSolution(); i++) {
|
||||
P1 = dst.PointOnShape1(i);
|
||||
P2 = dst.PointOnShape2(i);
|
||||
Standard_Real Dist = P1.Distance(P2);
|
||||
if (MinDist > Dist) {
|
||||
MinDist = Dist;
|
||||
Ptmp = P1;
|
||||
}
|
||||
}
|
||||
if(MinDist<1.e-7)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nbf = 0;
|
||||
for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
|
||||
nbf++;
|
||||
tmpSh1 = anExp.Current();
|
||||
}
|
||||
if(nbf==1) {
|
||||
Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(tmpSh1));
|
||||
if( S1->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
|
||||
S1->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
|
||||
nbf = 0;
|
||||
for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
|
||||
nbf++;
|
||||
tmpSh2 = anExp.Current();
|
||||
Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(tmpSh2));
|
||||
GeomAPI_IntSS ISS(S1,S2,1.e-7);
|
||||
if(ISS.IsDone()) {
|
||||
for(int i=1; i<=ISS.NbLines(); i++) {
|
||||
Handle(Geom_Curve) C3d = ISS.Line(i);
|
||||
BRep_Builder B;
|
||||
TopoDS_Edge E;
|
||||
B.MakeEdge(E,C3d,1.e-7);
|
||||
BRepExtrema_DistShapeShape dst(tmpSh2,E);
|
||||
if (dst.IsDone()) {
|
||||
gp_Pnt P1,P2;
|
||||
double MinDist = 1.e9;
|
||||
for (int i = 1; i <= dst.NbSolution(); i++) {
|
||||
P1 = dst.PointOnShape1(i);
|
||||
P2 = dst.PointOnShape2(i);
|
||||
Standard_Real Dist = P1.Distance(P2);
|
||||
if (MinDist > Dist) {
|
||||
MinDist = Dist;
|
||||
Ptmp = P1;
|
||||
}
|
||||
}
|
||||
if(MinDist<1.e-7)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* GetMinDistance
|
||||
@ -1918,63 +1622,15 @@ Standard_Real GEOMImpl_IMeasureOperations::GetMinDistance
|
||||
OCC_CATCH_SIGNALS;
|
||||
#endif
|
||||
|
||||
// Issue 0020231: A min distance bug with torus and vertex.
|
||||
// Make GetMinDistance() return zero if a sole VERTEX is inside any of SOLIDs
|
||||
gp_Pnt aPnt1, aPnt2;
|
||||
|
||||
// which of shapes consists of only one vertex?
|
||||
TopExp_Explorer exp1(aShape1,TopAbs_VERTEX), exp2(aShape2,TopAbs_VERTEX);
|
||||
TopoDS_Shape V1 = exp1.More() ? exp1.Current() : TopoDS_Shape();
|
||||
TopoDS_Shape V2 = exp2.More() ? exp2.Current() : TopoDS_Shape();
|
||||
exp1.Next(); exp2.Next();
|
||||
if ( exp1.More() ) V1.Nullify();
|
||||
if ( exp2.More() ) V2.Nullify();
|
||||
// vertex and container of solids
|
||||
TopoDS_Shape V = V1.IsNull() ? V2 : V1;
|
||||
TopoDS_Shape S = V1.IsNull() ? aShape1 : aShape2;
|
||||
if ( !V.IsNull() ) {
|
||||
// classify vertex against solids
|
||||
gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( V ) );
|
||||
for ( exp1.Init( S, TopAbs_SOLID ); exp1.More(); exp1.Next() ) {
|
||||
BRepClass3d_SolidClassifier classifier( exp1.Current(), p, 1e-6);
|
||||
if ( classifier.State() == TopAbs_IN ) {
|
||||
p.Coord(X1, Y1, Z1);
|
||||
p.Coord(X2, Y2, Z2);
|
||||
SetErrorCode(OK);
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// End Issue 0020231
|
||||
MinDist = GEOMUtils::GetMinDistance(aShape1, aShape2, aPnt1, aPnt2);
|
||||
|
||||
// skl 30.06.2008
|
||||
// additional workaround for bugs 19899, 19908 and 19910 from Mantis
|
||||
gp_Pnt Ptmp1, Ptmp2;
|
||||
double dist = CheckSingularCase(aShape1, aShape2, Ptmp1, Ptmp2);
|
||||
if (dist > -1.0) {
|
||||
Ptmp1.Coord(X1, Y1, Z1);
|
||||
Ptmp2.Coord(X2, Y2, Z2);
|
||||
SetErrorCode(OK);
|
||||
return dist;
|
||||
}
|
||||
|
||||
BRepExtrema_DistShapeShape dst (aShape1, aShape2);
|
||||
if (dst.IsDone()) {
|
||||
gp_Pnt PMin1, PMin2, P1, P2;
|
||||
|
||||
for (int i = 1; i <= dst.NbSolution(); i++) {
|
||||
P1 = dst.PointOnShape1(i);
|
||||
P2 = dst.PointOnShape2(i);
|
||||
|
||||
Standard_Real Dist = P1.Distance(P2);
|
||||
if (MinDist > Dist) {
|
||||
MinDist = Dist;
|
||||
PMin1 = P1;
|
||||
PMin2 = P2;
|
||||
}
|
||||
}
|
||||
|
||||
PMin1.Coord(X1, Y1, Z1);
|
||||
PMin2.Coord(X2, Y2, Z2);
|
||||
if (MinDist >= 0.0) {
|
||||
aPnt1.Coord(X1, Y1, Z1);
|
||||
aPnt2.Coord(X2, Y2, Z2);
|
||||
} else {
|
||||
return MinDist;
|
||||
}
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
@ -2021,7 +1677,7 @@ Standard_Integer GEOMImpl_IMeasureOperations::ClosestPoints (Handle(GEOM_Object)
|
||||
// skl 30.06.2008
|
||||
// additional workaround for bugs 19899, 19908 and 19910 from Mantis
|
||||
gp_Pnt P1, P2;
|
||||
double dist = CheckSingularCase(aShape1, aShape2, P1, P2);
|
||||
double dist = GEOMUtils::GetMinDistanceSingular(aShape1, aShape2, P1, P2);
|
||||
if (dist > -1.0) {
|
||||
nbSolutions = 1;
|
||||
|
||||
|
@ -114,11 +114,13 @@ class GEOMImpl_IMeasureOperations : public GEOM_IOperations {
|
||||
Standard_Real& Ix , Standard_Real& Iy , Standard_Real& Iz);
|
||||
|
||||
Standard_EXPORT void GetBoundingBox (Handle(GEOM_Object) theShape,
|
||||
const Standard_Boolean precise,
|
||||
Standard_Real& Xmin, Standard_Real& Xmax,
|
||||
Standard_Real& Ymin, Standard_Real& Ymax,
|
||||
Standard_Real& Zmin, Standard_Real& Zmax);
|
||||
|
||||
Standard_EXPORT Handle(GEOM_Object) GetBoundingBox (Handle(GEOM_Object) theShape);
|
||||
Standard_EXPORT Handle(GEOM_Object) GetBoundingBox (Handle(GEOM_Object) theShape,
|
||||
const Standard_Boolean precise);
|
||||
|
||||
Standard_EXPORT void GetTolerance (Handle(GEOM_Object) theShape,
|
||||
Standard_Real& FaceMin, Standard_Real& FaceMax,
|
||||
|
@ -105,7 +105,7 @@ Standard_Integer GEOMImpl_MeasureDriver::Execute(TFunction_Logbook& log) const
|
||||
gp_Pnt aCenterMass = aPos.Location();
|
||||
aShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
|
||||
}
|
||||
else if (aType == BND_BOX_MEASURE)
|
||||
else if (aType == BND_BOX_MEASURE || aType == BND_BOX_MEASURE_PRECISE)
|
||||
{
|
||||
Handle(GEOM_Function) aRefBase = aCI.GetBase();
|
||||
TopoDS_Shape aShapeBase = aRefBase->GetValue();
|
||||
@ -124,6 +124,12 @@ Standard_Integer GEOMImpl_MeasureDriver::Execute(TFunction_Logbook& log) const
|
||||
Bnd_Box B;
|
||||
BRepBndLib::Add(aShapeBase, B);
|
||||
|
||||
if (aType == BND_BOX_MEASURE_PRECISE) {
|
||||
if (!GEOMUtils::PreciseBoundingBox(aShapeBase, B)) {
|
||||
Standard_NullObject::Raise("Bounding box cannot be precised");
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
|
||||
B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
|
||||
|
||||
|
@ -319,6 +319,7 @@
|
||||
// Measures
|
||||
#define CDG_MEASURE 1
|
||||
#define BND_BOX_MEASURE 2
|
||||
#define BND_BOX_MEASURE_PRECISE 3
|
||||
#define VECTOR_FACE_NORMALE 4
|
||||
#define VERTEX_BY_INDEX 5
|
||||
|
||||
|
@ -41,6 +41,10 @@
|
||||
#include <BRepGProp.hxx>
|
||||
#include <BRepTools.hxx>
|
||||
|
||||
#include <BRepClass3d_SolidClassifier.hxx>
|
||||
|
||||
#include <BRepBuilderAPI_MakeFace.hxx>
|
||||
|
||||
#include <Bnd_Box.hxx>
|
||||
|
||||
#include <TopAbs.hxx>
|
||||
@ -58,8 +62,12 @@
|
||||
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
||||
#include <TopTools_Array1OfShape.hxx>
|
||||
|
||||
#include <Geom_Circle.hxx>
|
||||
#include <Geom_Surface.hxx>
|
||||
#include <Geom_Plane.hxx>
|
||||
#include <Geom_SphericalSurface.hxx>
|
||||
#include <Geom_ToroidalSurface.hxx>
|
||||
#include <Geom_RectangularTrimmedSurface.hxx>
|
||||
|
||||
#include <GeomLProp_CLProps.hxx>
|
||||
#include <GeomLProp_SLProps.hxx>
|
||||
@ -72,6 +80,9 @@
|
||||
#include <gp_Pln.hxx>
|
||||
#include <gp_Lin.hxx>
|
||||
|
||||
#include <ShapeAnalysis.hxx>
|
||||
#include <ShapeFix_Shape.hxx>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <Standard_Failure.hxx>
|
||||
@ -600,3 +611,343 @@ TopoDS_Shape GEOMUtils::GetEdgeNearPoint (const TopoDS_Shape& theShape,
|
||||
|
||||
return aResult;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : PreciseBoundingBox
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean GEOMUtils::PreciseBoundingBox
|
||||
(const TopoDS_Shape &theShape, Bnd_Box &theBox)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : GetMinDistanceSingular
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
double GEOMUtils::GetMinDistanceSingular(const TopoDS_Shape& aSh1,
|
||||
const TopoDS_Shape& aSh2,
|
||||
gp_Pnt& Ptmp1, gp_Pnt& Ptmp2)
|
||||
{
|
||||
bool IsChange1 = false;
|
||||
double AddDist1 = 0.0;
|
||||
TopExp_Explorer anExp;
|
||||
TopoDS_Shape tmpSh1, tmpSh2;
|
||||
int nbf = 0;
|
||||
for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
|
||||
nbf++;
|
||||
tmpSh1 = anExp.Current();
|
||||
}
|
||||
if(nbf==1) {
|
||||
TopoDS_Shape sh = aSh1;
|
||||
while(sh.ShapeType()==TopAbs_COMPOUND) {
|
||||
TopoDS_Iterator it(sh);
|
||||
sh = it.Value();
|
||||
}
|
||||
Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(tmpSh1));
|
||||
if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
|
||||
S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
|
||||
if( sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE ) {
|
||||
// non solid case
|
||||
double U1,U2,V1,V2;
|
||||
// changes for 0020677: EDF 1219 GEOM: MinDistance gives 0 instead of 20.88
|
||||
//S->Bounds(U1,U2,V1,V2); changed by
|
||||
ShapeAnalysis::GetFaceUVBounds(TopoDS::Face(tmpSh1),U1,U2,V1,V2);
|
||||
// end of changes for 020677 (dmv)
|
||||
Handle(Geom_RectangularTrimmedSurface) TrS1 =
|
||||
new Geom_RectangularTrimmedSurface(S,U1,(U1+U2)/2.,V1,V2);
|
||||
Handle(Geom_RectangularTrimmedSurface) TrS2 =
|
||||
new Geom_RectangularTrimmedSurface(S,(U1+U2)/2.,U2,V1,V2);
|
||||
BRep_Builder B;
|
||||
TopoDS_Face F1,F2;
|
||||
TopoDS_Compound Comp;
|
||||
B.MakeCompound(Comp);
|
||||
B.MakeFace(F1,TrS1,1.e-7);
|
||||
B.Add(Comp,F1);
|
||||
B.MakeFace(F2,TrS2,1.e-7);
|
||||
B.Add(Comp,F2);
|
||||
Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
|
||||
sfs->Init(Comp);
|
||||
sfs->SetPrecision(1.e-6);
|
||||
sfs->SetMaxTolerance(1.0);
|
||||
sfs->Perform();
|
||||
tmpSh1 = sfs->Shape();
|
||||
IsChange1 = true;
|
||||
}
|
||||
else {
|
||||
if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) {
|
||||
Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(S);
|
||||
gp_Pnt PC = SS->Location();
|
||||
BRep_Builder B;
|
||||
TopoDS_Vertex V;
|
||||
B.MakeVertex(V,PC,1.e-7);
|
||||
tmpSh1 = V;
|
||||
AddDist1 = SS->Radius();
|
||||
IsChange1 = true;
|
||||
}
|
||||
else {
|
||||
Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(S);
|
||||
gp_Ax3 ax3 = TS->Position();
|
||||
Handle(Geom_Circle) C = new Geom_Circle(ax3.Ax2(),TS->MajorRadius());
|
||||
BRep_Builder B;
|
||||
TopoDS_Edge E;
|
||||
B.MakeEdge(E,C,1.e-7);
|
||||
tmpSh1 = E;
|
||||
AddDist1 = TS->MinorRadius();
|
||||
IsChange1 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
tmpSh1 = aSh1;
|
||||
}
|
||||
else
|
||||
tmpSh1 = aSh1;
|
||||
bool IsChange2 = false;
|
||||
double AddDist2 = 0.0;
|
||||
nbf = 0;
|
||||
for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
|
||||
nbf++;
|
||||
tmpSh2 = anExp.Current();
|
||||
}
|
||||
if(nbf==1) {
|
||||
TopoDS_Shape sh = aSh2;
|
||||
while(sh.ShapeType()==TopAbs_COMPOUND) {
|
||||
TopoDS_Iterator it(sh);
|
||||
sh = it.Value();
|
||||
}
|
||||
Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(tmpSh2));
|
||||
if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
|
||||
S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
|
||||
if( sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE ) {
|
||||
// non solid case
|
||||
double U1,U2,V1,V2;
|
||||
//S->Bounds(U1,U2,V1,V2);
|
||||
ShapeAnalysis::GetFaceUVBounds(TopoDS::Face(tmpSh2),U1,U2,V1,V2);
|
||||
Handle(Geom_RectangularTrimmedSurface) TrS1 =
|
||||
new Geom_RectangularTrimmedSurface(S,U1,(U1+U2)/2.,V1,V2);
|
||||
Handle(Geom_RectangularTrimmedSurface) TrS2 =
|
||||
new Geom_RectangularTrimmedSurface(S,(U1+U2)/2.,U2,V1,V2);
|
||||
BRep_Builder B;
|
||||
TopoDS_Face F1,F2;
|
||||
TopoDS_Compound Comp;
|
||||
B.MakeCompound(Comp);
|
||||
B.MakeFace(F1,TrS1,1.e-7);
|
||||
B.Add(Comp,F1);
|
||||
B.MakeFace(F2,TrS2,1.e-7);
|
||||
B.Add(Comp,F2);
|
||||
Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
|
||||
sfs->Init(Comp);
|
||||
sfs->SetPrecision(1.e-6);
|
||||
sfs->SetMaxTolerance(1.0);
|
||||
sfs->Perform();
|
||||
tmpSh2 = sfs->Shape();
|
||||
IsChange2 = true;
|
||||
}
|
||||
else {
|
||||
if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) {
|
||||
Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(S);
|
||||
gp_Pnt PC = SS->Location();
|
||||
BRep_Builder B;
|
||||
TopoDS_Vertex V;
|
||||
B.MakeVertex(V,PC,1.e-7);
|
||||
tmpSh2 = V;
|
||||
AddDist2 = SS->Radius();
|
||||
IsChange2 = true;
|
||||
}
|
||||
else if( S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
|
||||
Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(S);
|
||||
gp_Ax3 ax3 = TS->Position();
|
||||
Handle(Geom_Circle) C = new Geom_Circle(ax3.Ax2(),TS->MajorRadius());
|
||||
BRep_Builder B;
|
||||
TopoDS_Edge E;
|
||||
B.MakeEdge(E,C,1.e-7);
|
||||
tmpSh2 = E;
|
||||
AddDist2 = TS->MinorRadius();
|
||||
IsChange2 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
tmpSh2 = aSh2;
|
||||
}
|
||||
else
|
||||
tmpSh2 = aSh2;
|
||||
|
||||
if( !IsChange1 && !IsChange2 )
|
||||
return -2.0;
|
||||
|
||||
BRepExtrema_DistShapeShape dst(tmpSh1,tmpSh2);
|
||||
if (dst.IsDone()) {
|
||||
double MinDist = 1.e9;
|
||||
gp_Pnt PMin1, PMin2, P1, P2;
|
||||
for (int i = 1; i <= dst.NbSolution(); i++) {
|
||||
P1 = dst.PointOnShape1(i);
|
||||
P2 = dst.PointOnShape2(i);
|
||||
Standard_Real Dist = P1.Distance(P2);
|
||||
if (MinDist > Dist) {
|
||||
MinDist = Dist;
|
||||
PMin1 = P1;
|
||||
PMin2 = P2;
|
||||
}
|
||||
}
|
||||
if(MinDist<1.e-7) {
|
||||
Ptmp1 = PMin1;
|
||||
Ptmp2 = PMin2;
|
||||
}
|
||||
else {
|
||||
gp_Dir aDir(gp_Vec(PMin1,PMin2));
|
||||
if( MinDist > (AddDist1+AddDist2) ) {
|
||||
Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1,
|
||||
PMin1.Y() + aDir.Y()*AddDist1,
|
||||
PMin1.Z() + aDir.Z()*AddDist1 );
|
||||
Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2,
|
||||
PMin2.Y() - aDir.Y()*AddDist2,
|
||||
PMin2.Z() - aDir.Z()*AddDist2 );
|
||||
return (MinDist - AddDist1 - AddDist2);
|
||||
}
|
||||
else {
|
||||
if( AddDist1 > 0 ) {
|
||||
Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1,
|
||||
PMin1.Y() + aDir.Y()*AddDist1,
|
||||
PMin1.Z() + aDir.Z()*AddDist1 );
|
||||
Ptmp2 = Ptmp1;
|
||||
}
|
||||
else {
|
||||
Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2,
|
||||
PMin2.Y() - aDir.Y()*AddDist2,
|
||||
PMin2.Z() - aDir.Z()*AddDist2 );
|
||||
Ptmp1 = Ptmp2;
|
||||
}
|
||||
}
|
||||
}
|
||||
double res = MinDist - AddDist1 - AddDist2;
|
||||
if(res<0.) res = 0.0;
|
||||
return res;
|
||||
}
|
||||
return -2.0;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : GetMinDistance
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Real GEOMUtils::GetMinDistance
|
||||
(const TopoDS_Shape& theShape1,
|
||||
const TopoDS_Shape& theShape2,
|
||||
gp_Pnt& thePnt1, gp_Pnt& thePnt2)
|
||||
{
|
||||
Standard_Real aResult = 1.e9;
|
||||
|
||||
// Issue 0020231: A min distance bug with torus and vertex.
|
||||
// Make GetMinDistance() return zero if a sole VERTEX is inside any of SOLIDs
|
||||
|
||||
// which of shapes consists of only one vertex?
|
||||
TopExp_Explorer exp1(theShape1,TopAbs_VERTEX), exp2(theShape2,TopAbs_VERTEX);
|
||||
TopoDS_Shape V1 = exp1.More() ? exp1.Current() : TopoDS_Shape();
|
||||
TopoDS_Shape V2 = exp2.More() ? exp2.Current() : TopoDS_Shape();
|
||||
exp1.Next(); exp2.Next();
|
||||
if ( exp1.More() ) V1.Nullify();
|
||||
if ( exp2.More() ) V2.Nullify();
|
||||
// vertex and container of solids
|
||||
TopoDS_Shape V = V1.IsNull() ? V2 : V1;
|
||||
TopoDS_Shape S = V1.IsNull() ? theShape1 : theShape2;
|
||||
if ( !V.IsNull() ) {
|
||||
// classify vertex against solids
|
||||
gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( V ) );
|
||||
for ( exp1.Init( S, TopAbs_SOLID ); exp1.More(); exp1.Next() ) {
|
||||
BRepClass3d_SolidClassifier classifier( exp1.Current(), p, 1e-6);
|
||||
if ( classifier.State() == TopAbs_IN ) {
|
||||
thePnt1 = p;
|
||||
thePnt2 = p;
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// End Issue 0020231
|
||||
|
||||
// skl 30.06.2008
|
||||
// additional workaround for bugs 19899, 19908 and 19910 from Mantis
|
||||
double dist = GEOMUtils::GetMinDistanceSingular
|
||||
(theShape1, theShape2, thePnt1, thePnt2);
|
||||
|
||||
if (dist > -1.0) {
|
||||
return dist;
|
||||
}
|
||||
|
||||
BRepExtrema_DistShapeShape dst (theShape1, theShape2);
|
||||
if (dst.IsDone()) {
|
||||
gp_Pnt P1, P2;
|
||||
|
||||
for (int i = 1; i <= dst.NbSolution(); i++) {
|
||||
P1 = dst.PointOnShape1(i);
|
||||
P2 = dst.PointOnShape2(i);
|
||||
|
||||
Standard_Real Dist = P1.Distance(P2);
|
||||
if (aResult > Dist) {
|
||||
aResult = Dist;
|
||||
thePnt1 = P1;
|
||||
thePnt2 = P2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return aResult;
|
||||
}
|
||||
|
@ -37,6 +37,8 @@
|
||||
|
||||
#include <functional>
|
||||
|
||||
class Bnd_Box;
|
||||
|
||||
inline Standard_Boolean IsEqual (const TopoDS_Shape& S1, const TopoDS_Shape& S2)
|
||||
{
|
||||
return S1.IsSame(S2);
|
||||
@ -132,6 +134,45 @@ class GEOMUtils {
|
||||
Standard_EXPORT static TopoDS_Shape GetEdgeNearPoint (const TopoDS_Shape& theShape,
|
||||
const TopoDS_Vertex& thePoint);
|
||||
|
||||
/*!
|
||||
* \brief Compute precise bounding box of the shape based on the rough bounding box.
|
||||
*
|
||||
* \param theShape the shape.
|
||||
* \param theBox rough bounding box on input; precise bounding box on output.
|
||||
* \retval Standard_True in case of success; Standard_False otherwise.
|
||||
*/
|
||||
Standard_EXPORT static Standard_Boolean PreciseBoundingBox
|
||||
(const TopoDS_Shape &theShape, Bnd_Box &theBox);
|
||||
|
||||
/*!
|
||||
* \brief Computes minumal distance between two shapes for singular cases
|
||||
* (workaround for bugs 19899, 19908 and 19910 from Mantis).
|
||||
*
|
||||
* \param aSh1 the first shape
|
||||
* \param aSh2 the second shape
|
||||
* \param Ptmp1 the output result point on the first shape
|
||||
* \param Ptmp2 the output result point on the second shape
|
||||
* \retval negative value if it is not a singular case; actual distance for singular case.
|
||||
*/
|
||||
Standard_EXPORT static Standard_Real GetMinDistanceSingular
|
||||
(const TopoDS_Shape& aSh1,
|
||||
const TopoDS_Shape& aSh2,
|
||||
gp_Pnt& Ptmp1, gp_Pnt& Ptmp2);
|
||||
|
||||
/*!
|
||||
* \brief Computes minumal distance between two shapes.
|
||||
*
|
||||
* \param theShape1 the first shape
|
||||
* \param theShape2 the second shape
|
||||
* \param thePnt1 the output result point on the first shape
|
||||
* \param thePnt2 the output result point on the second shape
|
||||
* \retval negative value in case of failure; otherwise the real distance.
|
||||
*/
|
||||
Standard_EXPORT static Standard_Real GetMinDistance
|
||||
(const TopoDS_Shape& theShape1,
|
||||
const TopoDS_Shape& theShape2,
|
||||
gp_Pnt& thePnt1, gp_Pnt& thePnt2);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -258,6 +258,7 @@ void GEOM_IMeasureOperations_i::GetInertia
|
||||
*/
|
||||
//=============================================================================
|
||||
void GEOM_IMeasureOperations_i::GetBoundingBox (GEOM::GEOM_Object_ptr theShape,
|
||||
CORBA::Boolean precise,
|
||||
CORBA::Double& Xmin, CORBA::Double& Xmax,
|
||||
CORBA::Double& Ymin, CORBA::Double& Ymax,
|
||||
CORBA::Double& Zmin, CORBA::Double& Zmax)
|
||||
@ -270,7 +271,8 @@ void GEOM_IMeasureOperations_i::GetBoundingBox (GEOM::GEOM_Object_ptr theShape,
|
||||
if (aShape.IsNull()) return;
|
||||
|
||||
// Get shape parameters
|
||||
GetOperations()->GetBoundingBox(aShape, Xmin, Xmax, Ymin, Ymax, Zmin, Zmax);
|
||||
GetOperations()->GetBoundingBox
|
||||
(aShape, precise, Xmin, Xmax, Ymin, Ymax, Zmin, Zmax);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
@ -279,7 +281,8 @@ void GEOM_IMeasureOperations_i::GetBoundingBox (GEOM::GEOM_Object_ptr theShape,
|
||||
*/
|
||||
//=============================================================================
|
||||
GEOM::GEOM_Object_ptr GEOM_IMeasureOperations_i::MakeBoundingBox
|
||||
(GEOM::GEOM_Object_ptr theShape)
|
||||
(GEOM::GEOM_Object_ptr theShape,
|
||||
CORBA::Boolean precise)
|
||||
{
|
||||
GEOM::GEOM_Object_var aGEOMObject;
|
||||
|
||||
@ -291,7 +294,8 @@ GEOM::GEOM_Object_ptr GEOM_IMeasureOperations_i::MakeBoundingBox
|
||||
if (aShape.IsNull()) return aGEOMObject._retn();
|
||||
|
||||
// Make Box - bounding box of theShape
|
||||
Handle(GEOM_Object) anObject = GetOperations()->GetBoundingBox(aShape);
|
||||
Handle(GEOM_Object) anObject =
|
||||
GetOperations()->GetBoundingBox(aShape, precise);
|
||||
if (!GetOperations()->IsDone() || anObject.IsNull())
|
||||
return aGEOMObject._retn();
|
||||
|
||||
|
@ -71,11 +71,13 @@ class GEOM_I_EXPORT GEOM_IMeasureOperations_i :
|
||||
CORBA::Double& Ix , CORBA::Double& Iy , CORBA::Double& Iz);
|
||||
|
||||
void GetBoundingBox (GEOM::GEOM_Object_ptr theShape,
|
||||
CORBA::Boolean precise,
|
||||
CORBA::Double& Xmin, CORBA::Double& Xmax,
|
||||
CORBA::Double& Ymin, CORBA::Double& Ymax,
|
||||
CORBA::Double& Zmin, CORBA::Double& Zmax);
|
||||
|
||||
GEOM::GEOM_Object_ptr MakeBoundingBox (GEOM::GEOM_Object_ptr theShape);
|
||||
GEOM::GEOM_Object_ptr MakeBoundingBox (GEOM::GEOM_Object_ptr theShape,
|
||||
CORBA::Boolean precise);
|
||||
|
||||
void GetTolerance (GEOM::GEOM_Object_ptr theShape,
|
||||
CORBA::Double& FaceMin, CORBA::Double& FaceMax,
|
||||
|
@ -9031,18 +9031,20 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
|
||||
|
||||
## Get parameters of bounding box of the given shape
|
||||
# @param theShape Shape to obtain bounding box of.
|
||||
# @param precise TRUE for precise computation; FALSE for fast one.
|
||||
# @return [Xmin,Xmax, Ymin,Ymax, Zmin,Zmax]
|
||||
# Xmin,Xmax: Limits of shape along OX axis.
|
||||
# Ymin,Ymax: Limits of shape along OY axis.
|
||||
# Zmin,Zmax: Limits of shape along OZ axis.
|
||||
#
|
||||
# @ref tui_measurement_tools_page "Example"
|
||||
def BoundingBox (self, theShape):
|
||||
def BoundingBox (self, theShape, precise=False):
|
||||
"""
|
||||
Get parameters of bounding box of the given shape
|
||||
|
||||
Parameters:
|
||||
theShape Shape to obtain bounding box of.
|
||||
precise TRUE for precise computation; FALSE for fast one.
|
||||
|
||||
Returns:
|
||||
[Xmin,Xmax, Ymin,Ymax, Zmin,Zmax]
|
||||
@ -9051,12 +9053,13 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
|
||||
Zmin,Zmax: Limits of shape along OZ axis.
|
||||
"""
|
||||
# Example: see GEOM_TestMeasures.py
|
||||
aTuple = self.MeasuOp.GetBoundingBox(theShape)
|
||||
aTuple = self.MeasuOp.GetBoundingBox(theShape, precise)
|
||||
RaiseIfFailed("GetBoundingBox", self.MeasuOp)
|
||||
return aTuple
|
||||
|
||||
## Get bounding box of the given shape
|
||||
# @param theShape Shape to obtain bounding box of.
|
||||
# @param precise TRUE for precise computation; FALSE for fast one.
|
||||
# @param theName Object name; when specified, this parameter is used
|
||||
# for result publication in the study. Otherwise, if automatic
|
||||
# publication is switched on, default value is used for result name.
|
||||
@ -9064,12 +9067,13 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
|
||||
# @return New GEOM.GEOM_Object, containing the created box.
|
||||
#
|
||||
# @ref tui_measurement_tools_page "Example"
|
||||
def MakeBoundingBox (self, theShape, theName=None):
|
||||
def MakeBoundingBox (self, theShape, precise=False, theName=None):
|
||||
"""
|
||||
Get bounding box of the given shape
|
||||
|
||||
Parameters:
|
||||
theShape Shape to obtain bounding box of.
|
||||
precise TRUE for precise computation; FALSE for fast one.
|
||||
theName Object name; when specified, this parameter is used
|
||||
for result publication in the study. Otherwise, if automatic
|
||||
publication is switched on, default value is used for result name.
|
||||
@ -9078,7 +9082,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
|
||||
New GEOM.GEOM_Object, containing the created box.
|
||||
"""
|
||||
# Example: see GEOM_TestMeasures.py
|
||||
anObj = self.MeasuOp.MakeBoundingBox(theShape)
|
||||
anObj = self.MeasuOp.MakeBoundingBox(theShape, precise)
|
||||
RaiseIfFailed("MakeBoundingBox", self.MeasuOp)
|
||||
self._autoPublish(anObj, theName, "bndbox")
|
||||
return anObj
|
||||
|
@ -220,7 +220,7 @@ bool MeasureGUI_BndBoxDlg::getParameters (double& theXmin, double& theXmax,
|
||||
return false;
|
||||
|
||||
GEOM::GEOM_IMeasureOperations_var anOper = GEOM::GEOM_IMeasureOperations::_narrow(getOperation());
|
||||
anOper->GetBoundingBox(myObj, theXmin, theXmax, theYmin, theYmax, theZmin, theZmax);
|
||||
anOper->GetBoundingBox(myObj, true, theXmin, theXmax, theYmin, theYmax, theZmin, theZmax);
|
||||
|
||||
return anOper->IsDone();
|
||||
}
|
||||
@ -300,7 +300,7 @@ bool MeasureGUI_BndBoxDlg::isValid (QString&)
|
||||
bool MeasureGUI_BndBoxDlg::execute (ObjectList& objects)
|
||||
{
|
||||
GEOM::GEOM_IMeasureOperations_var anOper = GEOM::GEOM_IMeasureOperations::_narrow(getOperation());
|
||||
GEOM::GEOM_Object_var anObj = anOper->MakeBoundingBox(myObj);
|
||||
GEOM::GEOM_Object_var anObj = anOper->MakeBoundingBox(myObj, true);
|
||||
|
||||
if (!anObj->_is_nil())
|
||||
objects.push_back(anObj._retn());
|
||||
|
@ -270,7 +270,7 @@ void TransformationGUI_MultiRotationDlg::SelectionIntoArgument()
|
||||
// recompute myAng and myStep (Mantis issue 0021718)
|
||||
GEOM::GEOM_IMeasureOperations_var anOper = getGeomEngine()->GetIMeasureOperations(getStudyId());
|
||||
double Xmin, Xmax, Ymin, Ymax, Zmin, Zmax;
|
||||
anOper->GetBoundingBox(myBase.get(), Xmin, Xmax, Ymin, Ymax, Zmin, Zmax);
|
||||
anOper->GetBoundingBox(myBase.get(), true, Xmin, Xmax, Ymin, Ymax, Zmin, Zmax);
|
||||
if (anOper->IsDone()) {
|
||||
// angular step
|
||||
double diag = sqrt((Xmax-Xmin)*(Xmax-Xmin) + (Ymax-Ymin)*(Ymax-Ymin));
|
||||
|
@ -335,7 +335,7 @@ void TransformationGUI_MultiTranslationDlg::SelectionIntoArgument()
|
||||
// recompute myStepU (Mantis issue 0021718)
|
||||
GEOM::GEOM_IMeasureOperations_var anOper = getGeomEngine()->GetIMeasureOperations(getStudyId());
|
||||
double Xmin, Xmax, Ymin, Ymax, Zmin, Zmax;
|
||||
anOper->GetBoundingBox(myBase.get(), Xmin, Xmax, Ymin, Ymax, Zmin, Zmax);
|
||||
anOper->GetBoundingBox(myBase.get(), true, Xmin, Xmax, Ymin, Ymax, Zmin, Zmax);
|
||||
if (anOper->IsDone()) {
|
||||
myStepU = floor(1.5 * (Xmax - Xmin));
|
||||
GroupPoints->SpinBox_DX->setValue(myStepU);
|
||||
@ -355,7 +355,7 @@ void TransformationGUI_MultiTranslationDlg::SelectionIntoArgument()
|
||||
// recompute myStepU and myStepV (Mantis issue 0021718)
|
||||
GEOM::GEOM_IMeasureOperations_var anOper = getGeomEngine()->GetIMeasureOperations(getStudyId());
|
||||
double Xmin, Xmax, Ymin, Ymax, Zmin, Zmax;
|
||||
anOper->GetBoundingBox(myBase.get(), Xmin, Xmax, Ymin, Ymax, Zmin, Zmax);
|
||||
anOper->GetBoundingBox(myBase.get(), true, Xmin, Xmax, Ymin, Ymax, Zmin, Zmax);
|
||||
if (anOper->IsDone()) {
|
||||
myStepU = floor(1.5 * (Xmax - Xmin));
|
||||
myStepV = floor(1.5 * (Ymax - Ymin));
|
||||
|
Loading…
Reference in New Issue
Block a user