mirror of
https://git.salome-platform.org/gitpub/modules/geom.git
synced 2024-12-25 17:00:35 +05:00
[bos #42424] [CEA][FORUM] bug with MinDistance in Geom Module. Old workarounds causing the problem have been abandoned.
This commit is contained in:
parent
d72c6cd028
commit
78d008f3a2
@ -44,6 +44,8 @@
|
|||||||
|
|
||||||
#include <utilities.h>
|
#include <utilities.h>
|
||||||
|
|
||||||
|
#include <Basics_OCCTVersion.hxx>
|
||||||
|
|
||||||
// OCCT Includes
|
// OCCT Includes
|
||||||
#include <Bnd_Box.hxx>
|
#include <Bnd_Box.hxx>
|
||||||
#include <BOPAlgo_CheckerSI.hxx>
|
#include <BOPAlgo_CheckerSI.hxx>
|
||||||
@ -2319,12 +2321,6 @@ Standard_Integer GEOMImpl_IMeasureOperations::ClosestPoints (Handle(GEOM_Object)
|
|||||||
try {
|
try {
|
||||||
OCC_CATCH_SIGNALS;
|
OCC_CATCH_SIGNALS;
|
||||||
|
|
||||||
// skl 30.06.2008
|
|
||||||
// additional workaround for bugs 19899, 19908 and 19910 from Mantis
|
|
||||||
gp_Pnt P1s, P2s;
|
|
||||||
double dist = GEOMUtils::GetMinDistanceSingular(aShape1, aShape2, P1s, P2s);
|
|
||||||
bool singularBetter = dist >= 0;
|
|
||||||
|
|
||||||
BRepExtrema_DistShapeShape dst (aShape1, aShape2);
|
BRepExtrema_DistShapeShape dst (aShape1, aShape2);
|
||||||
if (dst.IsDone()) {
|
if (dst.IsDone()) {
|
||||||
nbSolutions = dst.NbSolution();
|
nbSolutions = dst.NbSolution();
|
||||||
@ -2341,25 +2337,8 @@ Standard_Integer GEOMImpl_IMeasureOperations::ClosestPoints (Handle(GEOM_Object)
|
|||||||
theDoubles->Append(P2.X());
|
theDoubles->Append(P2.X());
|
||||||
theDoubles->Append(P2.Y());
|
theDoubles->Append(P2.Y());
|
||||||
theDoubles->Append(P2.Z());
|
theDoubles->Append(P2.Z());
|
||||||
|
|
||||||
Standard_Real Dist = P1.Distance(P2);
|
|
||||||
singularBetter = singularBetter && dist < Dist;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (singularBetter) {
|
|
||||||
if (theDoubles.IsNull()) theDoubles = new TColStd_HSequenceOfReal;
|
|
||||||
else theDoubles->Clear();
|
|
||||||
|
|
||||||
nbSolutions = 1;
|
|
||||||
|
|
||||||
theDoubles->Append(P1s.X());
|
|
||||||
theDoubles->Append(P1s.Y());
|
|
||||||
theDoubles->Append(P1s.Z());
|
|
||||||
theDoubles->Append(P2s.X());
|
|
||||||
theDoubles->Append(P2s.Y());
|
|
||||||
theDoubles->Append(P2s.Z());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Standard_Failure& aFail) {
|
catch (Standard_Failure& aFail) {
|
||||||
SetErrorCode(aFail.GetMessageString());
|
SetErrorCode(aFail.GetMessageString());
|
||||||
|
@ -119,112 +119,6 @@
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* This function constructs and returns modified shape from the original one
|
|
||||||
* for singular cases. It is used for the method GetMinDistanceSingular.
|
|
||||||
*
|
|
||||||
* \param theShape the original shape
|
|
||||||
* \param theModifiedShape output parameter. The modified shape.
|
|
||||||
* \param theAddDist output parameter. The added distance for modified shape.
|
|
||||||
* \retval true if the shape is modified; false otherwise.
|
|
||||||
*
|
|
||||||
* \internal
|
|
||||||
*/
|
|
||||||
Standard_Boolean ModifyShape(const TopoDS_Shape &theShape,
|
|
||||||
TopoDS_Shape &theModifiedShape,
|
|
||||||
Standard_Real &theAddDist)
|
|
||||||
{
|
|
||||||
TopExp_Explorer anExp;
|
|
||||||
int nbf = 0;
|
|
||||||
|
|
||||||
theAddDist = 0.;
|
|
||||||
theModifiedShape.Nullify();
|
|
||||||
|
|
||||||
for ( anExp.Init( theShape, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
|
|
||||||
nbf++;
|
|
||||||
theModifiedShape = anExp.Current();
|
|
||||||
}
|
|
||||||
if(nbf==1) {
|
|
||||||
TopoDS_Shape sh = theShape;
|
|
||||||
while(sh.ShapeType()==TopAbs_COMPOUND) {
|
|
||||||
TopoDS_Iterator it(sh);
|
|
||||||
sh = it.Value();
|
|
||||||
}
|
|
||||||
Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(theModifiedShape));
|
|
||||||
if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
|
|
||||||
S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ||
|
|
||||||
S->IsUPeriodic()) {
|
|
||||||
const Standard_Boolean isShell =
|
|
||||||
(sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE);
|
|
||||||
|
|
||||||
if ( !isShell && 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);
|
|
||||||
theModifiedShape = V;
|
|
||||||
theAddDist = SS->Radius();
|
|
||||||
return Standard_True;
|
|
||||||
}
|
|
||||||
if ( !isShell && 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);
|
|
||||||
theModifiedShape = E;
|
|
||||||
theAddDist = TS->MinorRadius();
|
|
||||||
return Standard_True;
|
|
||||||
}
|
|
||||||
|
|
||||||
// non solid case or any periodic surface (Mantis 22454).
|
|
||||||
double U1,U2,V1,V2;
|
|
||||||
BRepTools::UVBounds(TopoDS::Face(theModifiedShape),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);
|
|
||||||
TopoDS_Shape aMShape;
|
|
||||||
|
|
||||||
TopoDS_Face F1 = BRepBuilderAPI_MakeFace(TrS1, Precision::Confusion());
|
|
||||||
TopoDS_Face F2 = BRepBuilderAPI_MakeFace(TrS2, Precision::Confusion());
|
|
||||||
|
|
||||||
if (isShell) {
|
|
||||||
BRep_Builder B;
|
|
||||||
B.MakeCompound(TopoDS::Compound(aMShape));
|
|
||||||
B.Add(aMShape, F1);
|
|
||||||
B.Add(aMShape, F2);
|
|
||||||
} else {
|
|
||||||
// The original shape is a solid.
|
|
||||||
BRepBuilderAPI_Sewing aSewing (Precision::Confusion()*10.0);
|
|
||||||
aSewing.Add(F1);
|
|
||||||
aSewing.Add(F2);
|
|
||||||
aSewing.Perform();
|
|
||||||
aMShape = aSewing.SewedShape();
|
|
||||||
BRep_Builder B;
|
|
||||||
TopoDS_Solid aSolid;
|
|
||||||
B.MakeSolid(aSolid);
|
|
||||||
B.Add(aSolid, aMShape);
|
|
||||||
aMShape = aSolid;
|
|
||||||
}
|
|
||||||
|
|
||||||
Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
|
|
||||||
sfs->Init(aMShape);
|
|
||||||
sfs->SetPrecision(1.e-6);
|
|
||||||
sfs->SetMaxTolerance(1.0);
|
|
||||||
sfs->Perform();
|
|
||||||
theModifiedShape = sfs->Shape();
|
|
||||||
return Standard_True;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
theModifiedShape = theShape;
|
|
||||||
return Standard_False;
|
|
||||||
}
|
|
||||||
|
|
||||||
void parseWard( const GEOMUtils::LevelsList &theLevelList, std::string &treeStr )
|
void parseWard( const GEOMUtils::LevelsList &theLevelList, std::string &treeStr )
|
||||||
{
|
{
|
||||||
treeStr.append( "{" );
|
treeStr.append( "{" );
|
||||||
@ -836,75 +730,6 @@ Standard_Boolean GEOMUtils::PreciseBoundingBox
|
|||||||
return Standard_True;
|
return Standard_True;
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
|
||||||
//function : GetMinDistanceSingular
|
|
||||||
//purpose :
|
|
||||||
//=======================================================================
|
|
||||||
double GEOMUtils::GetMinDistanceSingular(const TopoDS_Shape& aSh1,
|
|
||||||
const TopoDS_Shape& aSh2,
|
|
||||||
gp_Pnt& Ptmp1, gp_Pnt& Ptmp2)
|
|
||||||
{
|
|
||||||
TopoDS_Shape tmpSh1;
|
|
||||||
TopoDS_Shape tmpSh2;
|
|
||||||
Standard_Real AddDist1 = 0.;
|
|
||||||
Standard_Real AddDist2 = 0.;
|
|
||||||
Standard_Boolean IsChange1 = ModifyShape(aSh1, tmpSh1, AddDist1);
|
|
||||||
Standard_Boolean IsChange2 = ModifyShape(aSh2, tmpSh2, AddDist2);
|
|
||||||
|
|
||||||
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
|
//function : GetMinDistance
|
||||||
//purpose :
|
//purpose :
|
||||||
@ -914,46 +739,7 @@ Standard_Real GEOMUtils::GetMinDistance
|
|||||||
const TopoDS_Shape& theShape2,
|
const TopoDS_Shape& theShape2,
|
||||||
gp_Pnt& thePnt1, gp_Pnt& thePnt2)
|
gp_Pnt& thePnt1, gp_Pnt& thePnt2)
|
||||||
{
|
{
|
||||||
Standard_Real aResult = 1.e9;
|
Standard_Real aResult = -1.0;
|
||||||
|
|
||||||
// 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
|
|
||||||
#if OCC_VERSION_LARGE < 0x07070000
|
|
||||||
aResult = GEOMUtils::GetMinDistanceSingular(theShape1, theShape2, thePnt1, thePnt2);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (dist > -1.0) {
|
|
||||||
return dist;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
BRepExtrema_DistShapeShape dst (theShape1, theShape2);
|
BRepExtrema_DistShapeShape dst (theShape1, theShape2);
|
||||||
if (dst.IsDone()) {
|
if (dst.IsDone()) {
|
||||||
@ -964,7 +750,7 @@ Standard_Real GEOMUtils::GetMinDistance
|
|||||||
P2 = dst.PointOnShape2(i);
|
P2 = dst.PointOnShape2(i);
|
||||||
|
|
||||||
Standard_Real Dist = P1.Distance(P2);
|
Standard_Real Dist = P1.Distance(P2);
|
||||||
if (aResult < 0 || aResult > Dist) {
|
if (aResult < 0 || Dist < aResult ) {
|
||||||
aResult = Dist;
|
aResult = Dist;
|
||||||
thePnt1 = P1;
|
thePnt1 = P1;
|
||||||
thePnt2 = P2;
|
thePnt2 = P2;
|
||||||
|
@ -181,20 +181,6 @@ namespace GEOMUtils
|
|||||||
*/
|
*/
|
||||||
Standard_EXPORT Standard_Boolean PreciseBoundingBox(const TopoDS_Shape &theShape, Bnd_Box &theBox);
|
Standard_EXPORT 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 Standard_Real GetMinDistanceSingular(const TopoDS_Shape& aSh1,
|
|
||||||
const TopoDS_Shape& aSh2,
|
|
||||||
gp_Pnt& Ptmp1, gp_Pnt& Ptmp2);
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Computes minumal distance between two shapes.
|
* \brief Computes minumal distance between two shapes.
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user