AppParCurves_Constraint myfirstC;
AppParCurves_Constraint mylastC;
Standard_Integer myMultiLineNb;
- Standard_Integer myNbPlusOnePoint;
Standard_Boolean myIsClear;
{
const Standard_Integer nbp3d = LineTool::NbP3d(theLine);
const Standard_Integer nbp2d = LineTool::NbP2d(theLine);
+
+ const Standard_Real coeff = 4.; //2*2
if (nbp3d > 1) //only simple cases are analysed
return Standard_True;
//Check: may be it is a real loop
if (LoopFound)
{
+#ifdef DRAW
+ for (Standard_Integer ipoint = theIndfirst; ipoint <= theIndlast; ipoint++)
+ {
+ LineTool::Value(theLine, ipoint, tabP);
+ gp_Pnt aPnt = tabP(1);
+ sprintf(name, "p%d", ipoint);
+ DrawTrSurf::Set(name, aPnt);
+ }
+#endif
for (Standard_Integer FirstInd = theIndfirst;
FirstInd <= theIndlast - 2; FirstInd++)
{
{
//search <indbad>
Standard_Real MaxSqDist = 0.;
+ Standard_Real MinSqDist = RealLast();
for (Standard_Integer k = theIndfirst+1; k <= theIndlast; k++)
{
LineTool::Value(theLine, k-1, tabP);
MaxSqDist = aSqDist;
indbads[1] = k;
}
+ if (aSqDist > gp::Resolution() &&
+ aSqDist < MinSqDist)
+ MinSqDist = aSqDist;
}
- for (Standard_Integer indcur = 2; indcur <= NbCur; indcur++)
- {
- MaxSqDist = 0.;
- for (Standard_Integer k = theIndfirst+1; k <= theIndlast; k++)
+ Standard_Real Relation = MaxSqDist / MinSqDist;
+ if (Relation < coeff)
+ LoopFound = Standard_False;
+ else
+ for (Standard_Integer indcur = 2; indcur <= NbCur; indcur++)
{
- LineTool::Value(theLine, k-1, tabP2d);
- gp_Pnt2d PrevPnt = tabP2d(indcur-1);
- LineTool::Value(theLine, k, tabP2d);
- gp_Pnt2d CurPnt = tabP2d(indcur-1);
- Standard_Real aSqDist = PrevPnt.SquareDistance(CurPnt);
- if (aSqDist > MaxSqDist)
+ MaxSqDist = 0.;
+ for (Standard_Integer k = theIndfirst+1; k <= theIndlast; k++)
{
- MaxSqDist = aSqDist;
- indbads[indcur] = k;
+ LineTool::Value(theLine, k-1, tabP2d);
+ gp_Pnt2d PrevPnt = tabP2d(indcur-1);
+ LineTool::Value(theLine, k, tabP2d);
+ gp_Pnt2d CurPnt = tabP2d(indcur-1);
+ Standard_Real aSqDist = PrevPnt.SquareDistance(CurPnt);
+ if (aSqDist > MaxSqDist)
+ {
+ MaxSqDist = aSqDist;
+ indbads[indcur] = k;
+ }
}
}
- }
}
} //if (myNbP3d == 1)
else //2d case
//Check: may be it is a real loop
if (LoopFound)
{
+#ifdef DRAW
+ for (Standard_Integer ipoint = theIndfirst; ipoint <= theIndlast; ipoint++)
+ {
+ LineTool::Value(theLine, ipoint, tabP2d);
+ gp_Pnt2d aPnt2d = tabP2d(1);
+ sprintf(name, "p%d", ipoint);
+ DrawTrSurf::Set(name, aPnt2d);
+ }
+#endif
for (Standard_Integer FirstInd = theIndfirst;
FirstInd <= theIndlast - 2; FirstInd++)
{
for (Standard_Integer indcur = 1; indcur <= NbCur; indcur++)
{
Standard_Real MaxSqDist = 0.;
+ Standard_Real MinSqDist = RealLast();
for (Standard_Integer k = theIndfirst+1; k <= theIndlast; k++)
{
LineTool::Value(theLine, k-1, tabP2d);
MaxSqDist = aSqDist;
indbads[indcur] = k;
}
+ if (aSqDist > gp::Resolution() &&
+ aSqDist < MinSqDist)
+ MinSqDist = aSqDist;
}
+ Standard_Real Relation = MaxSqDist / MinSqDist;
+ if (Relation < coeff)
+ LoopFound = Standard_False;
}
}
}
//Define <indbad>
- if (indbads[1] != 0 && indbads[2] != 0)
- {
- if (indbads[1] != indbads[2])
- LoopFound = Standard_False;
- else if (indbads[3] != 0 && indbads[1] != indbads[3])
- LoopFound = Standard_False;
- }
- if (LoopFound)
- theIndbad = indbads[1];
+ for (Standard_Integer i = 1; i <= 3; i++)
+ if (indbads[i] != 0)
+ {
+ theIndbad = indbads[i];
+ break;
+ }
+
+ if (!LoopFound)
+ theIndbad = 0;
return (!LoopFound);
}
const Standard_Boolean cutting,
const Standard_Boolean Squares)
: myMultiLineNb (0),
- myNbPlusOnePoint (0),
myIsClear (Standard_False)
{
myfirstParam = new TColStd_HArray1OfReal(Parameters.Lower(),
const Standard_Boolean cutting,
const Standard_Boolean Squares)
: myMultiLineNb (0),
- myNbPlusOnePoint (0),
myIsClear (Standard_False)
{
myfirstParam = new TColStd_HArray1OfReal(Parameters.Lower(),
const Approx_ParametrizationType parametrization,
const Standard_Boolean Squares)
: myMultiLineNb (0),
- myNbPlusOnePoint (0),
myIsClear (Standard_False)
{
myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
const Approx_ParametrizationType parametrization,
const Standard_Boolean Squares)
: myMultiLineNb (0),
- myNbPlusOnePoint (0),
myIsClear (Standard_False)
{
myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
Tolers3d.Clear();
Tolers2d.Clear();
myMultiLineNb = 0;
- //myNbPlusOnePoint = 0;
}
else myIsClear = Standard_False;
{
myIsClear = Standard_True;
//++myMultiLineNb;
- myNbPlusOnePoint++;
Perform(anOtherLine0);
alldone = Standard_True;
}
{
myIsClear = Standard_True;
//++myMultiLineNb;
- myNbPlusOnePoint++;
Par = SavePar;
Perform(anOtherLine2);
Ok = Standard_True;
{
myIsClear = Standard_True;
//++myMultiLineNb;
- myNbPlusOnePoint++;
Perform (anOtherLine2);
Ok = Standard_True;
}
{
myIsClear = Standard_True;
//++myMultiLineNb;
- myNbPlusOnePoint++;
Perform(anOtherLine3);
myfirstpt = mylastpt;
mylastpt = Thelastpt;
}
TheMultiCurve = AppParCurves_MultiCurve();
- MultiLine anOtherLine4;
- Standard_Boolean isOtherLine4Made = Standard_False;
Standard_Integer indbad = 0;
Ok = Compute(Line, myfirstpt, mylastpt, Param, thetol3d, thetol2d, indbad);
- if (indbad != 0)
- {
- isOtherLine4Made = LineTool::MakeMLOneMorePoint (Line, myfirstpt, mylastpt, indbad, anOtherLine4);
- }
- if (isOtherLine4Made)
- {
- myIsClear = Standard_True;
- //++myMultiLineNb;
- myNbPlusOnePoint++;
- Perform (anOtherLine4);
- Ok = Standard_True;
- }
if (myfirstpt == Thelastpt)
{
Finish = Standard_True;
#ifdef OCCT_DEBUG
if (mydebug) DUMP(mySCU);
#endif
- if (myNbPlusOnePoint != 0 &&
- !CheckMultiCurve(mySCU, Line,
+ if (!CheckMultiCurve(mySCU, Line,
fpt, lpt,
indbad))
{
//! Removes indices of vertices that are already on the
//! curve <theNC> from the map <theMV>.
//! It is used in PutEFPavesOnCurve and PutStickPavesOnCurve methods.
- Standard_EXPORT void RemoveUsedVertices (BOPDS_Curve& theNC, TColStd_MapOfInteger& theMV);
+ Standard_EXPORT void RemoveUsedVertices (const BOPDS_Curve& theNC, TColStd_MapOfInteger& theMV);
//! Puts the pave nV on the curve theNC.
aPF.SetNonDestructive(myNonDestructive);
//
BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
+ Standard_Integer aNbFF = aFFs.Length();
//
+
+ //Find unused vertices
+ TopTools_IndexedMapOfShape VertsUnused;
+ TColStd_MapOfInteger IndMap;
+ for (Standard_Integer i = 0; i < aNbFF; i++)
+ {
+ BOPDS_InterfFF& aFF = aFFs(i);
+ Standard_Integer nF1, nF2;
+ aFF.Indices(nF1, nF2);
+
+ TColStd_MapOfInteger aMV, aMVEF, aMI;
+ GetStickVertices(nF1, nF2, aMV, aMVEF, aMI);
+ BOPDS_VectorOfCurve& aVC = aFF.ChangeCurves();
+ Standard_Integer aNbC = aVC.Length();
+ for (j = 0; j < aNbC; j++)
+ {
+ BOPDS_Curve& aNC = aVC.ChangeValue(j);
+ RemoveUsedVertices(aNC, aMV);
+ }
+
+ TColStd_MapIteratorOfMapOfInteger itmap(aMV);
+ for(; itmap.More(); itmap.Next())
+ {
+ Standard_Integer indV = itmap.Value();
+ const TopoDS_Shape& aVertex = myDS->Shape(indV);
+ if (IndMap.Add(indV))
+ VertsUnused.Add(aVertex);
+ else
+ VertsUnused.RemoveKey(aVertex);
+ }
+ }
+ /////////////////////
+
Standard_Integer aNbME = theMicroEdges.Extent();
Standard_Integer aNbVOnRPB = theVertsOnRejectedPB.Extent();
// 0
- if (aNbS==1 && (aNbME == 0) && (aNbVOnRPB == 0)) {
+ if (aNbS==1 && (aNbME == 0) && (aNbVOnRPB == 0) && VertsUnused.IsEmpty()) {
const TopoDS_Shape& aS=theMSCPB.FindKey(1);
const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromIndex(1);
//
// Add vertices put on the real section curves to unify them with the
// vertices of the edges, by which these sections curves have been rejected
- for (Standard_Integer i = 1; i <= aNbVOnRPB; ++i)
+ // and with unused vertices
+ const TopTools_IndexedMapOfShape* VerMap [2] = {&theVertsOnRejectedPB, &VertsUnused};
+ for (Standard_Integer imap = 0; imap < 2; imap++)
{
- TopoDS_Shape aVer = theVertsOnRejectedPB(i);
- Standard_Integer iVer = myDS->Index(aVer);
- const Standard_Integer* pSD = aDMNewSD.Seek(iVer);
- if (pSD)
- aVer = myDS->Shape(*pSD);
-
- if (anAddedSD.Add(aVer))
- aLS.Append(aVer);
+ Standard_Integer NbVer = VerMap[imap]->Extent();
+ for (Standard_Integer i = 1; i <= NbVer; ++i)
+ {
+ TopoDS_Shape aVer = VerMap[imap]->FindKey(i);
+ Standard_Integer iVer = myDS->Index(aVer);
+ const Standard_Integer* pSD = aDMNewSD.Seek(iVer);
+ if (pSD)
+ aVer = myDS->Shape(*pSD);
+
+ if (anAddedSD.Add(aVer))
+ aLS.Append(aVer);
+ }
}
//
// 2 Fuse shapes
// function: RemoveUsedVertices
// purpose:
//=======================================================================
-void BOPAlgo_PaveFiller::RemoveUsedVertices(BOPDS_Curve& aNC,
+void BOPAlgo_PaveFiller::RemoveUsedVertices(const BOPDS_Curve& aNC,
TColStd_MapOfInteger& aMV)
{
if (!aMV.Extent()) {
return;
}
- Standard_Integer nV;
- BOPDS_Pave aPave;
- BOPDS_ListIteratorOfListOfPave aItLP;
- //
- Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
- const BOPDS_ListOfPave& aLP = aPB->ExtPaves();
- aItLP.Initialize(aLP);
- for (;aItLP.More();aItLP.Next()) {
- aPave = aItLP.Value();
- nV = aPave.Index();
- aMV.Remove(nV);
+
+ const BOPDS_ListOfPaveBlock& aLPBC = aNC.PaveBlocks();
+ BOPDS_ListIteratorOfListOfPaveBlock itPB(aLPBC);
+ for (; itPB.More(); itPB.Next())
+ {
+ const BOPDS_ListOfPave& aLP = itPB.Value()->ExtPaves();
+ BOPDS_ListIteratorOfListOfPave aItLP(aLP);
+ for (;aItLP.More();aItLP.Next()) {
+ BOPDS_Pave aPave = aItLP.Value();
+ Standard_Integer nV = aPave.Index();
+ aMV.Remove(nV);
+ }
}
}
AppParCurves_Constraint myfirstC;
AppParCurves_Constraint mylastC;
Standard_Integer myMultiLineNb;
- Standard_Integer myNbPlusOnePoint;
Standard_Boolean myIsClear;
: myNbrestr(0),
myTolReached2d(0.0),
myTolReached3d(0.0),
- myTolCheck(0.0000001),
- myTolAngCheck(0.3)
+ myTolCheck(1.e-7),
+ myTolAngCheck(1.e-6)
{}
//=======================================================================
: myNbrestr(0),
myTolReached2d(0.0),
myTolReached3d(0.0),
- myTolCheck(0.0000001),
- myTolAngCheck(0.3)
+ myTolCheck(1.e-7),
+ myTolAngCheck(1.e-6)
{
Perform(S1,S2,Tol,Approx,ApproxS1,ApproxS2);
}
AppParCurves_Constraint myfirstC;
AppParCurves_Constraint mylastC;
Standard_Integer myMultiLineNb;
- Standard_Integer myNbPlusOnePoint;
Standard_Boolean myIsClear;
//purpose :
//=======================================================================
GeomLib_Check2dBSplineCurve::GeomLib_Check2dBSplineCurve(const Handle(Geom2d_BSplineCurve)& Curve,
- const Standard_Real Tolerance,
- const Standard_Real AngularTolerance)
-:myCurve(Curve),
-myDone(Standard_False),
-myFixFirstTangent(Standard_False),
-myFixLastTangent(Standard_False),
-myAngularTolerance(Abs(AngularTolerance)),
-myTolerance(Abs(Tolerance)),
-myFirstPole(1.0,0.0e0),
-myLastPole(1.0e0,0.0e0)
+ const Standard_Real Tolerance,
+ const Standard_Real AngularTolerance)
+ : myCurve(Curve),
+ myDone(Standard_False),
+ myFixFirstTangent(Standard_False),
+ myFixLastTangent(Standard_False),
+ myAngularTolerance(Abs(AngularTolerance)),
+ myTolerance(Abs(Tolerance)),
+ myIndSecondPole(-1),
+ myIndPrelastPole(-1)
{
-
-
Standard_Integer ii,
num_poles ;
Standard_Real tangent_magnitude,
value,
- angular_value,
- factor,
vector_magnitude ;
- num_poles = Curve->NbPoles() ;
+ num_poles = myCurve->NbPoles() ;
+
if (( ! myCurve->IsPeriodic() )&& num_poles >= 4) {
- gp_Vec2d tangent,
- diff,
- a_vector;
- for (ii = 1 ; ii <= 2 ; ii++) {
- tangent.SetCoord(ii,myCurve->Pole(2).Coord(ii) - myCurve->Pole(1).Coord(ii)) ;
- a_vector.SetCoord(ii, myCurve->Pole(3).Coord(ii) - myCurve->Pole(1).Coord(ii)) ;
- }
+ gp_Vec2d tangent, tangent_normalized,
+ a_vector, avector_normalized;
+
+ const Standard_Real CrossProdTol = myAngularTolerance;
+
+ //Near first
+ tangent = gp_Vec2d(myCurve->Pole(1), myCurve->Pole(2));
tangent_magnitude = tangent.Magnitude() ;
- vector_magnitude = a_vector.Magnitude() ;
- if (tangent_magnitude > myTolerance &&
- vector_magnitude > myTolerance)
+ if (tangent_magnitude > myTolerance)
+ tangent_normalized = tangent/tangent_magnitude;
+
+ for (ii = 3; ii <= num_poles; ii++)
+ {
+ a_vector = gp_Vec2d(myCurve->Pole(1), myCurve->Pole(ii));
+ vector_magnitude = a_vector.Magnitude() ;
+
+ if (tangent_magnitude > myTolerance &&
+ vector_magnitude > myTolerance)
{
+ avector_normalized = a_vector/vector_magnitude;
+
+ Standard_Real CrossProd = tangent_normalized ^ avector_normalized;
+ if (Abs(CrossProd) > CrossProdTol)
+ break;
+
value = tangent.Dot(a_vector) ;
- if ( value < 0.0e0) {
- for (ii = 1 ; ii <= 2 ; ii++) {
- diff.SetCoord(ii, (tangent.Coord(ii) / tangent_magnitude) + (a_vector.Coord(ii) / vector_magnitude)) ;
- }
- angular_value =
- diff.Magnitude() ;
- if (angular_value < myAngularTolerance) {
- myFixFirstTangent = Standard_True ;
- factor = 1.0e0 ;
- if (tangent_magnitude > 0.5e0 * vector_magnitude) {
- factor = 0.5e0 * vector_magnitude / tangent_magnitude ;
- }
- for (ii = 1 ; ii <= 2 ; ii++) {
- myFirstPole.SetCoord(ii, myCurve->Pole(1).Coord(ii) - factor * tangent.Coord(ii)) ;
- }
- }
-
- }
+ if ( value < 0.0e0)
+ {
+ myFixFirstTangent = Standard_True ;
+ myIndSecondPole = ii;
+ break;
+ }
}
- for (ii = 1 ; ii <= 2 ; ii++) {
- tangent.SetCoord(ii,myCurve->Pole(num_poles-1).Coord(ii) - myCurve->Pole(num_poles).Coord(ii)) ;
- a_vector.SetCoord(ii, myCurve->Pole(num_poles-2).Coord(ii) - myCurve->Pole(num_poles).Coord(ii)) ;
}
+
+ //Near last
+ tangent = gp_Vec2d(myCurve->Pole(num_poles), myCurve->Pole(num_poles-1));
tangent_magnitude = tangent.Magnitude() ;
- vector_magnitude = a_vector.Magnitude() ;
+ if (tangent_magnitude > myTolerance)
+ tangent_normalized = tangent/tangent_magnitude;
+
+ for (ii = num_poles-2; ii >= 1; ii--)
+ {
+ a_vector = gp_Vec2d(myCurve->Pole(num_poles), myCurve->Pole(ii));
+ vector_magnitude = a_vector.Magnitude() ;
- if (tangent_magnitude > myTolerance &&
- vector_magnitude > myTolerance)
+ if (tangent_magnitude > myTolerance &&
+ vector_magnitude > myTolerance)
{
+ avector_normalized = a_vector/vector_magnitude;
+
+ Standard_Real CrossProd = tangent_normalized ^ avector_normalized;
+ if (Abs(CrossProd) > CrossProdTol)
+ break;
+
value = tangent.Dot(a_vector) ;
- if (value < 0.0e0) {
- for (ii = 1 ; ii <= 2 ; ii++) {
- diff.SetCoord(ii, (tangent.Coord(ii) / tangent_magnitude) + (a_vector.Coord(ii) / vector_magnitude)) ;
- }
- angular_value =
- diff.Magnitude() ;
- if ( angular_value < myAngularTolerance) {
- myFixLastTangent = Standard_True ;
- factor = 1.0e0 ;
- if (tangent_magnitude > 0.5e0 * vector_magnitude) {
- factor = 0.5e0 * vector_magnitude / tangent_magnitude ;
- }
- for (ii = 1 ; ii <= 2 ; ii++) {
- myLastPole.SetCoord(ii, myCurve->Pole(num_poles).Coord(ii) - factor * tangent.Coord(ii)) ;
- }
- }
-
+ if (value < 0.0e0)
+ {
+ myFixLastTangent = Standard_True ;
+ myIndPrelastPole = ii;
+ break;
}
}
-
- }
+ }
+ } //if (( ! myCurve->IsPeriodic() )&& num_poles >= 4)
else {
myDone = Standard_True ;
}
}
-
+
//=======================================================================
//function : NeedTangentFix
//purpose :
Standard_Boolean & LastFlag) const
{
FirstFlag = myFixFirstTangent ;
- LastFlag = myFixLastTangent ;
+ LastFlag = myFixLastTangent ;
}
+
//=======================================================================
//function : FixTangent
//purpose :
//=======================================================================
Handle(Geom2d_BSplineCurve) GeomLib_Check2dBSplineCurve::FixedTangent(const Standard_Boolean FirstFlag,
- const Standard_Boolean LastFlag)
-{
+ const Standard_Boolean LastFlag)
+{
Handle(Geom2d_BSplineCurve) new_curve ;
if ((myFixFirstTangent && FirstFlag) ||(myFixLastTangent && LastFlag)) {
new_curve =
Handle(Geom2d_BSplineCurve)::DownCast(myCurve->Copy()) ;
+ FixTangentOnCurve(new_curve, FirstFlag, LastFlag);
}
- if (myFixFirstTangent && FirstFlag) {
- new_curve->SetPole(2,
- myFirstPole) ;
- }
- if (myFixLastTangent && LastFlag) {
- Standard_Integer num_poles = myCurve->NbPoles() ;
- new_curve->SetPole(num_poles-1,
- myLastPole) ;
- }
-
- myDone = Standard_True ;
return new_curve ;
-}
+}
+
//=======================================================================
//function : FixTangent
//purpose :
//=======================================================================
void GeomLib_Check2dBSplineCurve::FixTangent(const Standard_Boolean FirstFlag,
- const Standard_Boolean LastFlag)
-{
+ const Standard_Boolean LastFlag)
+{
+ FixTangentOnCurve(myCurve, FirstFlag, LastFlag);
+}
+
+//=======================================================================
+//function : FixTangentOnCurve
+//purpose :
+//=======================================================================
+void GeomLib_Check2dBSplineCurve::FixTangentOnCurve(Handle(Geom2d_BSplineCurve)& theCurve,
+ const Standard_Boolean FirstFlag,
+ const Standard_Boolean LastFlag)
+{
if (myFixFirstTangent && FirstFlag) {
- myCurve->SetPole(2,
- myFirstPole) ;
+ gp_XY XY1 = theCurve->Pole(1).XY();
+ gp_XY XY2 = theCurve->Pole(myIndSecondPole).XY();
+ Standard_Real NbSamples = myIndSecondPole - 1;
+ for (Standard_Integer i = 2; i < myIndSecondPole; i++)
+ {
+ Standard_Real ii = i-1;
+ gp_Pnt2d aNewPole((1. - ii/NbSamples)*XY1 + ii/NbSamples*XY2);
+ theCurve->SetPole(i, aNewPole);
+ }
}
+
if (myFixLastTangent && LastFlag) {
- Standard_Integer num_poles = myCurve->NbPoles() ;
- myCurve->SetPole(num_poles-1,
- myLastPole) ;
+ Standard_Integer num_poles = theCurve->NbPoles() ;
+
+ gp_XY XY1 = theCurve->Pole(num_poles).XY();
+ gp_XY XY2 = theCurve->Pole(myIndPrelastPole).XY();
+ Standard_Real NbSamples = num_poles - myIndPrelastPole;
+ for (Standard_Integer i = num_poles-1; i > myIndPrelastPole; i--)
+ {
+ Standard_Real ii = num_poles-i;
+ gp_Pnt2d aNewPole((1. - ii/NbSamples)*XY1 + ii/NbSamples*XY2);
+ theCurve->SetPole(i, aNewPole);
+ }
}
myDone = Standard_True ;
DEFINE_STANDARD_ALLOC
- Standard_EXPORT GeomLib_Check2dBSplineCurve(const Handle(Geom2d_BSplineCurve)& Curve, const Standard_Real Tolerance, const Standard_Real AngularTolerance);
+ Standard_EXPORT GeomLib_Check2dBSplineCurve(const Handle(Geom2d_BSplineCurve)& Curve,
+ const Standard_Real Tolerance,
+ const Standard_Real AngularTolerance);
Standard_Boolean IsDone() const;
private:
+ void FixTangentOnCurve(Handle(Geom2d_BSplineCurve)& theCurve,
+ const Standard_Boolean FirstFlag,
+ const Standard_Boolean LastFlag);
Handle(Geom2d_BSplineCurve) myCurve;
Standard_Boolean myFixLastTangent;
Standard_Real myAngularTolerance;
Standard_Real myTolerance;
- gp_Pnt2d myFirstPole;
- gp_Pnt2d myLastPole;
-
+ Standard_Integer myIndSecondPole;
+ Standard_Integer myIndPrelastPole;
};
GeomLib_CheckBSplineCurve::GeomLib_CheckBSplineCurve(const Handle(Geom_BSplineCurve)& Curve,
const Standard_Real Tolerance,
const Standard_Real AngularTolerance)
-:myCurve(Curve),
-myDone(Standard_False),
-myFixFirstTangent(Standard_False),
-myFixLastTangent(Standard_False),
-myAngularTolerance(Abs(AngularTolerance)),
-myTolerance(Abs(Tolerance)),
-myFirstPole(1.0,0.0e0,0.e0),
-myLastPole(1.0e0,0.0e0,0.e0)
+ : myCurve(Curve),
+ myDone(Standard_False),
+ myFixFirstTangent(Standard_False),
+ myFixLastTangent(Standard_False),
+ myAngularTolerance(Abs(AngularTolerance)),
+ myTolerance(Abs(Tolerance)),
+ myIndSecondPole(-1),
+ myIndPrelastPole(-1)
{
-
-
Standard_Integer ii,
num_poles ;
Standard_Real tangent_magnitude,
value,
- angular_value,
- factor,
vector_magnitude ;
- num_poles = Curve->NbPoles() ;
+ num_poles = myCurve->NbPoles() ;
+
if (( ! myCurve->IsPeriodic() )&& num_poles >= 4) {
- gp_Vec tangent,
- diff,
- a_vector;
- for (ii = 1 ; ii <= 3 ; ii++) {
- tangent.SetCoord(ii,myCurve->Pole(2).Coord(ii) - myCurve->Pole(1).Coord(ii)) ;
- a_vector.SetCoord(ii, myCurve->Pole(3).Coord(ii) - myCurve->Pole(1).Coord(ii)) ;
- }
+ gp_Vec tangent, tangent_normalized,
+ a_vector, avector_normalized;
+
+ const Standard_Real CrossProdSqTol = myAngularTolerance*myAngularTolerance;
+
+ //Near first
+ tangent = gp_Vec(myCurve->Pole(1), myCurve->Pole(2));
tangent_magnitude = tangent.Magnitude() ;
- vector_magnitude = a_vector.Magnitude() ;
- if (tangent_magnitude > myTolerance &&
- vector_magnitude > myTolerance)
+ if (tangent_magnitude > myTolerance)
+ tangent_normalized = tangent/tangent_magnitude;
+
+ for (ii = 3; ii <= num_poles; ii++)
+ {
+ a_vector = gp_Vec(myCurve->Pole(1), myCurve->Pole(ii));
+ vector_magnitude = a_vector.Magnitude() ;
+
+ if (tangent_magnitude > myTolerance &&
+ vector_magnitude > myTolerance)
{
+ avector_normalized = a_vector/vector_magnitude;
+
+ gp_Vec CrossProd = tangent_normalized ^ avector_normalized;
+ Standard_Real CrossProdSqLength = CrossProd.SquareMagnitude();
+ if (CrossProdSqLength > CrossProdSqTol)
+ break;
+
value = tangent.Dot(a_vector) ;
- if ( value < 0.0e0) {
- for (ii = 1 ; ii <= 3 ; ii++) {
- diff.SetCoord(ii, (tangent.Coord(ii) / tangent_magnitude) + (a_vector.Coord(ii) / vector_magnitude)) ;
- }
- angular_value =
- diff.Magnitude() ;
- if (angular_value < myAngularTolerance) {
- myFixFirstTangent = Standard_True ;
- factor = 1.0e0 ;
- if (tangent_magnitude > 0.5e0 * vector_magnitude) {
- factor = 0.5e0 * vector_magnitude / tangent_magnitude ;
- }
- for (ii = 1 ; ii <= 3 ; ii++) {
- myFirstPole.SetCoord(ii, myCurve->Pole(1).Coord(ii) - factor * tangent.Coord(ii)) ;
- }
- }
-
+ if ( value < 0.0e0)
+ {
+ myFixFirstTangent = Standard_True ;
+ myIndSecondPole = ii;
+ break;
}
}
- for (ii = 1 ; ii <= 3 ; ii++) {
- tangent.SetCoord(ii,myCurve->Pole(num_poles-1).Coord(ii) - myCurve->Pole(num_poles).Coord(ii)) ;
- a_vector.SetCoord(ii, myCurve->Pole(num_poles-2).Coord(ii) - myCurve->Pole(num_poles).Coord(ii)) ;
}
+
+ //Near last
+ tangent = gp_Vec(myCurve->Pole(num_poles), myCurve->Pole(num_poles-1));
tangent_magnitude = tangent.Magnitude() ;
- vector_magnitude = a_vector.Magnitude() ;
-
- if (tangent_magnitude > myTolerance &&
- vector_magnitude > myTolerance)
+ if (tangent_magnitude > myTolerance)
+ tangent_normalized = tangent/tangent_magnitude;
+
+ for (ii = num_poles-2; ii >= 1; ii--)
+ {
+ a_vector = gp_Vec(myCurve->Pole(num_poles), myCurve->Pole(ii));
+ vector_magnitude = a_vector.Magnitude() ;
+
+ if (tangent_magnitude > myTolerance &&
+ vector_magnitude > myTolerance)
{
+ avector_normalized = a_vector/vector_magnitude;
+
+ gp_Vec CrossProd = tangent_normalized ^ avector_normalized;
+ Standard_Real CrossProdSqLength = CrossProd.SquareMagnitude();
+ if (CrossProdSqLength > CrossProdSqTol)
+ break;
+
value = tangent.Dot(a_vector) ;
- if (value < 0.0e0) {
- for (ii = 1 ; ii <= 3 ; ii++) {
- diff.SetCoord(ii, (tangent.Coord(ii) / tangent_magnitude) + (a_vector.Coord(ii) / vector_magnitude)) ;
- }
- angular_value =
- diff.Magnitude() ;
- if ( angular_value < myAngularTolerance) {
- myFixLastTangent = Standard_True ;
- factor = 1.0e0 ;
- if (tangent_magnitude > 0.5e0 * vector_magnitude) {
- factor = 0.5e0 * vector_magnitude / tangent_magnitude ;
- }
- for (ii = 1 ; ii <= 3 ; ii++) {
- myLastPole.SetCoord(ii, myCurve->Pole(num_poles).Coord(ii) - factor * tangent.Coord(ii)) ;
- }
- }
-
+ if (value < 0.0e0)
+ {
+ myFixLastTangent = Standard_True ;
+ myIndPrelastPole = ii;
+ break;
}
}
-
- }
+ }
+ } //if (( ! myCurve->IsPeriodic() )&& num_poles >= 4)
else {
myDone = Standard_True ;
}
Standard_Boolean & LastFlag) const
{
FirstFlag = myFixFirstTangent ;
- LastFlag = myFixLastTangent ;
+ LastFlag = myFixLastTangent ;
}
+
//=======================================================================
-//function : FixTangent
+//function : FixedTangent
//purpose :
//=======================================================================
Handle(Geom_BSplineCurve) GeomLib_CheckBSplineCurve::FixedTangent(const Standard_Boolean FirstFlag,
- const Standard_Boolean LastFlag)
+ const Standard_Boolean LastFlag)
{
Handle(Geom_BSplineCurve) new_curve ;
if ((myFixFirstTangent && FirstFlag) ||(myFixLastTangent && LastFlag)) {
new_curve =
Handle(Geom_BSplineCurve)::DownCast(myCurve->Copy()) ;
+ FixTangentOnCurve(new_curve, FirstFlag, LastFlag);
}
- if (myFixFirstTangent && FirstFlag) {
- new_curve->SetPole(2,
- myFirstPole) ;
- }
- if (myFixLastTangent && LastFlag) {
- Standard_Integer num_poles = myCurve->NbPoles() ;
- new_curve->SetPole(num_poles-1,
- myLastPole) ;
- }
-
- myDone = Standard_True ;
return new_curve ;
-}
+}
+
//=======================================================================
//function : FixTangent
//purpose :
//=======================================================================
void GeomLib_CheckBSplineCurve::FixTangent(const Standard_Boolean FirstFlag,
- const Standard_Boolean LastFlag)
+ const Standard_Boolean LastFlag)
+{
+ FixTangentOnCurve(myCurve, FirstFlag, LastFlag);
+}
+
+//=======================================================================
+//function : FixTangentOnCurve
+//purpose :
+//=======================================================================
+
+void GeomLib_CheckBSplineCurve::FixTangentOnCurve(Handle(Geom_BSplineCurve)& theCurve,
+ const Standard_Boolean FirstFlag,
+ const Standard_Boolean LastFlag)
{
-
if (myFixFirstTangent && FirstFlag) {
- myCurve->SetPole(2,
- myFirstPole) ;
+ gp_XYZ XYZ1 = theCurve->Pole(1).XYZ();
+ gp_XYZ XYZ2 = theCurve->Pole(myIndSecondPole).XYZ();
+ Standard_Real NbSamples = myIndSecondPole - 1;
+ for (Standard_Integer i = 2; i < myIndSecondPole; i++)
+ {
+ Standard_Real ii = i-1;
+ gp_Pnt aNewPole((1. - ii/NbSamples)*XYZ1 + ii/NbSamples*XYZ2);
+ theCurve->SetPole(i, aNewPole);
+ }
}
+
if (myFixLastTangent && LastFlag) {
- Standard_Integer num_poles = myCurve->NbPoles() ;
- myCurve->SetPole(num_poles-1,
- myLastPole) ;
+ Standard_Integer num_poles = theCurve->NbPoles() ;
+
+ gp_XYZ XYZ1 = theCurve->Pole(num_poles).XYZ();
+ gp_XYZ XYZ2 = theCurve->Pole(myIndPrelastPole).XYZ();
+ Standard_Real NbSamples = num_poles - myIndPrelastPole;
+ for (Standard_Integer i = num_poles-1; i > myIndPrelastPole; i--)
+ {
+ Standard_Real ii = num_poles-i;
+ gp_Pnt aNewPole((1. - ii/NbSamples)*XYZ1 + ii/NbSamples*XYZ2);
+ theCurve->SetPole(i, aNewPole);
+ }
}
myDone = Standard_True ;
DEFINE_STANDARD_ALLOC
- Standard_EXPORT GeomLib_CheckBSplineCurve(const Handle(Geom_BSplineCurve)& Curve, const Standard_Real Tolerance, const Standard_Real AngularTolerance);
+ Standard_EXPORT GeomLib_CheckBSplineCurve(const Handle(Geom_BSplineCurve)& Curve,
+ const Standard_Real Tolerance,
+ const Standard_Real AngularTolerance);
Standard_Boolean IsDone() const;
private:
+ void FixTangentOnCurve(Handle(Geom_BSplineCurve)& theCurve,
+ const Standard_Boolean FirstFlag,
+ const Standard_Boolean LastFlag);
Handle(Geom_BSplineCurve) myCurve;
Standard_Boolean myFixLastTangent;
Standard_Real myAngularTolerance;
Standard_Real myTolerance;
- gp_Pnt myFirstPole;
- gp_Pnt myLastPole;
-
+ Standard_Integer myIndSecondPole;
+ Standard_Integer myIndPrelastPole;
};
IntPatch_IType typl;
Handle(Geom_Curve) newc;
//
- const Standard_Real TOLCHECK =0.0000001;
- const Standard_Real TOLANGCHECK=0.1;
+ const Standard_Real TOLCHECK = 1.e-7;
+ const Standard_Real TOLANGCHECK = 1.e-6;
//
rejectSurface = Standard_False;
reApprox = Standard_False;
Handle(Geom2d_Curve)& PC1new, Handle(Geom2d_Curve)& PC2new,
Standard_Real& TolReached3d, Standard_Real& TolReached2d) const
{
+ const Standard_Real TOLCHECK = 1.e-7;
+ const Standard_Real TOLANGCHECK = 1.e-6;
+
Standard_Boolean CompC3D = myGeomTool.CompC3D();
//cout << "MakeCurves begin" << endl;
Handle(Geom_BSplineCurve) Curve (Handle(Geom_BSplineCurve)::DownCast(C3Dnew));
if(!Curve.IsNull()) {
- GeomLib_CheckBSplineCurve cbsc(Curve, 1.e-7, 0.1);
+ GeomLib_CheckBSplineCurve cbsc(Curve, TOLCHECK, TOLANGCHECK);
cbsc.NeedTangentFix(bf, bl);
#ifdef OCCT_DEBUG
Handle(Geom2d_BSplineCurve) Curve2df (Handle(Geom2d_BSplineCurve)::DownCast(PC1new));
if(!Curve2df.IsNull()) {
- GeomLib_Check2dBSplineCurve cbsc2df(Curve2df, 1.e-7, 0.1);
+ GeomLib_Check2dBSplineCurve cbsc2df(Curve2df, TOLCHECK, TOLANGCHECK);
cbsc2df.NeedTangentFix(bf, bl);
#ifdef OCCT_DEBUG
if (TopOpeBRepTool_GettraceCHKBSPL()) {
Handle(Geom2d_BSplineCurve) Curve2ds (Handle(Geom2d_BSplineCurve)::DownCast(PC2new));
if(!Curve2ds.IsNull()) {
- GeomLib_Check2dBSplineCurve cbsc2ds(Curve2ds, 1.e-7, 0.1);
+ GeomLib_Check2dBSplineCurve cbsc2ds(Curve2ds, TOLCHECK, TOLANGCHECK);
cbsc2ds.NeedTangentFix(bf, bl);
#ifdef OCCT_DEBUG
if (TopOpeBRepTool_GettraceCHKBSPL()) {
# Wrong pcurve of the section curve
###########################################################
-set ExpectedTol 9.8986150909815383e-05
set NbCurv_OK 1
restore [locate_data_file bug24585_b1.brep] b1
puts "Error: ${NbCurv_OK} curve(s) expected, but ${NbCurv} found."
}
-set tol_abs 0.0
-set tol_rel 0.01
-checkreal "Tolerance Reached" ${Toler} ${ExpectedTol} ${tol_abs} ${tol_rel}
+if { ${Toler} > 5.e-5} {
+ puts "Error: bad tolerance of result"
+}
bounds c2d1_1 U1 U2
2dcvalue c2d1_1 U1 U_begin V_begin
--- /dev/null
+puts "============"
+puts "OCC27079"
+puts "============"
+puts ""
+##################################################################
+# Bad approximation of intersection curves with variable curvature
+##################################################################
+
+restore [locate_data_file bug27079_s1.draw] s1
+restore [locate_data_file bug27079_s2.draw] s2
+trim ts1 s1 -5 5 0 20
+mkface f1 ts1
+mkface f2 s2
+
+smallview
+donly f1 f2
+fit
+
+bop f1 f2
+bopsection result
+
+checkprops result -l 13.7747
+checknbshapes result -vertex 4 -edge 3
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
--- /dev/null
+puts "============"
+puts "OCC27079"
+puts "============"
+puts ""
+##################################################################
+# Bad approximation of intersection curves with variable curvature
+##################################################################
+
+restore [locate_data_file bug27079_s3.draw] s3
+restore [locate_data_file bug27079_s4.draw] s4
+trim ts3 s3 pi-pi/30 pi -5 -2
+mkface f1 ts3
+mkface f2 s4
+
+smallview
+donly f1 f2
+fit
+
+bop f1 f2
+bopsection result
+
+checksection result
+checkprops result -l 8.5688
+checknbshapes result -vertex 2 -edge 2
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
pload ALL
-set MaxTol1 0.00042926432143107718
-set MaxTol2 0.00042926432143107718
-
set GoodNbCurv 4
restore [locate_data_file OCC13116_sh1.brep] b1
regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log1} full Toler NbCurv
-# Before fixing: Tolerance Reached=27.904993728420369
-checkreal ToleranceReached ${Toler} ${MaxTol1} 0.0 0.01
+if { ${Toler} > 0.0005} {
+ puts "Error: bad tolerance of result"
+}
smallview
don b1_3 b2_1 c_*
regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log2} full Toler NbCurv
-# Before fixing: Tolerance Reached=40.000000093341022
-checkreal ToleranceReached ${Toler} ${MaxTol2} 0.0 0.01
+if { ${Toler} > 0.0005} {
+ puts "Error: bad tolerance of result"
+}
smallview
don b1_3 b2_1 c_*
--- /dev/null
+puts "========"
+puts "OCC27648"
+puts "========"
+puts ""
+#################################################
+# Regression vs 6.7.1: General Fuse operation fails to fuse the solids
+#################################################
+
+restore [locate_data_file bug27648_simple.brep] s
+explode s
+bsection r s_1 s_2
+explode s_2 f
+
+# find section edge belonging to the face s_2_3
+foreach e [explode r e] {
+ if {[catch {mk2dcurve c2d $e s_2_3}] == 0} {
+ break
+ }
+}
+
+mkcurve c $e
+
+# in a loop, check that curve has increased Z value along its length
+set delta 0.001
+cvalue c 0 xp yp zp
+for {set p 0} {$p <= 1} {set p [expr $p + $delta]} {
+ cvalue c $p x y z
+ if {[dval z] < [dval zp]} {
+ puts "Error on parameter $p"
+ }
+ copy z zp
+}
\ No newline at end of file
-puts "TODO OCC28216 ALL: Error : bopcommon is WRONG"
-
puts "============"
puts "OCC28216"
puts "============"
bop s o
bopsection r_section
-checknbshapes r_section -vertex 4 -edge 3 -m "bopsection"
+checknbshapes r_section -vertex 4 -edge 4 -m "bopsection"
bopcheck r_section
bopcommon r_common
-checknbshapes r_common -vertex 4 -edge 3 -m "bopcommon"
+checknbshapes r_common -vertex 4 -edge 4 -face 1 -m "bopcommon"
bopcheck r_common
checkview -display r_section -2d -path ${imagedir}/${test_image}-section.png
--- /dev/null
+puts "============"
+puts "OCC29511"
+puts "============"
+puts ""
+##################################################################
+# Section fails for these two faces
+##################################################################
+
+restore [locate_data_file bug29511_face.brep] face
+restore [locate_data_file bug29511_prism.brep] prism
+
+bsection result face prism -n2d
+
+smallview
+donly result
+fit
+
+checkprops result -l 764.018
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png