mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-04 18:06:22 +03:00
0027282: [Regression to 6.9.1] smesh/bugs_00/A6: Cut produces an empty shape
1. The reason of the regression is not-closed intersection result. This problem has been solved (in this fix) by adding joint point to the both neighbors intersection lines (lines were extended to the this intersection point). It is made in IntPatch_WLineTool::ExtendTwoWlinesToEachOther(...) method. 2. Interface of IntPatch_PointLine and inherited classes has been changed. Methods ChangeVertex(...) and RemoveVertex(...) have been added. Test cases for this issue have been created. Small correction in the code.
This commit is contained in:
parent
93e38faa3b
commit
eee615ad2a
@ -1356,73 +1356,98 @@ void IntPatch_Intersection::GeomGeomPerfom(const Handle(Adaptor3d_HSurface)& the
|
||||
if (tgte)
|
||||
oppo = interii.OppositeFaces();
|
||||
|
||||
Standard_Boolean isQuadSet = Standard_False;
|
||||
IntSurf_Quadric Quad1,Quad2;
|
||||
|
||||
for (Standard_Integer i = 1; i <= interii.NbLines(); i++)
|
||||
{
|
||||
const Handle(IntPatch_Line)& line = interii.Line(i);
|
||||
if (line->ArcType() == IntPatch_Analytic)
|
||||
{
|
||||
const GeomAbs_SurfaceType aTyps1 = theS1->GetType();
|
||||
const GeomAbs_SurfaceType aTyps2 = theS2->GetType();
|
||||
IntSurf_Quadric Quad1,Quad2;
|
||||
|
||||
switch(aTyps1)
|
||||
if(!isQuadSet)
|
||||
{
|
||||
case GeomAbs_Plane:
|
||||
Quad1.SetValue(theS1->Plane());
|
||||
break;
|
||||
isQuadSet = Standard_True;
|
||||
|
||||
case GeomAbs_Cylinder:
|
||||
Quad1.SetValue(theS1->Cylinder());
|
||||
break;
|
||||
const GeomAbs_SurfaceType aTyps1 = theS1->GetType();
|
||||
const GeomAbs_SurfaceType aTyps2 = theS2->GetType();
|
||||
|
||||
case GeomAbs_Sphere:
|
||||
Quad1.SetValue(theS1->Sphere());
|
||||
break;
|
||||
switch(aTyps1)
|
||||
{
|
||||
case GeomAbs_Plane:
|
||||
Quad1.SetValue(theS1->Plane());
|
||||
break;
|
||||
|
||||
case GeomAbs_Cone:
|
||||
Quad1.SetValue(theS1->Cone());
|
||||
break;
|
||||
case GeomAbs_Cylinder:
|
||||
Quad1.SetValue(theS1->Cylinder());
|
||||
break;
|
||||
|
||||
case GeomAbs_Torus:
|
||||
Quad1.SetValue(theS1->Torus());
|
||||
break;
|
||||
case GeomAbs_Sphere:
|
||||
Quad1.SetValue(theS1->Sphere());
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case GeomAbs_Cone:
|
||||
Quad1.SetValue(theS1->Cone());
|
||||
break;
|
||||
|
||||
switch(aTyps2)
|
||||
{
|
||||
case GeomAbs_Plane:
|
||||
Quad2.SetValue(theS2->Plane());
|
||||
break;
|
||||
case GeomAbs_Cylinder:
|
||||
Quad2.SetValue(theS2->Cylinder());
|
||||
break;
|
||||
case GeomAbs_Torus:
|
||||
Quad1.SetValue(theS1->Torus());
|
||||
break;
|
||||
|
||||
case GeomAbs_Sphere:
|
||||
Quad2.SetValue(theS2->Sphere());
|
||||
break;
|
||||
default:
|
||||
isQuadSet = Standard_False;
|
||||
break;
|
||||
}
|
||||
|
||||
case GeomAbs_Cone:
|
||||
Quad2.SetValue(theS2->Cone());
|
||||
break;
|
||||
switch(aTyps2)
|
||||
{
|
||||
case GeomAbs_Plane:
|
||||
Quad2.SetValue(theS2->Plane());
|
||||
break;
|
||||
case GeomAbs_Cylinder:
|
||||
Quad2.SetValue(theS2->Cylinder());
|
||||
break;
|
||||
|
||||
case GeomAbs_Torus:
|
||||
Quad2.SetValue(theS2->Torus());
|
||||
break;
|
||||
case GeomAbs_Sphere:
|
||||
Quad2.SetValue(theS2->Sphere());
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
case GeomAbs_Cone:
|
||||
Quad2.SetValue(theS2->Cone());
|
||||
break;
|
||||
|
||||
case GeomAbs_Torus:
|
||||
Quad2.SetValue(theS2->Torus());
|
||||
break;
|
||||
|
||||
default:
|
||||
isQuadSet = Standard_False;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!isQuadSet)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IntPatch_ALineToWLine AToW(Quad1,Quad2,0.01,0.05,aNbPointsInALine);
|
||||
Handle(IntPatch_WLine) wlin=AToW.MakeWLine((*((Handle(IntPatch_ALine) *)(&line))));
|
||||
Handle(IntPatch_WLine) wlin =
|
||||
AToW.MakeWLine(Handle(IntPatch_ALine)::DownCast(line));
|
||||
wlin->EnablePurging(Standard_False);
|
||||
slin.Append(wlin);
|
||||
}
|
||||
else
|
||||
slin.Append(interii.Line(i));
|
||||
slin.Append(line);
|
||||
}
|
||||
|
||||
if(isQuadSet)
|
||||
{
|
||||
IntPatch_WLineTool::
|
||||
ExtendTwoWlinesToEachOther(slin, Quad1, Quad2, TolTang,
|
||||
theS1->IsUPeriodic()? theS1->UPeriod() : 0.0,
|
||||
theS2->IsUPeriodic()? theS2->UPeriod() : 0.0,
|
||||
theS1->IsVPeriodic()? theS1->VPeriod() : 0.0,
|
||||
theS2->IsVPeriodic()? theS2->VPeriod() : 0.0);
|
||||
}
|
||||
|
||||
for (Standard_Integer i = 1; i <= interii.NbPnts(); i++)
|
||||
|
@ -60,9 +60,15 @@ public:
|
||||
//! Returns the vertex of range Index on the line.
|
||||
Standard_EXPORT virtual const IntPatch_Point& Vertex (const Standard_Integer Index) const = 0;
|
||||
|
||||
//! Returns the vertex of range Index on the line.
|
||||
virtual IntPatch_Point& ChangeVertex (const Standard_Integer Index) = 0;
|
||||
|
||||
//! Removes vertices from the line
|
||||
Standard_EXPORT virtual void ClearVertexes() = 0;
|
||||
|
||||
//! Removes single vertex from the line
|
||||
Standard_EXPORT virtual void RemoveVertex (const Standard_Integer theIndex) = 0;
|
||||
|
||||
//! Returns set of intersection points
|
||||
Standard_EXPORT virtual Handle(IntSurf_LineOn2S) Curve() const = 0;
|
||||
|
||||
|
@ -123,6 +123,12 @@ public:
|
||||
//! Returns the vertex of range Index on the line.
|
||||
virtual const IntPatch_Point& Vertex (const Standard_Integer Index) const Standard_OVERRIDE;
|
||||
|
||||
//! Returns the vertex of range Index on the line.
|
||||
virtual IntPatch_Point& ChangeVertex (const Standard_Integer Index) Standard_OVERRIDE;
|
||||
|
||||
//! Removes single vertex from the line
|
||||
virtual void RemoveVertex (const Standard_Integer theIndex) Standard_OVERRIDE;
|
||||
|
||||
Standard_Boolean HasPolygon() const;
|
||||
|
||||
//! Returns the number of intersection points.
|
||||
|
@ -102,6 +102,18 @@ inline const IntPatch_Point& IntPatch_RLine::Vertex (const Standard_Integer Inde
|
||||
return svtx(Index);
|
||||
}
|
||||
|
||||
inline IntPatch_Point& IntPatch_RLine::ChangeVertex (const Standard_Integer Index)
|
||||
{
|
||||
return svtx(Index);
|
||||
}
|
||||
|
||||
inline void IntPatch_RLine::RemoveVertex(const Standard_Integer theIndex)
|
||||
{
|
||||
if((theIndex < 1) || (theIndex > NbVertex()))
|
||||
Standard_OutOfRange::Raise("Cannot delete not existing vertex");
|
||||
svtx.Remove(theIndex);
|
||||
}
|
||||
|
||||
inline Standard_Boolean IntPatch_RLine::HasPolygon () const
|
||||
{
|
||||
return (!curv.IsNull());
|
||||
|
@ -114,6 +114,9 @@ public:
|
||||
//! Returns the vertex of range Index on the line.
|
||||
virtual const IntPatch_Point& Vertex (const Standard_Integer Index) const Standard_OVERRIDE;
|
||||
|
||||
//! Returns the vertex of range Index on the line.
|
||||
virtual IntPatch_Point& ChangeVertex (const Standard_Integer Index) Standard_OVERRIDE;
|
||||
|
||||
//! Set the parameters of all the vertex on the line.
|
||||
//! if a vertex is already in the line,
|
||||
//! its parameter is modified
|
||||
@ -154,7 +157,8 @@ public:
|
||||
//! Removes vertices from the line (i.e. cleans svtx member)
|
||||
virtual void ClearVertexes() Standard_OVERRIDE;
|
||||
|
||||
Standard_EXPORT void RemoveVertex (const Standard_Integer theIndex);
|
||||
//! Removes single vertex from the line
|
||||
virtual void RemoveVertex (const Standard_Integer theIndex) Standard_OVERRIDE;
|
||||
|
||||
Standard_EXPORT void InsertVertexBefore (const Standard_Integer theIndex, const IntPatch_Point& thePnt);
|
||||
|
||||
|
@ -98,6 +98,11 @@ inline const IntPatch_Point& IntPatch_WLine::Vertex (const Standard_Integer Inde
|
||||
return svtx(Index);
|
||||
}
|
||||
|
||||
inline IntPatch_Point& IntPatch_WLine::ChangeVertex (const Standard_Integer Index)
|
||||
{
|
||||
return svtx(Index);
|
||||
}
|
||||
|
||||
inline void IntPatch_WLine::ClearVertexes()
|
||||
{
|
||||
svtx.Clear();
|
||||
|
@ -519,12 +519,10 @@ static Standard_Integer IsSeam( const Standard_Real theU1,
|
||||
//purpose : Returns TRUE if segment [thePtf, thePtl] intersects "seam-edge"
|
||||
// (if it exist) or surface boundaries and both thePtf and thePtl do
|
||||
// not match "seam-edge" or boundaries.
|
||||
// Point thePtmid lies in this segment. If thePtmid match
|
||||
// "seam-edge" or boundaries strictly (without any tolerance) then
|
||||
// the function will return TRUE.
|
||||
// Point thePtmid lies in this segment (in both 3D and 2D-space).
|
||||
// If thePtmid match "seam-edge" or boundaries strictly
|
||||
// (without any tolerance) then the function will return TRUE.
|
||||
// See comments in function body for detail information.
|
||||
//
|
||||
// Static subfunction in JoinWLines.
|
||||
//=======================================================================
|
||||
static Standard_Boolean IsSeamOrBound(const IntSurf_PntOn2S& thePtf,
|
||||
const IntSurf_PntOn2S& thePtl,
|
||||
@ -651,6 +649,107 @@ static Standard_Boolean IsSeamOrBound(const IntSurf_PntOn2S& thePtf,
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : AbjustPeriodicToPrevPoint
|
||||
//purpose : Returns theCurrentParam in order to the distance betwen
|
||||
// theRefParam and theCurrentParam is less than 0.5*thePeriod.
|
||||
//=======================================================================
|
||||
static void AbjustPeriodicToPrevPoint(const Standard_Real theRefParam,
|
||||
const Standard_Real thePeriod,
|
||||
Standard_Real& theCurrentParam)
|
||||
{
|
||||
if(thePeriod == 0.0)
|
||||
return;
|
||||
|
||||
Standard_Real aDeltaPar = 2.0*(theRefParam - theCurrentParam);
|
||||
const Standard_Real anIncr = Sign(thePeriod, aDeltaPar);
|
||||
while(Abs(aDeltaPar) > thePeriod)
|
||||
{
|
||||
theCurrentParam += anIncr;
|
||||
aDeltaPar = 2.0*(theRefParam-theCurrentParam);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsIntersectionPoint
|
||||
//purpose : Returns True if thePmid is intersection point
|
||||
// between theS1 and theS2 with given tolerance.
|
||||
// In this case, parameters of thePmid on every quadric
|
||||
// will be recomputed and returned.
|
||||
//=======================================================================
|
||||
static Standard_Boolean IsIntersectionPoint(const gp_Pnt& thePmid,
|
||||
const IntSurf_Quadric& theS1,
|
||||
const IntSurf_Quadric& theS2,
|
||||
const IntSurf_PntOn2S& theRefPt,
|
||||
const Standard_Real theTol,
|
||||
const Standard_Real theU1Period,
|
||||
const Standard_Real theU2Period,
|
||||
const Standard_Real theV1Period,
|
||||
const Standard_Real theV2Period,
|
||||
Standard_Real &theU1,
|
||||
Standard_Real &theV1,
|
||||
Standard_Real &theU2,
|
||||
Standard_Real &theV2)
|
||||
{
|
||||
Standard_Real aU1Ref = 0.0, aV1Ref = 0.0, aU2Ref = 0.0, aV2Ref = 0.0;
|
||||
theRefPt.Parameters(aU1Ref, aV1Ref, aU2Ref, aV2Ref);
|
||||
theS1.Parameters(thePmid, theU1, theV1);
|
||||
theS2.Parameters(thePmid, theU2, theV2);
|
||||
|
||||
AbjustPeriodicToPrevPoint(aU1Ref, theU1Period, theU1);
|
||||
AbjustPeriodicToPrevPoint(aV1Ref, theV1Period, theV1);
|
||||
AbjustPeriodicToPrevPoint(aU2Ref, theU2Period, theU2);
|
||||
AbjustPeriodicToPrevPoint(aV2Ref, theV2Period, theV2);
|
||||
|
||||
const gp_Pnt aP1(theS1.Value(theU1, theV1));
|
||||
const gp_Pnt aP2(theS2.Value(theU2, theV2));
|
||||
|
||||
return (aP1.SquareDistance(aP2) <= theTol*theTol);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ExtendFirst
|
||||
//purpose : Adds thePOn2S to the begin of theWline
|
||||
//=======================================================================
|
||||
static void ExtendFirst(const Handle(IntPatch_WLine)& theWline,
|
||||
const IntSurf_PntOn2S &thePOn2S)
|
||||
{
|
||||
theWline->Curve()->InsertBefore(1, thePOn2S);
|
||||
|
||||
IntPatch_Point &aVert = theWline->ChangeVertex(1);
|
||||
|
||||
Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0;
|
||||
thePOn2S.Parameters(aU1, aV1, aU2, aV2);
|
||||
|
||||
aVert.SetParameters(aU1, aV1, aU2, aV2);
|
||||
aVert.SetValue(thePOn2S.Value());
|
||||
|
||||
for(Standard_Integer i = 2; i <= theWline->NbVertex(); i++)
|
||||
{
|
||||
IntPatch_Point &aV = theWline->ChangeVertex(i);
|
||||
aV.SetParameter(aV.ParameterOnLine()+1);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ExtendLast
|
||||
//purpose : Adds thePOn2S to the end of theWline
|
||||
//=======================================================================
|
||||
static void ExtendLast(const Handle(IntPatch_WLine)& theWline,
|
||||
const IntSurf_PntOn2S &thePOn2S)
|
||||
{
|
||||
theWline->Curve()->Add(thePOn2S);
|
||||
|
||||
IntPatch_Point &aVert = theWline->ChangeVertex(theWline->NbVertex());
|
||||
|
||||
Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0;
|
||||
thePOn2S.Parameters(aU1, aV1, aU2, aV2);
|
||||
|
||||
aVert.SetParameters(aU1, aV1, aU2, aV2);
|
||||
aVert.SetValue(thePOn2S.Value());
|
||||
aVert.SetParameter(theWline->NbPnts());
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// function : ComputePurgedWLine
|
||||
// purpose :
|
||||
@ -952,3 +1051,297 @@ void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin,
|
||||
aNumOfLine1--;
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ExtendTwoWlinesToEachOther
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void IntPatch_WLineTool::ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& theSlin,
|
||||
const IntSurf_Quadric& theS1,
|
||||
const IntSurf_Quadric& theS2,
|
||||
const Standard_Real theToler3D,
|
||||
const Standard_Real theU1Period,
|
||||
const Standard_Real theU2Period,
|
||||
const Standard_Real theV1Period,
|
||||
const Standard_Real theV2Period)
|
||||
{
|
||||
if(theSlin.Length() < 2)
|
||||
return;
|
||||
|
||||
const Standard_Real aMaxAngle = M_PI/6; //30 degree
|
||||
const Standard_Real aSqToler = theToler3D*theToler3D;
|
||||
Standard_Real aU1=0.0, aV1=0.0, aU2=0.0, aV2=0.0;
|
||||
gp_Pnt aPmid;
|
||||
gp_Vec aVec1, aVec2, aVec3;
|
||||
|
||||
for(Standard_Integer aNumOfLine1 = 1; aNumOfLine1 <= theSlin.Length(); aNumOfLine1++)
|
||||
{
|
||||
Handle(IntPatch_WLine) aWLine1 (Handle(IntPatch_WLine)::
|
||||
DownCast(theSlin.Value(aNumOfLine1)));
|
||||
|
||||
if(aWLine1.IsNull())
|
||||
{//We must have failed to join not-point-lines
|
||||
continue;
|
||||
}
|
||||
|
||||
const Standard_Integer aNbPntsWL1 = aWLine1->NbPnts();
|
||||
|
||||
for(Standard_Integer aNumOfLine2 = aNumOfLine1 + 1;
|
||||
aNumOfLine2 <= theSlin.Length(); aNumOfLine2++)
|
||||
{
|
||||
Handle(IntPatch_WLine) aWLine2 (Handle(IntPatch_WLine)::
|
||||
DownCast(theSlin.Value(aNumOfLine2)));
|
||||
|
||||
if(aWLine2.IsNull())
|
||||
continue;
|
||||
|
||||
//Enable/Disable of some ckeck. Bit-mask is used for it.
|
||||
//E.g. if 1st point of aWLine1 matches with
|
||||
//1st point of aWLine2 then we do not need in check
|
||||
//1st point of aWLine1 and last point of aWLine2 etc.
|
||||
enum
|
||||
{
|
||||
IntPatchWT_EnAll = 0x00,
|
||||
IntPatchWT_DisLastLast = 0x01,
|
||||
IntPatchWT_DisLastFirst = 0x02,
|
||||
IntPatchWT_DisFirstLast = 0x04,
|
||||
IntPatchWT_DisFirstFirst = 0x08
|
||||
};
|
||||
|
||||
unsigned int aCheckResult = IntPatchWT_EnAll;
|
||||
|
||||
const Standard_Integer aNbPntsWL2 = aWLine2->NbPnts();
|
||||
|
||||
const IntSurf_PntOn2S& aPntFWL1 = aWLine1->Point(1);
|
||||
const IntSurf_PntOn2S& aPntFp1WL1 = aWLine1->Point(2);
|
||||
|
||||
const IntSurf_PntOn2S& aPntLWL1 = aWLine1->Point(aNbPntsWL1);
|
||||
const IntSurf_PntOn2S& aPntLm1WL1 = aWLine1->Point(aNbPntsWL1-1);
|
||||
|
||||
const IntSurf_PntOn2S& aPntFWL2 = aWLine2->Point(1);
|
||||
const IntSurf_PntOn2S& aPntFp1WL2 = aWLine2->Point(2);
|
||||
|
||||
const IntSurf_PntOn2S& aPntLWL2 = aWLine2->Point(aNbPntsWL2);
|
||||
const IntSurf_PntOn2S& aPntLm1WL2 = aWLine2->Point(aNbPntsWL2-1);
|
||||
|
||||
//if(!(aCheckResult & IntPatchWT_DisFirstFirst))
|
||||
{// First/First
|
||||
aVec1.SetXYZ(aPntFp1WL1.Value().XYZ() - aPntFWL1.Value().XYZ());
|
||||
aVec2.SetXYZ(aPntFWL2.Value().XYZ() - aPntFp1WL2.Value().XYZ());
|
||||
aVec3.SetXYZ(aPntFWL1.Value().XYZ() - aPntFWL2.Value().XYZ());
|
||||
|
||||
if(aVec3.SquareMagnitude() > aSqToler)
|
||||
{
|
||||
if( (aVec1.Angle(aVec2) < aMaxAngle) &&
|
||||
(aVec1.Angle(aVec3) < aMaxAngle) &&
|
||||
(aVec2.Angle(aVec3) < aMaxAngle))
|
||||
{
|
||||
aPmid.SetXYZ(0.5*(aPntFWL1.Value().XYZ()+aPntFWL2.Value().XYZ()));
|
||||
if(IsIntersectionPoint(aPmid, theS1, theS2, aPntFWL1, theToler3D,
|
||||
theU1Period, theU2Period, theV1Period, theV2Period,
|
||||
aU1, aV1, aU2, aV2))
|
||||
{
|
||||
IntSurf_PntOn2S aPOn2S;
|
||||
aPOn2S.SetValue(aPmid, aU1, aV1, aU2, aV2);
|
||||
|
||||
Standard_Real aU11 = 0.0, aV11 = 0.0, aU21 = 0.0, aV21 = 0.0,
|
||||
aU12 = 0.0, aV12 = 0.0, aU22 = 0.0, aV22 = 0.0;
|
||||
aPntFWL1.Parameters(aU11, aV11, aU21, aV21);
|
||||
aPntFWL2.Parameters(aU12, aV12, aU22, aV22);
|
||||
|
||||
if(!IsSeam(aU11, aU12, theU1Period) &&
|
||||
!IsSeam(aV11, aV12, theV1Period) &&
|
||||
!IsSeam(aU21, aU22, theU2Period) &&
|
||||
!IsSeam(aV21, aV22, theV2Period))
|
||||
{
|
||||
aCheckResult |= (IntPatchWT_DisFirstLast |
|
||||
IntPatchWT_DisLastFirst);
|
||||
|
||||
if(!aPOn2S.IsSame(aPntFWL1, Precision::Confusion()))
|
||||
{
|
||||
ExtendFirst(aWLine1, aPOn2S);
|
||||
}
|
||||
else
|
||||
{
|
||||
aWLine1->Curve()->Value(1, aPOn2S);
|
||||
}
|
||||
|
||||
if(!aPOn2S.IsSame(aPntFWL2, Precision::Confusion()))
|
||||
{
|
||||
ExtendFirst(aWLine2, aPOn2S);
|
||||
}
|
||||
else
|
||||
{
|
||||
aWLine2->Curve()->Value(1, aPOn2S);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}//if(aVec3.SquareMagnitude() > aSqToler) cond.
|
||||
}//if(!(aCheckResult & 0x08)) cond.
|
||||
|
||||
if(!(aCheckResult & IntPatchWT_DisFirstLast))
|
||||
{// First/Last
|
||||
aVec1.SetXYZ(aPntFp1WL1.Value().XYZ() - aPntFWL1.Value().XYZ());
|
||||
aVec2.SetXYZ(aPntLWL2.Value().XYZ() - aPntLm1WL2.Value().XYZ());
|
||||
aVec3.SetXYZ(aPntFWL1.Value().XYZ() - aPntLWL2.Value().XYZ());
|
||||
|
||||
if(aVec3.SquareMagnitude() > aSqToler)
|
||||
{
|
||||
if((aVec1.Angle(aVec2) < aMaxAngle) &&
|
||||
(aVec1.Angle(aVec3) < aMaxAngle) &&
|
||||
(aVec2.Angle(aVec3) < aMaxAngle))
|
||||
{
|
||||
aPmid.SetXYZ(0.5*(aPntFWL1.Value().XYZ()+aPntLWL2.Value().XYZ()));
|
||||
if(IsIntersectionPoint(aPmid, theS1, theS2, aPntFWL1, theToler3D,
|
||||
theU1Period, theU2Period, theV1Period, theV2Period,
|
||||
aU1, aV1, aU2, aV2))
|
||||
{
|
||||
IntSurf_PntOn2S aPOn2S;
|
||||
aPOn2S.SetValue(aPmid, aU1, aV1, aU2, aV2);
|
||||
|
||||
Standard_Real aU11 = 0.0, aV11 = 0.0, aU21 = 0.0, aV21 = 0.0,
|
||||
aU12 = 0.0, aV12 = 0.0, aU22 = 0.0, aV22 = 0.0;
|
||||
aPntFWL1.Parameters(aU11, aV11, aU21, aV21);
|
||||
aPntLWL2.Parameters(aU12, aV12, aU22, aV22);
|
||||
|
||||
if(!IsSeam(aU11, aU12, theU1Period) &&
|
||||
!IsSeam(aV11, aV12, theV1Period) &&
|
||||
!IsSeam(aU21, aU22, theU2Period) &&
|
||||
!IsSeam(aV21, aV22, theV2Period))
|
||||
{
|
||||
aCheckResult |= IntPatchWT_DisLastLast;
|
||||
|
||||
if(!aPOn2S.IsSame(aPntFWL1, Precision::Confusion()))
|
||||
{
|
||||
ExtendFirst(aWLine1, aPOn2S);
|
||||
}
|
||||
else
|
||||
{
|
||||
aWLine1->Curve()->Value(1, aPOn2S);
|
||||
}
|
||||
|
||||
if(!aPOn2S.IsSame(aPntLWL2, Precision::Confusion()))
|
||||
{
|
||||
ExtendLast(aWLine2, aPOn2S);
|
||||
}
|
||||
else
|
||||
{
|
||||
aWLine2->Curve()->Value(aWLine2->NbPnts(), aPOn2S);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}//if(aVec3.SquareMagnitude() > aSqToler) cond.
|
||||
}//if(!(aCheckResult & 0x04)) cond.
|
||||
|
||||
if(!(aCheckResult & IntPatchWT_DisLastFirst))
|
||||
{// Last/First
|
||||
aVec1.SetXYZ(aPntLWL1.Value().XYZ() - aPntLm1WL1.Value().XYZ());
|
||||
aVec2.SetXYZ(aPntFp1WL2.Value().XYZ() - aPntFWL2.Value().XYZ());
|
||||
aVec3.SetXYZ(aPntFWL2.Value().XYZ() - aPntLWL1.Value().XYZ());
|
||||
|
||||
if(aVec3.SquareMagnitude() > aSqToler)
|
||||
{
|
||||
if((aVec1.Angle(aVec2) < aMaxAngle) &&
|
||||
(aVec1.Angle(aVec3) < aMaxAngle) &&
|
||||
(aVec2.Angle(aVec3) < aMaxAngle))
|
||||
{
|
||||
aPmid.SetXYZ(0.5*(aPntLWL1.Value().XYZ()+aPntFWL2.Value().XYZ()));
|
||||
if(IsIntersectionPoint(aPmid, theS1, theS2, aPntLWL1, theToler3D,
|
||||
theU1Period, theU2Period, theV1Period, theV2Period,
|
||||
aU1, aV1, aU2, aV2))
|
||||
{
|
||||
IntSurf_PntOn2S aPOn2S;
|
||||
aPOn2S.SetValue(aPmid, aU1, aV1, aU2, aV2);
|
||||
|
||||
Standard_Real aU11 = 0.0, aV11 = 0.0, aU21 = 0.0, aV21 = 0.0,
|
||||
aU12 = 0.0, aV12 = 0.0, aU22 = 0.0, aV22 = 0.0;
|
||||
aPntLWL1.Parameters(aU11, aV11, aU21, aV21);
|
||||
aPntFWL2.Parameters(aU12, aV12, aU22, aV22);
|
||||
|
||||
if(!IsSeam(aU11, aU12, theU1Period) &&
|
||||
!IsSeam(aV11, aV12, theV1Period) &&
|
||||
!IsSeam(aU21, aU22, theU2Period) &&
|
||||
!IsSeam(aV21, aV22, theV2Period))
|
||||
{
|
||||
aCheckResult |= IntPatchWT_DisLastLast;
|
||||
|
||||
if(!aPOn2S.IsSame(aPntLWL1, Precision::Confusion()))
|
||||
{
|
||||
ExtendLast(aWLine1, aPOn2S);
|
||||
}
|
||||
else
|
||||
{
|
||||
aWLine1->Curve()->Value(aWLine1->NbPnts(), aPOn2S);
|
||||
}
|
||||
|
||||
if(!aPOn2S.IsSame(aPntFWL2, Precision::Confusion()))
|
||||
{
|
||||
ExtendFirst(aWLine2, aPOn2S);
|
||||
}
|
||||
else
|
||||
{
|
||||
aWLine2->Curve()->Value(1, aPOn2S);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}//if(aVec3.SquareMagnitude() > aSqToler) cond.
|
||||
}//if(!(aCheckResult & 0x02)) cond.
|
||||
|
||||
if(!(aCheckResult & IntPatchWT_DisLastLast))
|
||||
{// Last/Last
|
||||
aVec1.SetXYZ(aPntLWL1.Value().XYZ() - aPntLm1WL1.Value().XYZ());
|
||||
aVec2.SetXYZ(aPntLm1WL2.Value().XYZ() - aPntLWL2.Value().XYZ());
|
||||
aVec3.SetXYZ(aPntLWL2.Value().XYZ() - aPntLWL1.Value().XYZ());
|
||||
|
||||
if(aVec3.SquareMagnitude() > aSqToler)
|
||||
{
|
||||
if((aVec1.Angle(aVec2) < aMaxAngle) &&
|
||||
(aVec1.Angle(aVec3) < aMaxAngle) &&
|
||||
(aVec2.Angle(aVec3) < aMaxAngle))
|
||||
{
|
||||
aPmid.SetXYZ(0.5*(aPntLWL1.Value().XYZ()+aPntLWL2.Value().XYZ()));
|
||||
if(IsIntersectionPoint(aPmid, theS1, theS2, aPntLWL1, theToler3D,
|
||||
theU1Period, theU2Period, theV1Period, theV2Period,
|
||||
aU1, aV1, aU2, aV2))
|
||||
{
|
||||
IntSurf_PntOn2S aPOn2S;
|
||||
aPOn2S.SetValue(aPmid, aU1, aV1, aU2, aV2);
|
||||
|
||||
Standard_Real aU11 = 0.0, aV11 = 0.0, aU21 = 0.0, aV21 = 0.0,
|
||||
aU12 = 0.0, aV12 = 0.0, aU22 = 0.0, aV22 = 0.0;
|
||||
aPntLWL1.Parameters(aU11, aV11, aU21, aV21);
|
||||
aPntLWL2.Parameters(aU12, aV12, aU22, aV22);
|
||||
|
||||
if(!IsSeam(aU11, aU12, theU1Period) &&
|
||||
!IsSeam(aV11, aV12, theV1Period) &&
|
||||
!IsSeam(aU21, aU22, theU2Period) &&
|
||||
!IsSeam(aV21, aV22, theV2Period))
|
||||
{
|
||||
if(!aPOn2S.IsSame(aPntLWL1, Precision::Confusion()))
|
||||
{
|
||||
ExtendLast(aWLine1, aPOn2S);
|
||||
}
|
||||
else
|
||||
{
|
||||
aWLine1->Curve()->Value(aWLine1->NbPnts(), aPOn2S);
|
||||
}
|
||||
|
||||
if(!aPOn2S.IsSame(aPntLWL2, Precision::Confusion()))
|
||||
{
|
||||
ExtendLast(aWLine2, aPOn2S);
|
||||
}
|
||||
else
|
||||
{
|
||||
aWLine2->Curve()->Value(aWLine2->NbPnts(), aPOn2S);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}//if(aVec3.SquareMagnitude() > aSqToler) cond.
|
||||
}//if(!(aCheckResult & 0x01)) cond.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <Standard_Macro.hxx>
|
||||
#include <IntPatch_WLine.hxx>
|
||||
#include <IntPatch_SequenceOfLine.hxx>
|
||||
#include <IntSurf_Quadric.hxx>
|
||||
class TopoDS_Face;
|
||||
class GeomAdaptor_HSurface;
|
||||
class GeomInt_LineConstructor;
|
||||
@ -76,6 +77,23 @@ public:
|
||||
const Standard_Real theVfSurf2,
|
||||
const Standard_Real theVlSurf2);
|
||||
|
||||
|
||||
//! Concatenates two some Walking lines from theSlin if it is possible.
|
||||
//! This method does not create single line from several. It allows every
|
||||
//! extended line to be started/finished in strictly determined point
|
||||
//! (in the place of joint of two lines). As result, some gaps between two lines
|
||||
//! will vanish.
|
||||
//! The Walking lines are supposed (algorithm will do nothing for not-Walking line)
|
||||
//! to be computed as a result of intersection of two quadrics.
|
||||
//! The quadrics definition is accepted in input parameters.
|
||||
Standard_EXPORT static void ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& theSlin,
|
||||
const IntSurf_Quadric& theS1,
|
||||
const IntSurf_Quadric& theS2,
|
||||
const Standard_Real theToler3D,
|
||||
const Standard_Real theU1Period,
|
||||
const Standard_Real theU2Period,
|
||||
const Standard_Real theV1Period,
|
||||
const Standard_Real theV2Period);
|
||||
};
|
||||
|
||||
#endif
|
@ -57,7 +57,7 @@ Standard_Boolean IntSurf_PntOn2S::IsSame( const IntSurf_PntOn2S& theOterPoint,
|
||||
if(pt.SquareDistance(theOterPoint.Value()) > theTol3D*theTol3D)
|
||||
return Standard_False;
|
||||
|
||||
if(IsEqual(theTol2D, 0.0))
|
||||
if(theTol2D < 0.0)
|
||||
{//We need not compare 2D-coordinates of the points
|
||||
return Standard_True;
|
||||
}
|
||||
|
@ -74,8 +74,8 @@ public:
|
||||
|
||||
//! Returns TRUE if 2D- and 3D-coordinates of theOterPoint are equal to
|
||||
//! corresponding coordinates of me (with given tolerance).
|
||||
//! If theTol2D == 0.0 we will compare 3D-points only.
|
||||
Standard_EXPORT Standard_Boolean IsSame (const IntSurf_PntOn2S& theOterPoint, const Standard_Real theTol3D = 0.0, const Standard_Real theTol2D = 0.0) const;
|
||||
//! If theTol2D < 0.0 we will compare 3D-points only.
|
||||
Standard_EXPORT Standard_Boolean IsSame (const IntSurf_PntOn2S& theOterPoint, const Standard_Real theTol3D = 0.0, const Standard_Real theTol2D = -1.0) const;
|
||||
|
||||
|
||||
|
||||
|
34
tests/bugs/modalg_6/bug27282_1
Normal file
34
tests/bugs/modalg_6/bug27282_1
Normal file
@ -0,0 +1,34 @@
|
||||
puts "TODO OCC27300 ALL: ERROR. result is not valid for BOP"
|
||||
|
||||
puts "============"
|
||||
puts "OCC27282"
|
||||
puts "============"
|
||||
puts ""
|
||||
###############################
|
||||
## [Regression to 6.9.1] smesh/bugs_00/A6: Cut produces an empty shape
|
||||
###############################
|
||||
|
||||
restore [locate_data_file bug27282_cmpd.brep] a
|
||||
explode a
|
||||
|
||||
bclearobjects
|
||||
bcleartools
|
||||
baddobjects a_1
|
||||
baddtools a_2
|
||||
|
||||
bfillds
|
||||
|
||||
# CUT-operation
|
||||
bbop result 2
|
||||
|
||||
set log [bopargcheck result #F]
|
||||
|
||||
if { [string compare -nocase $log "Shape(s) seem(s) to be valid for BOP.\n"] } {
|
||||
puts "ERROR. result is not valid for BOP"
|
||||
}
|
||||
|
||||
checkshape result
|
||||
checknbshapes result -solid 1 -face 4
|
||||
checkprops result -v 2.96079e+007
|
||||
|
||||
checkview -display result -2d -path ${imagedir}/${test_image}.png
|
47
tests/bugs/modalg_6/bug27282_2
Normal file
47
tests/bugs/modalg_6/bug27282_2
Normal file
@ -0,0 +1,47 @@
|
||||
puts "TODO OCC27302 ALL: Error: Curve Number is bad!"
|
||||
|
||||
puts "============"
|
||||
puts "OCC27282"
|
||||
puts "============"
|
||||
puts ""
|
||||
###############################
|
||||
## [Regression to 6.9.1] smesh/bugs_00/A6: Cut produces an empty shape
|
||||
###############################
|
||||
|
||||
set MaxTol 4.8106951786435371e-006
|
||||
set GoodNbCurv 1
|
||||
|
||||
restore [locate_data_file bug27282_cmpd.brep] a
|
||||
explode a f
|
||||
|
||||
smallview
|
||||
don a_2 a_5
|
||||
fit
|
||||
|
||||
set log [bopcurves a_2 a_5 -2d]
|
||||
|
||||
regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv
|
||||
|
||||
checkreal ToleranceReached ${Toler} ${MaxTol} 0.0 0.1
|
||||
|
||||
checkview -screenshot -2d -path ${imagedir}/${test_image}.png
|
||||
|
||||
if {${NbCurv} != ${GoodNbCurv}} {
|
||||
puts "Error: Curve Number is bad!"
|
||||
|
||||
for {set i 1} {$i < ${NbCurv}} {incr i} {
|
||||
for {set j [expr $i+1]} {$j <= $NbCurv} {incr j} {
|
||||
mkedge e1 c_$i
|
||||
mkedge e2 c_$j
|
||||
|
||||
dset dd_val 100.0*${Toler}
|
||||
distmini dd e1 e2
|
||||
|
||||
if { [dval dd_val] > ${Toler} } {
|
||||
puts "Error: Intersection result is not closed"
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
checklength c_1 -l 833.56846559428755
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user