mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
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.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -457,6 +523,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;
|
||||
|
||||
Standard_Real aStepMin = 0.1 * aStep, aStepMax = 10.0 * aStep;
|
||||
|
||||
@@ -489,6 +557,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;
|
||||
}
|
||||
@@ -617,6 +688,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;
|
||||
}
|
||||
@@ -656,6 +748,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)
|
||||
@@ -760,6 +861,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;
|
||||
|
Reference in New Issue
Block a user