Commit bb368e27 authored by jgv's avatar jgv Committed by smoskvin
Browse files

0032721: Modeling Algorithms - BOP wrong results on a cone and an extrusion

1. Modify method IntPatch_ALineToWLine::MakeWLine: add correction of end points of each line on 2 surfaces if an end point is a pole on a surface.
2. Modify method IntPatch_WLine::ComputeVertexParameters: adjust a point on curve to corresponding vertex the following way: set 3D point as the point of the vertex and 2D points as the points of the point on curve.
No related merge requests found
Showing with 230 additions and 30 deletions
+230 -30
......@@ -29,7 +29,7 @@
//function : AddPointIntoLine
//purpose :
//=======================================================================
static inline void AddPointIntoLine(Handle(IntSurf_LineOn2S) theLine,
static inline void AddPointIntoLine(Handle(IntSurf_LineOn2S)& theLine,
const Standard_Real* const theArrPeriods,
IntSurf_PntOn2S &thePoint,
IntPatch_Point* theVertex = 0)
......@@ -252,6 +252,69 @@ void IntPatch_ALineToWLine::SetTolOpenDomain(const Standard_Real aTol)
return myTolOpenDomain;
}
//=======================================================================
//function : CorrectEndPoint
//purpose :
//=======================================================================
void IntPatch_ALineToWLine::CorrectEndPoint(Handle(IntSurf_LineOn2S)& theLine,
const Standard_Integer theIndex) const
{
const Standard_Real aTol = 1.e-5;
const Standard_Real aSqTol = 1.e-10;
//Perform linear extrapolation from two previous points
Standard_Integer anIndFirst, anIndSecond;
if (theIndex == 1)
{
anIndFirst = 3;
anIndSecond = 2;
}
else
{
anIndFirst = theIndex - 2;
anIndSecond = theIndex - 1;
}
IntSurf_PntOn2S aPntOn2S = theLine->Value(theIndex);
for (Standard_Integer ii = 1; ii <= 2; ii++)
{
Standard_Boolean anIsOnFirst = (ii == 1);
const IntSurf_Quadric& aQuad = (ii == 1)? myQuad1 : myQuad2;
if (aQuad.TypeQuadric() == GeomAbs_Cone)
{
const gp_Cone aCone = aQuad.Cone();
const gp_Pnt anApex = aCone.Apex();
if (anApex.SquareDistance (aPntOn2S.Value()) > aSqTol)
continue;
}
else if (aQuad.TypeQuadric() == GeomAbs_Sphere)
{
Standard_Real aU, aV;
aPntOn2S.ParametersOnSurface(anIsOnFirst, aU, aV);
if (Abs(aV - M_PI/2) > aTol &&
Abs(aV + M_PI/2) > aTol)
continue;
}
else
continue;
gp_Pnt2d PrevPrevP2d = theLine->Value(anIndFirst).ValueOnSurface(anIsOnFirst);
gp_Pnt2d PrevP2d = theLine->Value (anIndSecond).ValueOnSurface(anIsOnFirst);
gp_Dir2d aDir = gp_Vec2d(PrevPrevP2d, PrevP2d);
Standard_Real aX0 = PrevPrevP2d.X(), aY0 = PrevPrevP2d.Y();
Standard_Real aXend, aYend;
aPntOn2S.ParametersOnSurface(anIsOnFirst, aXend, aYend);
if (Abs(aDir.Y()) < gp::Resolution())
continue;
Standard_Real aNewXend = aDir.X()/aDir.Y() * (aYend - aY0) + aX0;
theLine->SetUV (theIndex, anIsOnFirst, aNewXend, aYend);
}
}
//=======================================================================
//function : GetSectionRadius
//purpose :
......@@ -331,24 +394,27 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
#if 0
//To draw ALine as a wire DRAW-object use the following code.
{
static int zzz = 0;
zzz++;
static int ind = 0;
ind++;
bool flShow = /*(zzz == 1)*/false;
bool flShow = true;
if (flShow)
{
std::cout << " +++ DUMP ALine (begin) +++++" << std::endl;
Standard_Integer aI = 0;
const Standard_Real aStep = (theLPar - theFPar) / 9999.0;
for (Standard_Real aPrm = theFPar; aPrm < theLPar; aPrm += aStep)
const Standard_Integer NbSamples = 20;
const Standard_Real aStep = (theLPar - theFPar) / NbSamples;
char* name = new char[100];
for (Standard_Integer ii = 0; ii <= NbSamples; ii++)
{
Standard_Real aPrm = theFPar + ii * aStep;
const gp_Pnt aPP(theALine->Value(aPrm));
std::cout << "vertex v" << ++aI << " " << aPP.X() << " " << aPP.Y() << " " << aPP.Z() << std::endl;
}
std::cout << "vertex v" << ii << " " << aPP.X() << " " << aPP.Y() << " " << aPP.Z() << std::endl;
gp_Pnt aPP(theALine->Value(theLPar));
std::cout << "vertex v" << ++aI << " " << aPP.X() << " " << aPP.Y() << " " << aPP.Z() << std::endl;
sprintf(name, "p%d_%d", ii, ind);
Draw::Set(name, aPP);
}
std::cout << " --- DUMP ALine (end) -----" << std::endl;
}
}
......@@ -435,6 +501,8 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
Standard_Integer aNewVertID = 0;
aLinOn2S = new IntSurf_LineOn2S;
Standard_Boolean anIsFirstDegenerated = Standard_False,
anIsLastDegenerated = Standard_False;
const Standard_Real aStepMin = 0.1*aStep, aStepMax = 10.0*aStep;
......@@ -467,6 +535,9 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
{
// We cannot compute 2D-parameters of
// aPOn2S correctly.
if (anIsLastDegenerated) //the current last point is wrong
aLinOn2S->RemovePoint (aLinOn2S->NbPoints());
isPointValid = Standard_False;
}
......@@ -591,6 +662,27 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
AddPointIntoLine(aLinOn2S, anArrPeriods, aPOn2S);
aPrevLPoint = aPOn2S;
}
else
{
//add point, set correxponding status: to be corrected later
Standard_Boolean ToAdd = Standard_False;
if (aLinOn2S->NbPoints() == 0)
{
anIsFirstDegenerated = Standard_True;
ToAdd = Standard_True;
}
else if (aLinOn2S->NbPoints() > 1)
{
anIsLastDegenerated = Standard_True;
ToAdd = Standard_True;
}
if (ToAdd)
{
AddPointIntoLine(aLinOn2S, anArrPeriods, aPOn2S);
aPrevLPoint = aPOn2S;
}
}
continue;
}
......@@ -630,6 +722,15 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
aPrePointExist = IsPoleOrSeam(myS1, myS2, aPrefIso, aLinOn2S, aVtx,
anArrPeriods, aTol, aSingularSurfaceID);
if (aPrePointExist == IntPatch_SPntPole ||
aPrePointExist == IntPatch_SPntPoleSeamU)
{
//set correxponding status: to be corrected later
if (aLinOn2S->NbPoints() == 1)
anIsFirstDegenerated = Standard_True;
else
anIsLastDegenerated = Standard_True;
}
const Standard_Real aCurVertParam = aVtx.ParameterOnLine();
if(aPrePointExist != IntPatch_SPntNone)
......@@ -702,6 +803,15 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
continue;
}
//Correct first and last points if needed
if (aLinOn2S->NbPoints() >= 3)
{
if (anIsFirstDegenerated)
CorrectEndPoint (aLinOn2S, 1);
if (anIsLastDegenerated)
CorrectEndPoint (aLinOn2S, aLinOn2S->NbPoints());
}
//-----------------------------------------------------------------
//-- W L i n e c r e a t i o n ---
//-----------------------------------------------------------------
......
......@@ -20,6 +20,7 @@
#include <Adaptor3d_Surface.hxx>
#include <IntPatch_SequenceOfLine.hxx>
#include <IntSurf_Quadric.hxx>
#include <IntSurf_LineOn2S.hxx>
class IntPatch_ALine;
class IntSurf_PntOn2S;
......@@ -90,6 +91,13 @@ protected:
//! This check is made for cone and sphere only.
Standard_EXPORT Standard_Real GetSectionRadius(const gp_Pnt& thePnt3d) const;
//! Corrects the U-parameter of an end point (first or last) of the line
//! if this end point is a pole.
//! The line must contain at least 3 points.
//! This is made for cone and sphere only.
Standard_EXPORT void CorrectEndPoint(Handle(IntSurf_LineOn2S)& theLine,
const Standard_Integer theIndex) const;
private:
......
......@@ -471,8 +471,7 @@ void IntPatch_WLine::ComputeVertexParameters( const Standard_Real RTol)
//----------------------------------------------------
//-- On detecte les points confondus dans la LineOn2S
Standard_Real dmini = Precision::Confusion();
dmini*=dmini;
Standard_Real dmini = Precision::SquareConfusion();
for(i=2; (i<=nbponline) && (nbponline > 2); i++) {
const IntSurf_PntOn2S& aPnt1=curv->Value(i-1);
const IntSurf_PntOn2S& aPnt2=curv->Value(i);
......@@ -516,7 +515,20 @@ void IntPatch_WLine::ComputeVertexParameters( const Standard_Real RTol)
IntSurf_PntOn2S POn2S = svtx.Value(i).PntOn2S();
RecadreMemePeriode(POn2S,curv->Value(1),U1Period(),V1Period(),U2Period(),V2Period());
curv->Value(1,POn2S);
if (myCreationWay == IntPatch_WLImpImp)
{
//Adjust first point of curve to corresponding vertex the following way:
//set 3D point as the point of the vertex and 2D points as the points of the point on curve.
curv->SetPoint (1, POn2S.Value());
Standard_Real mu1,mv1,mu2,mv2;
curv->Value(1).Parameters(mu1,mv1,mu2,mv2);
svtx.ChangeValue(i).SetParameter(1);
svtx.ChangeValue(i).SetParameters(mu1,mv1,mu2,mv2);
}
else
{
curv->Value(1,POn2S);
}
//--curv->Value(1,svtx.Value(i).PntOn2S());
svtx.ChangeValue(i).SetParameter(1.0);
......@@ -551,6 +563,9 @@ void IntPatch_WLine::ComputeVertexParameters( const Standard_Real RTol)
//---------------------------------------------------------
Standard_Boolean Substitution = Standard_False;
//-- for(k=indicevertexonline+1; !Substitution && k>=indicevertexonline-1;k--) { avant le 9 oct 97
Standard_Real mu1,mv1,mu2,mv2;
curv->Value(indicevertexonline).Parameters(mu1,mv1,mu2,mv2);
for(k=indicevertexonline+1; k>=indicevertexonline-1;k--) {
if(k>0 && k<=nbponline) {
if(CompareVertexAndPoint(P,curv->Value(k).Value(),vTol)) {
......@@ -560,9 +575,21 @@ void IntPatch_WLine::ComputeVertexParameters( const Standard_Real RTol)
//-------------------------------------------------------
IntSurf_PntOn2S POn2S = svtx.Value(i).PntOn2S();
RecadreMemePeriode(POn2S,curv->Value(k),U1Period(),V1Period(),U2Period(),V2Period());
curv->Value(k,POn2S);
Standard_Real mu1,mv1,mu2,mv2;
POn2S.Parameters(mu1,mv1,mu2,mv2);
if (myCreationWay == IntPatch_WLImpImp)
{
//Adjust a point of curve to corresponding vertex the following way:
//set 3D point as the point of the vertex and 2D points as the points
//of the point on curve with index <indicevertexonline>
curv->SetPoint (k, POn2S.Value());
curv->SetUV (k, Standard_True, mu1, mv1);
curv->SetUV (k, Standard_False, mu2, mv2);
}
else
{
curv->Value(k,POn2S);
POn2S.Parameters(mu1,mv1,mu2,mv2);
}
svtx.ChangeValue(i).SetParameter(k);
svtx.ChangeValue(i).SetParameters(mu1,mv1,mu2,mv2);
Substitution = Standard_True;
......
......@@ -62,9 +62,14 @@ public:
//! Replaces the point of range Index in the line.
void Value (const Standard_Integer Index, const IntSurf_PntOn2S& P);
//! Sets the 3D point of the Index-th PntOn2S
Standard_EXPORT void SetPoint(const Standard_Integer Index, const gp_Pnt& thePnt);
//! Sets the parametric coordinates on one of the surfaces
//! of the point of range Index in the line.
Standard_EXPORT void SetUV(const Standard_Integer Index, const Standard_Boolean OnFirst, const Standard_Real U, const Standard_Real V);
Standard_EXPORT void SetUV(const Standard_Integer Index,
const Standard_Boolean OnFirst,
const Standard_Real U, const Standard_Real V);
void Clear();
......
......@@ -38,6 +38,12 @@ inline void IntSurf_LineOn2S::Value(const Standard_Integer Index,
mySeq(Index) = P;
}
inline void IntSurf_LineOn2S::SetPoint(const Standard_Integer Index,
const gp_Pnt& thePnt)
{
mySeq(Index).SetValue (thePnt);
}
inline void IntSurf_LineOn2S::Clear ()
{
mySeq.Clear();
......
......@@ -3,8 +3,6 @@ puts "0029807: Impossible to cut cone from prism"
puts "========"
puts ""
puts "TODO OCC29922 ALL: Error: Degenerated edge is not found"
restore [locate_data_file bug29807-obj.brep] b1
restore [locate_data_file bug29807-tool.brep] b2
......
......@@ -3,9 +3,6 @@ puts "0029807: Impossible to cut cone from prism"
puts "========"
puts ""
puts "TODO OCC29860 ALL: Error : is WRONG because number of WIRE entities in shape \"result\" is 10"
puts "TODO OCC29860 ALL: Error : is WRONG because number of FACE entities in shape \"result\" is 10"
restore [locate_data_file bug29807-obj.brep] b1
restore [locate_data_file bug29807-tool.brep] b2
......
puts "======================================================"
puts "OCC32721: BOP wrong results on a cone and an extrusion"
puts "======================================================"
puts ""
restore [locate_data_file bug32721.brep] prism
pcone cone 6 0 10
bop cone prism
bopfuse r1
bopcommon r2
bopcut r3
boptuc r4
checkshape r1
checknbshapes r1 -t -vertex 8 -edge 17 -wire 8 -face 8 -shell 1 -solid 1
checkshape r2
checknbshapes r2 -t -vertex 3 -edge 7 -wire 4 -face 4 -shell 1 -solid 1
checkshape r3
checknbshapes r3 -t -vertex 4 -edge 10 -wire 4 -face 4 -shell 1 -solid 1
checkshape r4
checknbshapes r4 -t -vertex 7 -edge 14 -wire 8 -face 8 -shell 2 -solid 2
set tolres [checkmaxtol r1]
if { ${tolres} > 0.0002} {
puts "Error: bad tolerance of result"
}
checkprops r1 -s 388.634 -v 406.357
checkprops r2 -s 57.8605 -v 22.8116
checkprops r3 -s 358.735 -v 354.179
checkprops r4 -s 87.7592 -v 29.3659
checkview -display r1 -2d -path ${imagedir}/${test_image}.png
\ No newline at end of file
......@@ -17,7 +17,9 @@ fit
regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b1_5 b2_2 -2d] full Toler NbCurv
checkreal Tolerance $Toler 0.00039718358540697849 0.0 0.01
if { ${Toler} > 0.0004} {
puts "Error: bad tolerance of result"
}
if {$NbCurv != 2} {
puts "Error: Please check NbCurves for intersector"
......
......@@ -17,7 +17,9 @@ fit
regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b1_5 b2_2 -2d] full Toler NbCurv
checkreal Tolerance $Toler 5.0314111870170835e-005 0.0 0.01
if { ${Toler} > 5.1e-5} {
puts "Error: bad tolerance of result"
}
if {$NbCurv != 2} {
puts "Error: Please check NbCurves for intersector"
......
......@@ -18,7 +18,9 @@ fit
regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b1_5 b2_2 -2d] full Toler NbCurv
checkreal Tolerance $Toler 0.00011289757099748416 0.0 0.01
if { ${Toler} > 0.000113} {
puts "Error: bad tolerance of result"
}
if {$NbCurv != 2} {
puts "Error: Please check NbCurves for intersector"
......
......@@ -18,7 +18,9 @@ fit
regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b1_5 b2_2 -2d] full Toler NbCurv
checkreal Tolerance $Toler 7.7125880147734232e-007 0.0 0.01
if { ${Toler} > 8e-7} {
puts "Error: bad tolerance of result"
}
if {$NbCurv != 2} {
puts "Error: Please check NbCurves for intersector"
......
......@@ -16,7 +16,9 @@ fit
regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b1_5 f2 -2d] full Toler NbCurv
checkreal Tolerance $Toler 0.00039718358530349535 0.0 0.01
if { ${Toler} > 0.0004} {
puts "Error: bad tolerance of result"
}
if {$NbCurv != 2} {
puts "Error: Please check NbCurves for intersector"
......
......@@ -17,7 +17,9 @@ fit
regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b1_5 f2 -2d] full Toler NbCurv
checkreal Tolerance $Toler 0.00011289757087827709 0.0 0.01
if { ${Toler} > 0.000113} {
puts "Error: bad tolerance of result"
}
if {$NbCurv != 2} {
puts "Error: Please check NbCurves for intersector"
......
......@@ -17,7 +17,9 @@ fit
regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b1_5 f2 -2d] full Toler NbCurv
checkreal Tolerance $Toler 7.7124681583892622e-007 0.0 0.01
if { ${Toler} > 8e-7} {
puts "Error: bad tolerance of result"
}
if {$NbCurv != 2} {
puts "Error: Please check NbCurves for intersector"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment