1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-29 14:00:49 +03:00

Compare commits

...

12 Commits

Author SHA1 Message Date
nbv
204e98c0b1 0029887: Wrong result of CUT operation due to incorrect point-face classification
Using of input tolerance has been eliminated in Geom2dInt_GInter algorithm called from BRepClass_Intersector::Perform(...) method. Now, the input tolerance is used only for check ON-status of classification.

(cherry picked from commit 748c9dc6ae0d6018018fca585b6d8cf511c0dd0b)
2018-06-21 10:01:04 +03:00
nbv
22f9125e1e Correction of test cases. 2018-02-15 15:15:29 +03:00
nbv
1a196a871d 0029510: IntWalk_PWalking:: PutToBoundary(...) method results in appearing several coincident points in Walking-line
Places have been detected where coincident points are created. The problem has been fixed.

(cherry picked from commit 7c7cda9f73f8762d4999657a925f65cd02bc6864)
2018-02-15 14:47:12 +03:00
nbv
5eba99e74b 0029494: Intersection line between two parametric surfaces is restricted incorrectly if it matches the surface boundary
Creation of IntPatch_Points is forbidden in tangent-zones exceptionally domain boundaries of intersected surface.

(cherry picked from commit 2123a44c2595633288e208a352050592710782f5)
2018-02-15 10:48:00 +03:00
nbv
1560ac5528 # Correction in test cases and documentation.
(cherry picked from commit b244aa455edc4b973457be365ef95bb475523654)
2018-02-14 14:59:37 +03:00
nbv
4b46072ae9 # Correction of test case
(cherry picked from commit 663b5da04a351f0ba1ffc8b26c7df818ad56545b)
2018-02-14 14:57:29 +03:00
nbv
eed77ff55c 0029496: No intersection curve between faces if starting points are given
Now, bounded IntPatch_Points are found in case when starting points are used in intersection algorithm. Before the fix, these points were not looked for (even).

(cherry picked from commit e6a1e86e7b926937f6773d45ed75a2c36d0e7c27)
2018-02-14 14:55:55 +03:00
emv
118e720920 0029488: Regression: boolean operation " general fuse" creates solid containing 5 not connected shells lying on the one level.
Boolean Operations - when checking two faces with the same bounds on Same Domain, take into account possible deviation of the edges from the faces surfaces.

Test cases for the issue.

(cherry picked from commit 8a7476a622)
2018-02-14 11:47:31 +03:00
gka
80f77ed256 # Modified scripts 2018-02-05 17:27:12 +03:00
emv
8f87d4a954 0029465: Regression relation to 691 version: Extrema_ExtCC returns IsParallel equal to true for not parallel curves
Strengthening of the criteria of the parallel status of the curves by additional checking if the ends of the curves do not diverge.

Test cases for the issue.
2018-02-05 11:20:31 +03:00
gka
eeccb2515d 0029473: DRAW command "splitshape" produces invalid result on the cylindrical face.
Fix for porting SenerAlgo on the OCCT 720.

Test case for the issue.
2018-02-05 11:20:30 +03:00
msv
b1ee6d0e4b 0029463: Regression relation to 691 version: Method BndBox::IsOut() returns true for point lying on the planar face
Correct the method BRepBndLib::Add so that to enlarge the bounding box on the tolerance of edges which curves participate in calculation of the box.
2018-02-05 11:20:08 +03:00
39 changed files with 1059 additions and 757 deletions

View File

@@ -994,46 +994,61 @@ Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain
Handle(IntTools_Context)& theContext,
const Standard_Real theFuzz)
{
Standard_Boolean bFlag;
Standard_Integer iErr;
Standard_Real aTolF1, aTolF2, aTol;
gp_Pnt2d aP2D;
gp_Pnt aP;
TopoDS_Face aF1, aF2;
TopoDS_Edge aE1;
TopExp_Explorer aExp;
Standard_Real aFuzz1 = (theFuzz > Precision::Confusion() ? theFuzz : Precision::Confusion());
//
bFlag=Standard_False;
//
aF1=theF1;
aF1.Orientation(TopAbs_FORWARD);
aF2=theF2;
aF2.Orientation(TopAbs_FORWARD);
//
aTolF1=BRep_Tool::Tolerance(aF1);
// 1
aExp.Init(aF1, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
aE1=(*(TopoDS_Edge*)(&aExp.Current()));
if (!BRep_Tool::Degenerated(aE1)) {
Standard_Real aTolE = BRep_Tool::Tolerance(aE1);
if (aTolE > aTolF1) {
aTolF1 = aTolE;
Standard_Boolean bFacesSD = Standard_False;
// The idea is to find a point inside the first face
// and check its validity for the second face.
// If valid - the faces are same domain.
gp_Pnt aP1;
gp_Pnt2d aP2D1;
// Find point inside the first face
Standard_Integer iErr =
BOPTools_AlgoTools3D::PointInFace(theF1, aP1, aP2D1, theContext);
if (iErr != 0)
{
// unable to find the point
return bFacesSD;
}
// Check validity of the point for second face
// Compute the tolerance to check the validity -
// sum of tolerance of faces and fuzzy tolerance
// Compute the tolerance of the faces, taking into account the deviation
// of the edges from the surfaces
Standard_Real aTolF1 = BRep_Tool::Tolerance(theF1),
aTolF2 = BRep_Tool::Tolerance(theF2);
// Find maximal tolerance of edges.
// The faces should have the same boundaries, thus
// it does not matter which face to explore.
{
Standard_Real aTolEMax = -1.;
TopExp_Explorer anExpE(theF1, TopAbs_EDGE);
for (; anExpE.More(); anExpE.Next())
{
const TopoDS_Edge& aE = TopoDS::Edge(anExpE.Current());
if (!BRep_Tool::Degenerated(aE))
{
Standard_Real aTolE = BRep_Tool::Tolerance(aE);
if (aTolE > aTolEMax)
aTolEMax = aTolE;
}
}
if (aTolEMax > aTolF1) aTolF1 = aTolEMax;
if (aTolEMax > aTolF2) aTolF2 = aTolEMax;
}
// 2
aTolF2=BRep_Tool::Tolerance(aF2);
aTol = aTolF1 + aTolF2 + aFuzz1;
//
iErr = BOPTools_AlgoTools3D::PointInFace(aF1, aP, aP2D,
theContext);
if (!iErr) {
bFlag=theContext->IsValidPointForFace(aP, aF2, aTol);
}
//
return bFlag;
// Checking criteria
Standard_Real aTol = aTolF1 + aTolF2 + Max(theFuzz, Precision::Confusion());
// Project and classify the point on second face
bFacesSD = theContext->IsValidPointForFace(aP1, theF2, aTol);
return bFacesSD;
}
//=======================================================================

View File

@@ -115,8 +115,9 @@ void BRepBndLib::Add(const TopoDS_Shape& S, Bnd_Box& B, Standard_Boolean useTria
}
else {
for (;ex2.More();ex2.Next()) {
BC.Initialize(TopoDS::Edge(ex2.Current()));
BndLib_Add3dCurve::Add(BC, BRep_Tool::Tolerance(F), B);
const TopoDS_Edge& anEdge = TopoDS::Edge(ex2.Current());
BC.Initialize(anEdge);
BndLib_Add3dCurve::Add(BC, BRep_Tool::Tolerance(anEdge), B);
}
B.Enlarge(BRep_Tool::Tolerance(F));
}

View File

@@ -135,10 +135,10 @@ void BRepClass_Intersector::Perform(const gp_Lin2d& L,
IntRes2d_Domain DL;
//
if(P!=RealLast()) {
DL.SetValues(L.Location(),0.,aTolZ,ElCLib::Value(P,L),P,aTolZ);
DL.SetValues(L.Location(),0.,Precision::PConfusion(),ElCLib::Value(P,L),P,Precision::PConfusion());
}
else {
DL.SetValues(L.Location(),0.,aTolZ,Standard_True);
DL.SetValues(L.Location(),0.,Precision::PConfusion(),Standard_True);
}
IntRes2d_Domain DE(pdeb,deb,toldeb,pfin,fin,tolfin);

View File

@@ -21,6 +21,7 @@
#include <Standard_OutOfRange.hxx>
#include <Adaptor2d_Curve2d.hxx>
#include <Extrema_Curve2dTool.hxx>
#include <Extrema_ExtPC2d.hxx>
#include <Extrema_POnCurv2d.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec2d.hxx>
@@ -43,6 +44,7 @@
#define Pnt_hxx <gp_Pnt2d.hxx>
#define Vec gp_Vec2d
#define Vec_hxx <gp_Vec2d.hxx>
#define Extrema_GExtPC Extrema_ExtPC2d
#define Extrema_GenExtCC Extrema_ECC2d
#define Extrema_GenExtCC_hxx <Extrema_ECC2d.hxx>
#include <Extrema_GenExtCC.gxx>

View File

@@ -21,6 +21,7 @@
#include <Standard_OutOfRange.hxx>
#include <Adaptor3d_Curve.hxx>
#include <Extrema_CurveTool.hxx>
#include <Extrema_ExtPC.hxx>
#include <Extrema_POnCurv.hxx>
#include <gp_Pnt.hxx>
#include <gp_Vec.hxx>
@@ -43,6 +44,7 @@
#define Pnt_hxx <gp_Pnt.hxx>
#define Vec gp_Vec
#define Vec_hxx <gp_Vec.hxx>
#define Extrema_GExtPC Extrema_ExtPC
#define Extrema_GenExtCC Extrema_ECC
#define Extrema_GenExtCC_hxx <Extrema_ECC.hxx>
#include <Extrema_GenExtCC.gxx>

View File

@@ -22,6 +22,7 @@
#include <Standard_OutOfRange.hxx>
#include <StdFail_NotDone.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_ListOfInteger.hxx>
#include <Precision.hxx>
#include <NCollection_Vector.hxx>
#include <NCollection_CellFilter.hxx>
@@ -92,6 +93,29 @@ private:
Standard_Boolean myIsFind;
};
//=======================================================================
//function : ProjPOnC
//purpose : Projects the point on the curve and returns the minimal
// projection distance
//=======================================================================
static Standard_Real ProjPOnC(const Pnt& theP,
Extrema_GExtPC& theProjTool)
{
Standard_Real aDist = ::RealLast();
theProjTool.Perform(theP);
if (theProjTool.IsDone() && theProjTool.NbExt())
{
for (Standard_Integer i = 1; i <= theProjTool.NbExt(); ++i)
{
Standard_Real aD = theProjTool.SquareDistance(i);
if (aD < aDist)
aDist = aD;
}
aDist = sqrt(aDist);
}
return aDist;
}
//=======================================================================
//function : Extrema_GenExtCC
//purpose :
@@ -262,9 +286,10 @@ void Extrema_GenExtCC::Perform()
aFinder.SetFunctionalMinimalValue(0.0); // Best distance cannot be lower than 0.0.
// Size computed to have cell index inside of int32 value.
const Standard_Real aCellSize = Max(anIntervals1.Last() - anIntervals1.First(),
const Standard_Real aCellSize = Max(Max(anIntervals1.Last() - anIntervals1.First(),
anIntervals2.Last() - anIntervals2.First())
* Precision::PConfusion() / (2.0 * Sqrt(2.0));
* Precision::PConfusion() / (2.0 * Sqrt(2.0)),
Precision::PConfusion());
Extrema_CCPointsInspector anInspector(aCellSize);
NCollection_CellFilter<Extrema_CCPointsInspector> aFilter(aCellSize);
NCollection_Vector<gp_XY> aPnts;
@@ -329,63 +354,150 @@ void Extrema_GenExtCC::Perform()
}
}
if (aPnts.Size() == 0)
const Standard_Integer aNbSol = aPnts.Length();
if (aNbSol == 0)
{
// No solutions.
myDone = Standard_False;
return;
}
myDone = Standard_True;
if (aNbSol == 1)
{
// Single solution
const gp_XY& aSol = aPnts.First();
myPoints1.Append(aSol.X());
myPoints2.Append(aSol.Y());
return;
}
// More than one solution is found.
// Check for infinity solutions case, for this:
// Sort points lexicographically and check midpoint between each two neighboring points.
// If all midpoints functional value is acceptable
// then set myParallel flag to true and return one solution.
// If all midpoints functional value is acceptable then check the projection distances
// of the bounding points of the curves onto the opposite curves.
// If these distances are also acceptable set myParallel flag to true and return one solution.
std::sort(aPnts.begin(), aPnts.end(), comp);
Standard_Boolean isParallel = Standard_False;
// Solutions to pass into result.
// If the parallel segment is found, save only extreme solutions on that segment.
// The first and last solutions will always be the extreme ones, thus save them unconditionally.
TColStd_ListOfInteger aSolutions;
// Manages the addition of the solution into result.
// Set it to TRUE to add the first solution.
Standard_Boolean bSaveSolution = Standard_True;
// Define direction of the second curve relatively the first one
// (it will be needed for projection).
Standard_Boolean bDirsCoinside = Standard_True;
// Check also if the found solutions are not concentrated in one point
// on any of the curves. And if they are, avoid marking the curves as parallel.
Standard_Boolean bDifferentSolutions = Standard_False;
Standard_Boolean isParallel = Standard_True;
Standard_Real aVal = 0.0;
math_Vector aVec(1,2, 0.0);
math_Vector aVec(1, 2, 0.0);
// Avoid mark parallel case when have duplicates out of tolerance.
// Bad conditioned task: bug25635_1, bug23706_10, bug23706_13.
if (aPnts.Size() >= 2)
// Iterate on all solutions and collect the extreme solutions on all parallel segments.
for (Standard_Integer anIdx = 0; anIdx < aNbSol - 1; anIdx++)
{
isParallel = Standard_True;
for(Standard_Integer anIdx = aPnts.Lower(); anIdx <= aPnts.Upper() - 1; anIdx++)
const gp_XY& aCurrent = aPnts(anIdx);
const gp_XY& aNext = aPnts(anIdx + 1);
aVec(1) = (aCurrent.X() + aNext.X()) * 0.5;
aVec(2) = (aCurrent.Y() + aNext.Y()) * 0.5;
aFunc.Value(aVec, aVal);
if (Abs(aVal - aF) < Precision::Confusion())
{
const gp_XY& aCurrent = aPnts(anIdx);
const gp_XY& aNext = aPnts(anIdx + 1);
aVec(1) = (aCurrent.X() + aNext.X()) * 0.5;
aVec(2) = (aCurrent.Y() + aNext.Y()) * 0.5;
aFunc.Value(aVec, aVal);
if (Abs(aVal - aF) > Precision::Confusion())
// It seems the parallel segment is found.
// Save only extreme solutions on that segment.
if (bSaveSolution)
{
isParallel = Standard_False;
break;
// Add current solution as the beginning of the parallel segment.
aSolutions.Append(anIdx);
// Do not keep the next solution in current parallel segment.
bSaveSolution = Standard_False;
}
}
else
{
// Mid point does not satisfy the tolerance criteria, curves are not parallel.
isParallel = Standard_False;
// Add current solution as the last one in previous parallel segment.
aSolutions.Append(anIdx);
// Save also the next solution as the first one in next parallel segment.
bSaveSolution = Standard_True;
}
if (!bDifferentSolutions)
{
if (aNext.X() > aCurrent.X())
{
if (aNext.Y() > aCurrent.Y())
{
bDifferentSolutions = Standard_True;
bDirsCoinside = Standard_True;
}
else if (aNext.Y() < aCurrent.Y())
{
bDifferentSolutions = Standard_True;
bDirsCoinside = Standard_False;
}
}
}
}
// Save the last solution
aSolutions.Append(aNbSol - 1);
if (!bDifferentSolutions)
isParallel = Standard_False;
if (isParallel)
{
// For the check on parallel case it is also necessary to check additionally
// if the ends of the curves do not diverge. For this, project the bounding
// points of the curves on the opposite curves and check the distances.
Standard_Real aT1[2] = {myLowBorder(1), myUppBorder(1)};
Standard_Real aT2[2] = {bDirsCoinside ? myLowBorder(2) : myUppBorder(2),
bDirsCoinside ? myUppBorder(2) : myLowBorder(2)};
Extrema_GExtPC anExtPC1, anExtPC2;
anExtPC1.Initialize(C1, myLowBorder(1), myUppBorder(1));
anExtPC2.Initialize(C2, myLowBorder(2), myUppBorder(2));
for (Standard_Integer iT = 0; isParallel && (iT < 2); ++iT)
{
Standard_Real aDist1 = ProjPOnC(C1.Value(aT1[iT]), anExtPC2);
Standard_Real aDist2 = ProjPOnC(C2.Value(aT2[iT]), anExtPC1);
isParallel = (Abs(Min(aDist1, aDist2) - aF) < Precision::Confusion());
}
}
if (isParallel)
{
const gp_XY& aCurrent = aPnts.First();
myPoints1.Append(aCurrent.X());
myPoints2.Append(aCurrent.Y());
// Keep only one solution
const gp_XY& aSol = aPnts.First();
myPoints1.Append(aSol.X());
myPoints2.Append(aSol.Y());
myParallel = Standard_True;
}
else
{
for(Standard_Integer anIdx = aPnts.Lower(); anIdx <= aPnts.Upper(); anIdx++)
// Keep all saved solutions
TColStd_ListIteratorOfListOfInteger aItSol(aSolutions);
for (; aItSol.More(); aItSol.Next())
{
const gp_XY& aCurrent = aPnts(anIdx);
myPoints1.Append(aCurrent.X());
myPoints2.Append(aCurrent.Y());
const gp_XY& aSol = aPnts(aItSol.Value());
myPoints1.Append(aSol.X());
myPoints2.Append(aSol.Y());
}
}
myDone = Standard_True;
}
//=======================================================================

View File

@@ -365,7 +365,7 @@ static Standard_Integer xdistcs(Draw_Interpretor& di, Standard_Integer n, const
// report error or warning if distance is greater than tolerance
if (aD > anErrTol)
{
di << "Error :";
di << "Error in " << a[1] << ":";
}
else if (aD > aWarnTol)
{

View File

@@ -930,21 +930,19 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1,
// 3. ts1 == ts2 == 0 <Param-Param>
// Geom - Geom
const Standard_Boolean RestrictLine = Standard_True;
if(ts1 == ts2 && ts1 == 1)
{
IntSurf_ListOfPntOn2S ListOfPnts;
ListOfPnts.Clear();
if(isGeomInt)
{
GeomGeomPerfom( theS1, theD1, theS2, theD2, TolArc,
TolTang, ListOfPnts, RestrictLine,
typs1, typs2, theIsReqToKeepRLine);
GeomGeomPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang,
ListOfPnts, typs1, typs2, theIsReqToKeepRLine);
}
else
{
ParamParamPerfom(theS1, theD1, theS2, theD2,
TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
TolArc, TolTang, ListOfPnts, typs1, typs2);
}
}
@@ -961,7 +959,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1,
ListOfPnts.Clear();
ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc,
TolTang, ListOfPnts, RestrictLine, typs1, typs2);
TolTang, ListOfPnts, typs1, typs2);
}
if(!theIsReqToPostWLProc)
@@ -978,7 +976,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1,
continue;
Handle(IntPatch_WLine) aRW =
IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2, RestrictLine);
IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2);
if(aRW.IsNull())
continue;
@@ -999,7 +997,6 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1,
const Standard_Real TolArc,
const Standard_Real TolTang,
IntSurf_ListOfPntOn2S& ListOfPnts,
const Standard_Boolean RestrictLine,
const Standard_Boolean isGeomInt,
const Standard_Boolean theIsReqToKeepRLine,
const Standard_Boolean theIsReqToPostWLProc)
@@ -1183,7 +1180,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1,
if(!isGeomInt)
{
ParamParamPerfom(theS1, theD1, theS2, theD2,
TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
TolArc, TolTang, ListOfPnts, typs1, typs2);
}
else if(ts1 != ts2)
{
@@ -1192,12 +1189,12 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1,
else if (ts1 == 0)
{
ParamParamPerfom(theS1, theD1, theS2, theD2,
TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
TolArc, TolTang, ListOfPnts, typs1, typs2);
}
else if(ts1 == 1)
{
GeomGeomPerfom(theS1, theD1, theS2, theD2, TolArc,
TolTang, ListOfPnts, RestrictLine, typs1, typs2, theIsReqToKeepRLine);
GeomGeomPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang,
ListOfPnts, typs1, typs2, theIsReqToKeepRLine);
}
if(!theIsReqToPostWLProc)
@@ -1214,7 +1211,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1,
continue;
Handle(IntPatch_WLine) aRW =
IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2, RestrictLine);
IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2);
if(aRW.IsNull())
continue;
@@ -1235,7 +1232,6 @@ void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_HSurface)&
const Standard_Real TolArc,
const Standard_Real TolTang,
IntSurf_ListOfPntOn2S& ListOfPnts,
const Standard_Boolean RestrictLine,
const GeomAbs_SurfaceType typs1,
const GeomAbs_SurfaceType typs2)
{
@@ -1245,10 +1241,10 @@ void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_HSurface)&
Standard_Boolean ClearFlag = Standard_True;
if(!ListOfPnts.IsEmpty())
{
interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep, ListOfPnts, RestrictLine);
interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep, ListOfPnts);
ClearFlag = Standard_False;
}
interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep,ClearFlag); //double call!!!!!!!
interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep,ClearFlag);
}
else if((theD1->DomainIsInfinite()) ^ (theD2->DomainIsInfinite()))
{
@@ -1345,7 +1341,6 @@ void IntPatch_Intersection::GeomGeomPerfom(const Handle(Adaptor3d_HSurface)& the
const Standard_Real TolArc,
const Standard_Real TolTang,
IntSurf_ListOfPntOn2S& ListOfPnts,
const Standard_Boolean RestrictLine,
const GeomAbs_SurfaceType theTyps1,
const GeomAbs_SurfaceType theTyps2,
const Standard_Boolean theIsReqToKeepRLine)
@@ -1357,7 +1352,7 @@ void IntPatch_Intersection::GeomGeomPerfom(const Handle(Adaptor3d_HSurface)& the
{
done = Standard_False;
ParamParamPerfom(theS1, theD1, theS2, theD2,
TolArc, TolTang, ListOfPnts, RestrictLine, theTyps1, theTyps2);
TolArc, TolTang, ListOfPnts, theTyps1, theTyps2);
return;
}
@@ -1604,7 +1599,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& S1,
continue;
Handle(IntPatch_WLine) aRW =
IntPatch_WLineTool::ComputePurgedWLine(aWL, S1, S2, D1, D2, Standard_True);
IntPatch_WLineTool::ComputePurgedWLine(aWL, S1, S2, D1, D2);
if(aRW.IsNull())
continue;

View File

@@ -70,16 +70,16 @@ public:
//!
//! UVMaxStep is a parameter used in the walking
//! algorithms to compute the distance between to
//! points in their respective parametrtic spaces.
//! points in their respective parametric spaces.
Standard_EXPORT void SetTolerances (const Standard_Real TolArc, const Standard_Real TolTang, const Standard_Real UVMaxStep, const Standard_Real Fleche);
//! Flag theIsReqToKeepRLine has been enterred only for
//! Flag theIsReqToKeepRLine has been entered only for
//! compatibility with TopOpeBRep package. It shall be deleted
//! after deleting TopOpeBRep.
//! When intersection result returns IntPatch_RLine and another
//! IntPatch_Line (not restriction) we (in case of theIsReqToKeepRLine==TRUE)
//! will always keep both lines even if they are coincided.
//! Flag theIsReqToPostWLProc has been enterred only for
//! Flag theIsReqToPostWLProc has been entered only for
//! compatibility with TopOpeBRep package. It shall be deleted
//! after deleting TopOpeBRep.
//! If theIsReqToPostWLProc == FALSE, then we will work with Walking-line
@@ -88,18 +88,18 @@ public:
//! If isGeomInt == Standard_False, then method
//! Param-Param intersection will be used.
//! Flag theIsReqToKeepRLine has been enterred only for
//! Flag theIsReqToKeepRLine has been entered only for
//! compatibility with TopOpeBRep package. It shall be deleted
//! after deleting TopOpeBRep.
//! When intersection result returns IntPatch_RLine and another
//! IntPatch_Line (not restriction) we (in case of theIsReqToKeepRLine==TRUE)
//! will always keep both lines even if they are coincided.
//! Flag theIsReqToPostWLProc has been enterred only for
//! Flag theIsReqToPostWLProc has been entered only for
//! compatibility with TopOpeBRep package. It shall be deleted
//! after deleting TopOpeBRep.
//! If theIsReqToPostWLProc == FALSE, then we will work with Walking-line
//! obtained after intersection algorithm directly (wothout any post-processing).
Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, IntSurf_ListOfPntOn2S& LOfPnts, const Standard_Boolean RestrictLine = Standard_True, const Standard_Boolean isGeomInt = Standard_True, const Standard_Boolean theIsReqToKeepRLine = Standard_False, const Standard_Boolean theIsReqToPostWLProc = Standard_True);
//! obtained after intersection algorithm directly (without any post-processing).
Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, IntSurf_ListOfPntOn2S& LOfPnts, const Standard_Boolean isGeomInt = Standard_True, const Standard_Boolean theIsReqToKeepRLine = Standard_False, const Standard_Boolean theIsReqToPostWLProc = Standard_True);
//! Perform with start point
Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real U1, const Standard_Real V1, const Standard_Real U2, const Standard_Real V2, const Standard_Real TolArc, const Standard_Real TolTang);
@@ -107,14 +107,14 @@ public:
//! Uses for finding self-intersected surfaces.
Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Standard_Real TolArc, const Standard_Real TolTang);
//! Returns True if the calculus was succesfull.
//! Returns True if the calculus was successful.
Standard_Boolean IsDone() const;
//! Returns true if the is no intersection.
Standard_Boolean IsEmpty() const;
//! Returns True if the two patches are considered as
//! entierly tangent, i-e every restriction arc of one
//! entirely tangent, i-e every restriction arc of one
//! patch is inside the geometric base of the other patch.
Standard_Boolean TangentFaces() const;
@@ -157,15 +157,15 @@ protected:
private:
Standard_EXPORT void ParamParamPerfom (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, IntSurf_ListOfPntOn2S& LOfPnts, const Standard_Boolean RestrictLine, const GeomAbs_SurfaceType typs1, const GeomAbs_SurfaceType typs2);
Standard_EXPORT void ParamParamPerfom (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, IntSurf_ListOfPntOn2S& LOfPnts, const GeomAbs_SurfaceType typs1, const GeomAbs_SurfaceType typs2);
//! Flag theIsReqToKeepRLine has been enterred only for
//! Flag theIsReqToKeepRLine has been entered only for
//! compatibility with TopOpeBRep package. It shall be deleted
//! after deleting TopOpeBRep.
//! When intersection result returns IntPatch_RLine and another
//! IntPatch_Line (not restriction) we (in case of theIsReqToKeepRLine==TRUE)
//! will always keep both lines even if they are coincided.
Standard_EXPORT void GeomGeomPerfom (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, IntSurf_ListOfPntOn2S& LOfPnts, const Standard_Boolean RestrictLine, const GeomAbs_SurfaceType typs1, const GeomAbs_SurfaceType typs2, const Standard_Boolean theIsReqToKeepRLine = Standard_False);
Standard_EXPORT void GeomGeomPerfom (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, IntSurf_ListOfPntOn2S& LOfPnts, const GeomAbs_SurfaceType typs1, const GeomAbs_SurfaceType typs2, const Standard_Boolean theIsReqToKeepRLine);
Standard_EXPORT void GeomParamPerfom (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Boolean isNotAnalitical, const GeomAbs_SurfaceType typs1, const GeomAbs_SurfaceType typs2);

View File

@@ -1551,8 +1551,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
const Standard_Real Epsilon,
const Standard_Real Deflection,
const Standard_Real Increment,
IntSurf_ListOfPntOn2S& LOfPnts,
const Standard_Boolean RestrictLine)
IntSurf_ListOfPntOn2S& LOfPnts)
{
if (LOfPnts.IsEmpty()){
done = Standard_True;
@@ -1788,15 +1787,13 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
Standard_Real TolTang = TolTangency;
Handle(IntPatch_WLine) wline = new IntPatch_WLine(PW.Line(),Standard_False,trans1,trans2);
if (RestrictLine){
//the method PutVertexOnLine can reduce the number of points in <wline>
IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang);
if (wline->NbPnts() < 2)
continue;
IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang);
if (wline->NbPnts() < 2)
continue;
}
//the method PutVertexOnLine can reduce the number of points in <wline>
IntPatch_RstInt::PutVertexOnLine(wline, Surf1, D1, Surf2, Standard_True, TolTang);
if (wline->NbPnts() < 2)
continue;
IntPatch_RstInt::PutVertexOnLine(wline, Surf2, D2, Surf1, Standard_False, TolTang);
if (wline->NbPnts() < 2)
continue;
if(wline->NbVertex() == 0) {
IntPatch_Point vtx;

View File

@@ -68,7 +68,7 @@ public:
//! Performs the intersection between <Caro1> and
//! <Caro2>. The method computes the polyhedron on
//! each surface.
Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& Caro1, const Handle(Adaptor3d_TopolTool)& Domain1, const Handle(Adaptor3d_HSurface)& Caro2, const Handle(Adaptor3d_TopolTool)& Domain2, const Standard_Real TolTangency, const Standard_Real Epsilon, const Standard_Real Deflection, const Standard_Real Increment, IntSurf_ListOfPntOn2S& ListOfPnts, const Standard_Boolean RestrictLine);
Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& Caro1, const Handle(Adaptor3d_TopolTool)& Domain1, const Handle(Adaptor3d_HSurface)& Caro2, const Handle(Adaptor3d_TopolTool)& Domain2, const Standard_Real TolTangency, const Standard_Real Epsilon, const Standard_Real Deflection, const Standard_Real Increment, IntSurf_ListOfPntOn2S& ListOfPnts);
//! Performs the intersection between <Caro1> and
//! <Caro2>. The method computes the polyhedron on

View File

@@ -234,40 +234,6 @@ static void GetLinePoint2d (const Handle(IntPatch_Line)& L,
V = (1.-par)*vs1+par*vs2;
}
static void GetWLinePoint (const Handle(IntPatch_WLine)& wlin,
const Standard_Real param,
Standard_Real& U1, Standard_Real& V1,
Standard_Real& U2, Standard_Real& V2,
gp_Pnt& P)
{
Standard_Integer Nbptlin = wlin->NbPnts();
Standard_Real par = IntegerPart(param);
Standard_Integer Irang = Standard_Integer(par);
if (Irang == Nbptlin) {
Irang--;
par = 1.0;
}
else
par = Abs(param-par);
const IntSurf_PntOn2S& p2s1 = wlin->Point(Irang);
const IntSurf_PntOn2S& p2s2 = wlin->Point(Irang+1);
const gp_Pnt& p1 = p2s1.Value();
const gp_Pnt& p2 = p2s2.Value();
P.ChangeCoord().SetLinearForm(1.-par, p1.XYZ(), par, p2.XYZ());
Standard_Real us1,vs1,us2,vs2;
p2s1.ParametersOnS1(us1,vs1);
p2s2.ParametersOnS1(us2,vs2);
U1 = (1.-par)*us1+par*us2;
V1 = (1.-par)*vs1+par*vs2;
p2s1.ParametersOnS2(us1,vs1);
p2s2.ParametersOnS2(us2,vs2);
U2 = (1.-par)*us1+par*us2;
V2 = (1.-par)*vs1+par*vs2;
}
static Standard_Boolean FindParameter(const Handle(IntPatch_Line)& L,
const Handle(Adaptor3d_HSurface)& OtherSurf,
const Standard_Real Tol,
@@ -394,50 +360,6 @@ inline Standard_Boolean ArePnt2dEqual(const gp_Pnt2d& p1, const gp_Pnt2d& p2,
return Abs(p1.X()-p2.X()) < tolU && Abs(p1.Y()-p2.Y()) < tolV;
}
static gp_Pnt2d GetPointOnPolygo(const IntPatch_Polygo& Pol,
const Standard_Real param)
{
Standard_Real par = IntegerPart(param);
Standard_Integer irang = Standard_Integer(par) + 1;
if (irang == Pol.NbPoints()) {
irang--;
par = 1.;
}
else {
par = Abs(param-par);
}
gp_Pnt2d p1 = Pol.Point(irang);
gp_Pnt2d p2 = Pol.Point(irang+1);
gp_Pnt2d p;
p.ChangeCoord().SetLinearForm(1.-par,p1.XY(),par,p2.XY());
return p;
}
static Standard_Boolean IsSegment2dSmall(const IntPatch_Polygo& Pol,
const Standard_Real parmin,
const Standard_Real parmax,
const Standard_Real URes,
const Standard_Real VRes)
{
Standard_Integer irang1 = Standard_Integer(IntegerPart(parmin)) + 2;
Standard_Integer irang2 = Standard_Integer(IntegerPart(parmax)) + 1;
gp_Pnt2d p1,p2;
Standard_Real du=0.,dv=0.;
p1 = GetPointOnPolygo(Pol,parmin);
for (Standard_Integer i=irang1; i <= irang2 && du <= URes && dv <= VRes; i++) {
p2 = Pol.Point(i);
du += Abs(p2.X()-p1.X());
dv += Abs(p2.Y()-p1.Y());
p1 = p2;
}
if (du <= URes && dv <= VRes) {
p2 = GetPointOnPolygo(Pol,parmax);
du += Abs(p2.X()-p1.X());
dv += Abs(p2.Y()-p1.Y());
}
return du <= URes && dv <= VRes;
}
//=======================================================================
//function : PutVertexOnLine
//purpose :
@@ -467,7 +389,6 @@ void IntPatch_RstInt::PutVertexOnLine (const Handle(IntPatch_Line)& L,
Handle(IntPatch_RLine) rlin (Handle(IntPatch_RLine)::DownCast (L)); //-- aucune verification n est
Handle(IntPatch_WLine) wlin (Handle(IntPatch_WLine)::DownCast (L)); //-- faite au cast.
Standard_Integer Nbvtx =0;
Standard_Integer Nbptlin =0;
Standard_Real tolPLin = Surf->UResolution(Precision::Confusion());
tolPLin = Max (tolPLin, Surf->VResolution(Precision::Confusion()));
tolPLin = Min (tolPLin, Precision::Confusion());
@@ -491,12 +412,10 @@ void IntPatch_RstInt::PutVertexOnLine (const Handle(IntPatch_Line)& L,
if (typL == IntPatch_Walking) {
Nbvtx = wlin->NbVertex();
PLin.SetWLine(OnFirst,wlin);
Nbptlin = wlin->NbPnts();
}
else if ( typL == IntPatch_Restriction) {
Nbvtx = rlin->NbVertex();
PLin.SetRLine(OnFirst,rlin);
Nbptlin = rlin->NbPnts();
}
else {
throw Standard_DomainError();
@@ -553,8 +472,6 @@ void IntPatch_RstInt::PutVertexOnLine (const Handle(IntPatch_Line)& L,
// MSV Oct 15, 2001: use tolerance of this edge if possible
Standard_Real edgeTol = Tol3d(arc,Domain,Tol);
Standard_Real URes = Surf->UResolution(edgeTol);
Standard_Real VRes = Surf->VResolution(edgeTol);
IntPatch_HInterTool::Bounds(arc,PFirst,PLast);
if(Precision::IsNegativeInfinite(PFirst))
@@ -567,26 +484,16 @@ void IntPatch_RstInt::PutVertexOnLine (const Handle(IntPatch_Line)& L,
// return;
//}
Standard_Boolean isVFirst = Standard_False, isVLast = Standard_False;
gp_Pnt2d p2dFirst,p2dLast;
Standard_Real tolUFirst=0.,tolVFirst=0.,tolULast=0.,tolVLast=0.;
Domain->Initialize(arc);
for (Domain->InitVertexIterator(); Domain->MoreVertex(); Domain->NextVertex()) {
Handle(Adaptor3d_HVertex) vtx = Domain->Vertex();
Standard_Real prm = IntPatch_HInterTool::Parameter(vtx,arc);
if (Abs(prm - PFirst) < Precision::PConfusion()) {
arc->D0(PFirst,p2dFirst);
Standard_Real tol3d = Max (Tol3d(vtx,Domain), edgeTol);
tolUFirst = Surf->UResolution(tol3d);
tolVFirst = Surf->VResolution(tol3d);
isVFirst = Standard_True;
}
else if (Abs(prm - PLast) < Precision::PConfusion()) {
arc->D0(PLast,p2dLast);
Standard_Real tol3d = Max (edgeTol, Tol3d(vtx,Domain));
tolULast = Surf->UResolution(tol3d);
tolVLast = Surf->VResolution(tol3d);
isVLast = Standard_True;
}
}
@@ -697,473 +604,378 @@ void IntPatch_RstInt::PutVertexOnLine (const Handle(IntPatch_Line)& L,
Commun.Perform(PLin,Brise);
locpt.Clear();
locpt2.Clear();
Standard_Integer Commun_NbSectionPoints = Commun.NbSectionPoints();
Standard_Integer Commun_NbTangentZones = Commun.NbTangentZones();
Standard_Integer Commun_Section_Tangent = Commun_NbSectionPoints
+ Commun_NbTangentZones;
for (i=1;i<=Commun_Section_Tangent;i++) {
Standard_Real W1[2],W2[2];
Standard_Boolean refine[2],useWL[2];
Standard_Integer nbpt = 1;
if(i<=Commun_NbSectionPoints) {
// intersection point
W1[0] = Commun.PntValue(i).ParamOnFirst();
W2[0] = Commun.PntValue(i).ParamOnSecond();
refine[0] = Standard_True;
}
else {
// tangent zone
Standard_Real UMinCh,UMaxCh; //-- ligne de cheminement 0..(Nbptlin-1)
Standard_Real UMinAr,UMaxAr; //-- polyline of arc 0..(NbEchant-1)
Commun.ZoneValue(i-Commun_NbSectionPoints).ParamOnFirst(UMinCh,UMaxCh);
Commun.ZoneValue(i-Commun_NbSectionPoints).ParamOnSecond(UMinAr,UMaxAr);
gp_Pnt2d p1Ar = GetPointOnPolygo(Brise,UMinAr);
gp_Pnt2d p2Ar = GetPointOnPolygo(Brise,UMaxAr);
Standard_Real tolU = URes*2.;
Standard_Real tolV = VRes*2.;
if (isVFirst && ArePnt2dEqual(p1Ar,p2dFirst,tolUFirst,tolVFirst)) {
tolU = Max(tolUFirst,tolU); tolV = Max(tolVFirst,tolV);
}
if (isVLast && ArePnt2dEqual(p2Ar,p2dLast,tolULast,tolVLast)) {
tolU = Max(tolULast,tolU); tolV = Max(tolVLast,tolV);
}
Standard_Real nptCh = UMaxCh-UMinCh;
Standard_Boolean isNptLow = (nptCh < 10. && nptCh < Nbptlin/100.) ||
(!Domain->Has3d() && Standard_Integer(nptCh)+1 < Nbptlin);
if (!isNptLow && !IsSegment2dSmall(Brise,UMinAr,UMaxAr,tolU,tolV)) {
// treat both ends
Standard_Real UMinChP,UMinArP,UMaxArP;
UMinChP = IntegerPart(UMinCh);
UMinArP = IntegerPart(UMinAr);
UMaxArP = IntegerPart(UMaxAr);
Standard_Integer irangAr1,irangAr2;
irangAr1 = Standard_Integer(UMinArP)+1;
irangAr2 = Standard_Integer(UMaxArP)+1;
UMinChP = UMinCh - UMinChP;
UMinArP = UMinAr - UMinArP;
//UMaxChP = UMaxCh - UMaxChP; UMaxArP = UMaxAr - UMaxArP;
const Standard_Real eps = 1e-10;
// Standard_Boolean isChExtr1 = irangCh1==1 && UMinChP<eps;
// Standard_Boolean isChExtr2 = irangCh2==Nbptlin;
Standard_Boolean isArExtr1 = irangAr1==1 && UMinArP<eps;
Standard_Boolean isArExtr2 = irangAr2==NbEchant;
// detect orientation
gp_Pnt2d p1Ch = GetPointOnPolygo(PLin,UMinCh);
Standard_Real d11 = p1Ch.SquareDistance(p1Ar);
Standard_Real d12 = p1Ch.SquareDistance(p2Ar);
Standard_Boolean sameOri = d11 < d12;
if (!sameOri) {
Standard_Boolean itmp=isArExtr1; isArExtr1=isArExtr2; isArExtr2=itmp;
Standard_Real dtmp=UMinAr; UMinAr=UMaxAr; UMaxAr=dtmp;
}
W1[0] = UMinCh; W1[1] = UMaxCh;
W2[0] = UMinAr; W2[1] = UMaxAr;
//refine[0] = ! (isChExtr1 || isArExtr1);
//refine[1] = ! (isChExtr2 || isArExtr2);
refine[0] = refine[1] = Standard_False;
useWL[0] = !isArExtr1;
useWL[1] = !isArExtr2;
nbpt = 2;
}
else {
// treat the middle point as an intersection point
W1[0] = 0.5*(UMinCh+UMaxCh);
W2[0] = 0.5*(UMinAr+UMaxAr);
refine[0] = Standard_True;
}
}
Standard_Integer nbTreated = 0;
for (Standard_Integer ip=0; ip < nbpt; ip++) {
GetLinePoint2d (L, W1[ip]+1, !OnFirst, U,V);
// We do not need in putting vertex into tangent zone(s).
// Therefore, only section points are interested by us.
// Boundary of WLine (its first/last points) will be
// marked by some vertex later. See bug #29494.
const Standard_Integer aNbSectionPts = Commun.NbSectionPoints();
for (i = 1; i <= aNbSectionPts; i++)
{
const Standard_Real aW1 = Commun.PntValue(i).ParamOnFirst(),
aW2 = Commun.PntValue(i).ParamOnSecond();
if (!refine[ip] && useWL[ip]) {
Standard_Real aU1,aV1;
GetLinePoint2d (L, W1[ip]+1, OnFirst, aU1,aV1);
p2d.SetCoord(aU1,aV1);
Standard_Real paramProj;
if (!IntPatch_HInterTool::Project(arc,p2d,paramProj,p2d)) continue;
W = paramProj;
}
else {
Standard_Real par = IntegerPart(W2[ip]);
Standard_Integer Irang = Standard_Integer(par) + 1;
if (Irang == Brise.NbPoints()) {
Irang--;
par = 1.;
}
else {
par =Abs(W2[ip]-par);
}
W = (1.-par)*Brise.Parameter(Irang) + par*Brise.Parameter(Irang+1);
}
Standard_Integer nbTreated = 0;
GetLinePoint2d (L, aW1+1, !OnFirst, U,V);
Standard_Boolean refined = Standard_False;
if (refine[ip])
Standard_Real par = IntegerPart(aW2);
Standard_Integer Irang = Standard_Integer(par) + 1;
if (Irang == Brise.NbPoints())
{
Irang--;
par = 1.;
}
else
{
par = Abs(aW2 - par);
}
W = (1. - par)*Brise.Parameter(Irang) + par*Brise.Parameter(Irang + 1);
//------------------------------------------------------------------------
//-- On a trouve un point 2d approche Ua,Va intersection de la ligne
//-- de cheminement et de la restriction.
//--
//-- On injecte ce point ds les intersections Courbe-Surface
//--
IntPatch_CSFunction thefunc(OtherSurf,arc,Surf);
// MSV: extend UV bounds to not miss solution near the boundary
const Standard_Real margCoef = 0.004;
Standard_Boolean refined = Standard_False;
IntPatch_CurvIntSurf IntCS(U,V,W,thefunc,edgeTol,margCoef);
if (IntCS.IsDone() && !IntCS.IsEmpty())
{
ptsommet = IntCS.Point();
IntCS.ParameterOnSurface(U2,V2);
gp_Pnt anOldPnt, aNewPnt;
OtherSurf->D0(U,V, anOldPnt);
OtherSurf->D0(U2,V2, aNewPnt);
if (anOldPnt.SquareDistance(aNewPnt) < Precision::SquareConfusion())
{
//------------------------------------------------------------------------
//-- On a trouve un point 2d approche Ua,Va intersection de la ligne
//-- de cheminement et de la restriction.
//--
//-- On injecte ce point ds les intersections Courbe-Surface
//--
IntPatch_CSFunction thefunc(OtherSurf,arc,Surf);
// MSV: extend UV bounds to not miss solution near the boundary
Standard_Real margCoef = 0.004;
IntPatch_CurvIntSurf IntCS(U,V,W,thefunc,edgeTol,margCoef);
if (IntCS.IsDone())
{
if (!IntCS.IsEmpty())
{
ptsommet = IntCS.Point();
IntCS.ParameterOnSurface(U2,V2);
gp_Pnt anOldPnt, aNewPnt;
OtherSurf->D0(U,V, anOldPnt);
OtherSurf->D0(U2,V2, aNewPnt);
if (anOldPnt.SquareDistance(aNewPnt) < Precision::Confusion()
* Precision::Confusion())
{
U2 = U;
V2 = V;
}
paramarc = IntCS.ParameterOnCurve();
refined = Standard_True;
}
}
U2 = U;
V2 = V;
}
else {
U2 = U; V2 = V;
paramarc = W;
arc->D0(paramarc,p2d);
Surf->D0(p2d.X(),p2d.Y(),ptsommet);
paramarc = IntCS.ParameterOnCurve();
refined = Standard_True;
}
if (refined) {
duplicate = Standard_False;
for (j=1; j<=locpt.Length();j++) {
if (ptsommet.Distance(locpt(j)) <= edgeTol) {
if (possiblyClosed) {
locpt2(j).Coord(U,V);
if ((OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed) ||
(OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed))
continue;
}
duplicate = Standard_True;
break;
}
}
if (!refine[ip] || refined) {
duplicate = Standard_False;
for (j=1; j<=locpt.Length();j++) {
if (ptsommet.Distance(locpt(j)) <= edgeTol) {
if (possiblyClosed) {
locpt2(j).Coord(U,V);
if ((OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed) ||
(OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed))
continue;
}
duplicate = Standard_True;
break;
if (!duplicate) {
Standard_Integer ParamApproxOnLine = Standard_Integer(aW1)+1;
arc->D1(paramarc,p2d,d2d);
U1 = p2d.X(); V1 = p2d.Y();
if (typL == IntPatch_Walking && SurfaceIsPeriodic) {
if (OnFirst)
Recadre(TypeS1,TypeS2,wlin,ParamApproxOnLine,U1,V1,U2,V2);
else
Recadre(TypeS1,TypeS2,wlin,ParamApproxOnLine,U2,V2,U1,V1);
}
locpt.Append(ptsommet);
locpt2.Append(gp_Pnt2d(U2,V2));
found = FindParameter(L,OtherSurf,edgeTol,ptsommet,gp_Pnt2d(U2,V2),
paramline,tgline,ParamApproxOnLine,OnFirst);
if (typL == IntPatch_Walking && found && possiblyClosed) {
// check in 2d
if (SurfaceIsUClosed || SurfaceIsVClosed) {
GetLinePoint2d (L, paramline, OnFirst, U,V);
if ((SurfaceIsUClosed && Abs(U-U1) > tolUClosed) ||
(SurfaceIsVClosed && Abs(V-V1) > tolVClosed))
found = Standard_False;
}
if (found && (OSurfaceIsUClosed || OSurfaceIsVClosed)) {
GetLinePoint2d (L, paramline, !OnFirst, U,V);
if ((OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed) ||
(OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed))
found = Standard_False;
}
}
if (!found) {
continue;
}
if (!duplicate) {
Standard_Integer ParamApproxOnLine = Standard_Integer(W1[ip])+1;
VtxOnArc = CoincideOnArc(ptsommet,arc,Surf,edgeTol,Domain,vtxarc);
Standard_Real vtxTol;
if (VtxOnArc) {
vtxTol = Tol3d(vtxarc,Domain);
if (edgeTol > vtxTol) vtxTol = edgeTol;
}
else vtxTol = edgeTol;
arc->D1(paramarc,p2d,d2d);
U1 = p2d.X(); V1 = p2d.Y();
if (typL == IntPatch_Walking && SurfaceIsPeriodic) {
if (OnFirst)
Recadre(TypeS1,TypeS2,wlin,ParamApproxOnLine,U1,V1,U2,V2);
else
Recadre(TypeS1,TypeS2,wlin,ParamApproxOnLine,U2,V2,U1,V1);
}
locpt.Append(ptsommet);
locpt2.Append(gp_Pnt2d(U2,V2));
found = FindParameter(L,OtherSurf,edgeTol,ptsommet,gp_Pnt2d(U2,V2),
paramline,tgline,ParamApproxOnLine,OnFirst);
if (typL == IntPatch_Walking && found && possiblyClosed) {
// check in 2d
if (SurfaceIsUClosed || SurfaceIsVClosed) {
GetLinePoint2d (L, paramline, OnFirst, U,V);
if ((SurfaceIsUClosed && Abs(U-U1) > tolUClosed) ||
(SurfaceIsVClosed && Abs(V-V1) > tolVClosed))
found = Standard_False;
}
if (found && (OSurfaceIsUClosed || OSurfaceIsVClosed)) {
GetLinePoint2d (L, paramline, !OnFirst, U,V);
if ((OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed) ||
(OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed))
found = Standard_False;
}
}
if (!found) {
continue;
}
VtxOnArc = CoincideOnArc(ptsommet,arc,Surf,edgeTol,Domain,vtxarc);
Standard_Real vtxTol;
if (VtxOnArc) {
vtxTol = Tol3d(vtxarc,Domain);
if (edgeTol > vtxTol) vtxTol = edgeTol;
}
else vtxTol = edgeTol;
//-- It is necessary to test that the point does not already exist
//-- - It can be already a point on arc
//-- BUT on a different arc
// MSV 27.03.2002: find the nearest point; add check in 2d
Standard_Integer ivtx = 0;
Standard_Real dmin = RealLast();
for (j=1; j<=Nbvtx; j++) {
const IntPatch_Point& Rptline = (typL == IntPatch_Walking
? wlin->Vertex(j)
: rlin->Vertex(j));
Standard_Boolean APointOnRstStillExist =
((OnFirst && Rptline.IsOnDomS1() && Rptline.ArcOnS1() == arc) ||
(!OnFirst && Rptline.IsOnDomS2() && Rptline.ArcOnS2() == arc));
if(!APointOnRstStillExist) {
if (possiblyClosed) {
if (SurfaceIsUClosed || SurfaceIsVClosed) {
if (OnFirst) Rptline.ParametersOnS1(U,V);
else Rptline.ParametersOnS2(U,V);
if ((SurfaceIsUClosed && Abs(U-U1) > tolUClosed) ||
(SurfaceIsVClosed && Abs(V-V1) > tolVClosed))
continue;
}
if (OSurfaceIsUClosed || OSurfaceIsVClosed) {
if (OnFirst) Rptline.ParametersOnS2(U,V);
else Rptline.ParametersOnS1(U,V);
if ((OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed) ||
(OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed))
continue;
}
//-- It is necessary to test that the point does not already exist
//-- - It can be already a point on arc
//-- BUT on a different arc
// MSV 27.03.2002: find the nearest point; add check in 2d
Standard_Integer ivtx = 0;
Standard_Real dmin = RealLast();
for (j=1; j<=Nbvtx; j++) {
const IntPatch_Point& Rptline = (typL == IntPatch_Walking
? wlin->Vertex(j)
: rlin->Vertex(j));
Standard_Boolean APointOnRstStillExist =
((OnFirst && Rptline.IsOnDomS1() && Rptline.ArcOnS1() == arc) ||
(!OnFirst && Rptline.IsOnDomS2() && Rptline.ArcOnS2() == arc));
if(!APointOnRstStillExist) {
if (possiblyClosed) {
if (SurfaceIsUClosed || SurfaceIsVClosed) {
if (OnFirst) Rptline.ParametersOnS1(U,V);
else Rptline.ParametersOnS2(U,V);
if ((SurfaceIsUClosed && Abs(U-U1) > tolUClosed) ||
(SurfaceIsVClosed && Abs(V-V1) > tolVClosed))
continue;
}
Standard_Real dist = ptsommet.Distance(Rptline.Value());
Standard_Real dt = Max(vtxTol, Rptline.Tolerance());
if (dist < dmin) {
if (dist <= dt) {
ptline = Rptline;
ivtx = j;
if( surfacetype == GeomAbs_Cone ) {
ivtx = 0;
}
}
else {
// cancel previous solution because this point is better
// but its tolerance is not large enough
if (OSurfaceIsUClosed || OSurfaceIsVClosed) {
if (OnFirst) Rptline.ParametersOnS2(U,V);
else Rptline.ParametersOnS1(U,V);
if ((OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed) ||
(OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed))
continue;
}
}
Standard_Real dist = ptsommet.Distance(Rptline.Value());
Standard_Real dt = Max(vtxTol, Rptline.Tolerance());
if (dist < dmin) {
if (dist <= dt) {
ptline = Rptline;
ivtx = j;
if( surfacetype == GeomAbs_Cone ) {
ivtx = 0;
}
dmin = dist;
}
}
}
if (ivtx) {
if (ptline.Tolerance() > vtxTol) {
vtxTol = ptline.Tolerance();
if (!VtxOnArc) {
// now we should repeat attempt to coincide on a bound of arc
VtxOnArc = CoincideOnArc(ptsommet,arc,Surf,vtxTol,Domain,vtxarc);
if (VtxOnArc) {
Standard_Real tol = Tol3d(vtxarc,Domain);
if (tol > vtxTol) vtxTol = tol;
}
}
}
}
if (typL == IntPatch_Walking)
VerifyTgline(wlin,(Standard_Integer)paramline,edgeTol,tgline);
Surf->D1(U1,V1,ptbid,d1u,d1v);
tgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
normsurf = d1u.Crossed(d1v);
if (normsurf.Magnitude() < gp::Resolution()) {
transline.SetValue(Standard_True,IntSurf_Undecided);
transarc.SetValue(Standard_True,IntSurf_Undecided);
}
else
IntSurf::MakeTransition(tgline,tgrst,normsurf,transline,transarc);
if (typL == IntPatch_Walking && !refine[ip]) {
// for new vertex use coordinates from Line
if (OnFirst)
GetWLinePoint (wlin, paramline, U1,V1,U2,V2,ptsommet);
else
GetWLinePoint (wlin, paramline, U2,V2,U1,V1,ptsommet);
}
nbTreated++;
if (!ivtx) {
Sommet.SetValue(ptsommet,vtxTol,Standard_False); // pour tangence
if (OnFirst)
Sommet.SetParameters(U1,V1,U2,V2);
else
Sommet.SetParameters(U2,V2,U1,V1);
if (VtxOnArc)
Sommet.SetVertex(OnFirst,vtxarc);
//---------------------------------------------------------
//-- lbr : On remplace le point d indice paramline sur la -
//-- ligne par le vertex . -
//---------------------------------------------------------
Sommet.SetParameter(paramline); // sur ligne d intersection
Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
if (typL == IntPatch_Walking) {
wlin->AddVertex(Sommet);
Nbvtx++;
}
else {
rlin->AddVertex(Sommet);
Nbvtx++;
}
}
else {
// CAS DE FIGURE : en appelant s1 la surf sur laquelle on
// connait les pts sur restriction, et s2 celle sur laquelle
// on les cherche. Le point trouve verifie necessairement
// IsOnDomS1 = True.
// Pas vtxS1, pas vtxS2 :
// on recupere le point et on applique SetArcOnS2 et
// eventuellement SetVertexOnS2. Si on a deja IsOnDomS2,
// on considere que le point est deja traite, mais ne devrait
// pas se produire.
// vtxS1, pas vtxS2 :
// si pas IsOnDomS2 : pour chaque occurrence, faire SetArcOnS2,
// et eventuellement SetVertexOnS2.
// si IsOnDomS2 : impossible, on doit avoir IsVtxOnS2.
// vtxS1,vtxS2 :
// on doit avoir VtxOnArc = True. On duplique chaque occurrence
// "sur S1" du point en changeant ArcOnS2.
// pas vtxS1, vtxS2 :
// on doit avoir VtxOnArc = True. On duplique le point sur S1
// en changeant ArcOnS2.
Standard_Boolean OnDifferentRst =
((OnFirst && ptline.IsOnDomS1() && ptline.ArcOnS1() != arc) ||
(!OnFirst && ptline.IsOnDomS2() && ptline.ArcOnS2() != arc));
ptline.SetTolerance(vtxTol);
if ( (!ptline.IsVertexOnS1() && OnFirst)
|| (!ptline.IsVertexOnS2() && !OnFirst)
|| (OnDifferentRst)) {
if ( (!ptline.IsOnDomS2() && !OnFirst)
||(!ptline.IsOnDomS1() && OnFirst)
||(OnDifferentRst)) {
ptline.SetArc(OnFirst,arc,paramarc,transline,transarc);
//ptline.SetParameter(paramline); //-- rajout lbr le 20 nov 97
if (VtxOnArc)
ptline.SetVertex(OnFirst,vtxarc);
if (typL == IntPatch_Walking) {
if(OnDifferentRst) {
wlin->AddVertex(ptline);
Nbvtx++;
}
else {
wlin->Replace(ivtx,ptline);
}
}
else {
if(OnDifferentRst) {
rlin->AddVertex(ptline);
Nbvtx++;
}
else {
rlin->Replace(ivtx,ptline);
}
}
}
else if ( ( OnFirst && ptline.IsVertexOnS2())
||(!OnFirst && ptline.IsVertexOnS1())) {
Sommet = ptline;
Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
if (VtxOnArc)
Sommet.SetVertex(OnFirst,vtxarc);
if (typL == IntPatch_Walking) {
wlin->AddVertex(Sommet);
Nbvtx++;
}
else {
rlin->AddVertex(Sommet);
Nbvtx++;
}
}
else {
//-- cout << "pb dans RstInt Type 1 " << endl;
// cancel previous solution because this point is better
// but its tolerance is not large enough
ivtx = 0;
}
dmin = dist;
}
}
}
if (ivtx) {
if (ptline.Tolerance() > vtxTol) {
vtxTol = ptline.Tolerance();
if (!VtxOnArc) {
// now we should repeat attempt to coincide on a bound of arc
VtxOnArc = CoincideOnArc(ptsommet,arc,Surf,vtxTol,Domain,vtxarc);
if (VtxOnArc) {
Standard_Real tol = Tol3d(vtxarc,Domain);
if (tol > vtxTol) vtxTol = tol;
}
}
else {
Handle(Adaptor3d_HVertex) vtxref = (OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()) ;
if ( ( OnFirst && !ptline.IsOnDomS2())
||(!OnFirst && !ptline.IsOnDomS1())) {
ptline.SetArc(OnFirst,arc,paramarc,transline,transarc);
if (VtxOnArc)
ptline.SetVertex(OnFirst,vtxarc);
if (typL == IntPatch_Walking) {
}
}
if (typL == IntPatch_Walking)
VerifyTgline(wlin,(Standard_Integer)paramline,edgeTol,tgline);
Surf->D1(U1,V1,ptbid,d1u,d1v);
tgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
normsurf = d1u.Crossed(d1v);
if (normsurf.Magnitude() < gp::Resolution()) {
transline.SetValue(Standard_True,IntSurf_Undecided);
transarc.SetValue(Standard_True,IntSurf_Undecided);
}
else
IntSurf::MakeTransition(tgline,tgrst,normsurf,transline,transarc);
nbTreated++;
if (!ivtx) {
Sommet.SetValue(ptsommet,vtxTol,Standard_False); // pour tangence
if (OnFirst)
Sommet.SetParameters(U1,V1,U2,V2);
else
Sommet.SetParameters(U2,V2,U1,V1);
if (VtxOnArc)
Sommet.SetVertex(OnFirst,vtxarc);
//---------------------------------------------------------
//-- lbr : On remplace le point d indice paramline sur la -
//-- ligne par le vertex . -
//---------------------------------------------------------
Sommet.SetParameter(paramline); // sur ligne d intersection
Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
if (typL == IntPatch_Walking) {
wlin->AddVertex(Sommet);
Nbvtx++;
}
else {
rlin->AddVertex(Sommet);
Nbvtx++;
}
}
else {
// CAS DE FIGURE : en appelant s1 la surf sur laquelle on
// connait les pts sur restriction, et s2 celle sur laquelle
// on les cherche. Le point trouve verifie necessairement
// IsOnDomS1 = True.
// Pas vtxS1, pas vtxS2 :
// on recupere le point et on applique SetArcOnS2 et
// eventuellement SetVertexOnS2. Si on a deja IsOnDomS2,
// on considere que le point est deja traite, mais ne devrait
// pas se produire.
// vtxS1, pas vtxS2 :
// si pas IsOnDomS2 : pour chaque occurrence, faire SetArcOnS2,
// et eventuellement SetVertexOnS2.
// si IsOnDomS2 : impossible, on doit avoir IsVtxOnS2.
// vtxS1,vtxS2 :
// on doit avoir VtxOnArc = True. On duplique chaque occurrence
// "sur S1" du point en changeant ArcOnS2.
// pas vtxS1, vtxS2 :
// on doit avoir VtxOnArc = True. On duplique le point sur S1
// en changeant ArcOnS2.
Standard_Boolean OnDifferentRst =
((OnFirst && ptline.IsOnDomS1() && ptline.ArcOnS1() != arc) ||
(!OnFirst && ptline.IsOnDomS2() && ptline.ArcOnS2() != arc));
ptline.SetTolerance(vtxTol);
if ( (!ptline.IsVertexOnS1() && OnFirst)
|| (!ptline.IsVertexOnS2() && !OnFirst)
|| (OnDifferentRst)) {
if ( (!ptline.IsOnDomS2() && !OnFirst)
||(!ptline.IsOnDomS1() && OnFirst)
||(OnDifferentRst)) {
ptline.SetArc(OnFirst,arc,paramarc,transline,transarc);
//ptline.SetParameter(paramline); //-- rajout lbr le 20 nov 97
if (VtxOnArc)
ptline.SetVertex(OnFirst,vtxarc);
if (typL == IntPatch_Walking) {
if(OnDifferentRst) {
wlin->AddVertex(ptline);
Nbvtx++;
}
else {
wlin->Replace(ivtx,ptline);
}
}
else {
if(OnDifferentRst) {
rlin->AddVertex(ptline);
Nbvtx++;
}
else {
rlin->Replace(ivtx,ptline);
}
for (k=1; k<=Nbvtx; k++) if (k != ivtx) {
if (typL == IntPatch_Walking) {
ptline = wlin->Vertex(k);
}
else {
ptline = rlin->Vertex(k);
}
if ( ( OnFirst && ptline.IsVertexOnS1())
|| (!OnFirst && ptline.IsVertexOnS2())) {
if (Domain->Identical(vtxref, (OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()))) {
if (ptline.Tolerance() < vtxTol) ptline.SetTolerance(vtxTol);
ptline.SetArc(OnFirst,arc,paramarc,transline,transarc);
if (VtxOnArc)
ptline.SetVertex(OnFirst,vtxarc);
if (typL == IntPatch_Walking) {
wlin->Replace(k,ptline);
}
else {
rlin->Replace(k,ptline);
}
}
}
}
}
else if( ( OnFirst && ptline.IsVertexOnS2())
|| (!OnFirst && ptline.IsVertexOnS1())) {
// on doit avoir vtxons2 = vtxarc... pas de verif...
Sommet = ptline;
Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
if (typL == IntPatch_Walking) {
wlin->AddVertex(Sommet);
Nbvtx++;
}
else {
rlin->AddVertex(Sommet);
Nbvtx++;
}
for (k=1; k<=Nbvtx; k++) if (k != ivtx) {
if (typL == IntPatch_Walking) {
ptline = wlin->Vertex(k);
}
else {
ptline = rlin->Vertex(k);
}
if ( ( OnFirst && ptline.IsVertexOnS1())
||(!OnFirst && ptline.IsVertexOnS2())) {
if (Domain->Identical(vtxref,(OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()))) {
if (ptline.Tolerance() < vtxTol) ptline.SetTolerance(vtxTol);
Sommet = ptline;
Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
if (typL == IntPatch_Walking) {
wlin->Replace(k,ptline);
wlin->AddVertex(Sommet);
Nbvtx++;
}
else {
rlin->Replace(k,ptline);
rlin->AddVertex(Sommet);
Nbvtx++;
}
}
}
}
}
else if ( ( OnFirst && ptline.IsVertexOnS2())
||(!OnFirst && ptline.IsVertexOnS1())) {
Sommet = ptline;
Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
if (VtxOnArc)
Sommet.SetVertex(OnFirst,vtxarc);
if (typL == IntPatch_Walking) {
wlin->AddVertex(Sommet);
Nbvtx++;
}
else {
//-- cout << "pb dans RstInt Type 2 " << endl;
rlin->AddVertex(Sommet);
Nbvtx++;
}
}
else {
//-- cout << "pb dans RstInt Type 1 " << endl;
}
}
else {
Handle(Adaptor3d_HVertex) vtxref = (OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()) ;
if ( ( OnFirst && !ptline.IsOnDomS2())
||(!OnFirst && !ptline.IsOnDomS1())) {
ptline.SetArc(OnFirst,arc,paramarc,transline,transarc);
if (VtxOnArc)
ptline.SetVertex(OnFirst,vtxarc);
if (typL == IntPatch_Walking) {
wlin->Replace(ivtx,ptline);
}
else {
rlin->Replace(ivtx,ptline);
}
for (k=1; k<=Nbvtx; k++) if (k != ivtx) {
if (typL == IntPatch_Walking) {
ptline = wlin->Vertex(k);
}
else {
ptline = rlin->Vertex(k);
}
if ( ( OnFirst && ptline.IsVertexOnS1())
|| (!OnFirst && ptline.IsVertexOnS2())) {
if (Domain->Identical(vtxref, (OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()))) {
if (ptline.Tolerance() < vtxTol) ptline.SetTolerance(vtxTol);
ptline.SetArc(OnFirst,arc,paramarc,transline,transarc);
if (VtxOnArc)
ptline.SetVertex(OnFirst,vtxarc);
if (typL == IntPatch_Walking) {
wlin->Replace(k,ptline);
}
else {
rlin->Replace(k,ptline);
}
}
}
}
}
else if( ( OnFirst && ptline.IsVertexOnS2())
|| (!OnFirst && ptline.IsVertexOnS1())) {
// on doit avoir vtxons2 = vtxarc... pas de verif...
Sommet = ptline;
Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
if (typL == IntPatch_Walking) {
wlin->AddVertex(Sommet);
Nbvtx++;
}
else {
rlin->AddVertex(Sommet);
Nbvtx++;
}
for (k=1; k<=Nbvtx; k++) if (k != ivtx) {
if (typL == IntPatch_Walking) {
ptline = wlin->Vertex(k);
}
else {
ptline = rlin->Vertex(k);
}
if ( ( OnFirst && ptline.IsVertexOnS1())
||(!OnFirst && ptline.IsVertexOnS2())) {
if (Domain->Identical(vtxref,(OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()))) {
if (ptline.Tolerance() < vtxTol) ptline.SetTolerance(vtxTol);
Sommet = ptline;
Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
if (typL == IntPatch_Walking) {
wlin->Replace(k,ptline);
wlin->AddVertex(Sommet);
Nbvtx++;
}
else {
rlin->Replace(k,ptline);
rlin->AddVertex(Sommet);
Nbvtx++;
}
}
}
}
}
else {
//-- cout << "pb dans RstInt Type 2 " << endl;
}
}
}
}

View File

@@ -1218,8 +1218,7 @@ Handle(IntPatch_WLine) IntPatch_WLineTool::
const Handle(Adaptor3d_HSurface) &theS1,
const Handle(Adaptor3d_HSurface) &theS2,
const Handle(Adaptor3d_TopolTool) &theDom1,
const Handle(Adaptor3d_TopolTool) &theDom2,
const Standard_Boolean theRestrictLine)
const Handle(Adaptor3d_TopolTool) &theDom2)
{
Standard_Integer i, k, v, nb, nbvtx;
Handle(IntPatch_WLine) aResult;
@@ -1322,11 +1321,8 @@ Handle(IntPatch_WLine) IntPatch_WLineTool::
return aLocalWLine;
}
if (theRestrictLine)
{
// II: Delete out of borders points.
aLocalWLine = DeleteOuterPoints(aLocalWLine, theS1, theS2, theDom1, theDom2);
}
// II: Delete out of borders points.
aLocalWLine = DeleteOuterPoints(aLocalWLine, theS1, theS2, theDom1, theDom2);
// III: Delete points by tube criteria.
Handle(IntPatch_WLine) aLocalWLineTube =

View File

@@ -34,7 +34,6 @@ public:
//!
//! II
//! Removes point out of borders in case of non periodic surfaces.
//! This step is done only if theRestrictLine is true.
//!
//! III
//! Removes exceed points using tube criteria:
@@ -48,8 +47,7 @@ public:
const Handle(Adaptor3d_HSurface) &theS1,
const Handle(Adaptor3d_HSurface) &theS2,
const Handle(Adaptor3d_TopolTool) &theDom1,
const Handle(Adaptor3d_TopolTool) &theDom2,
const Standard_Boolean theRestrictLine);
const Handle(Adaptor3d_TopolTool) &theDom2);
//! Joins all WLines from theSlin to one if it is possible and records
//! the result into theSlin again. Lines will be kept to be splitted if:

View File

@@ -358,8 +358,6 @@ static Standard_Boolean isTreatAnalityc(const BRepAdaptor_Surface& theBAS1,
void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
const TopoDS_Face& aF2)
{
Standard_Boolean RestrictLine = Standard_False;
if (myContext.IsNull()) {
myContext=new IntTools_Context;
}
@@ -509,14 +507,6 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
myIntersector.SetTolerances(TolArc, TolTang, UVMaxStep, Deflection);
}
if((myHS1->IsUClosed() && !myHS1->IsUPeriodic()) ||
(myHS1->IsVClosed() && !myHS1->IsVPeriodic()) ||
(myHS2->IsUClosed() && !myHS2->IsUPeriodic()) ||
(myHS2->IsVClosed() && !myHS2->IsVPeriodic()))
{
RestrictLine = Standard_True;
}
//
if((aType1 != GeomAbs_BSplineSurface) &&
(aType1 != GeomAbs_BezierSurface) &&
(aType1 != GeomAbs_OtherSurface) &&
@@ -524,8 +514,6 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
(aType2 != GeomAbs_BezierSurface) &&
(aType2 != GeomAbs_OtherSurface))
{
RestrictLine = Standard_True;
if ((aType1 == GeomAbs_Torus) ||
(aType2 == GeomAbs_Torus))
{
@@ -533,27 +521,6 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
}
}
//
if(!RestrictLine)
{
TopExp_Explorer aExp;
for(Standard_Integer i = 0; (!RestrictLine) && (i < 2); i++)
{
const TopoDS_Face& aF=(!i) ? myFace1 : myFace2;
aExp.Init(aF, TopAbs_EDGE);
for(; aExp.More(); aExp.Next())
{
const TopoDS_Edge& aE=TopoDS::Edge(aExp.Current());
if(BRep_Tool::Degenerated(aE))
{
RestrictLine = Standard_True;
break;
}
}
}
}
#ifdef INTTOOLS_FACEFACE_DEBUG
if(!myListOfPnts.IsEmpty()) {
char aBuff[10000];
@@ -581,7 +548,7 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
myIntersector.Perform(myHS1, dom1, TolArc, TolTang);
else
myIntersector.Perform(myHS1, dom1, myHS2, dom2, TolArc, TolTang,
myListOfPnts, RestrictLine, isGeomInt);
myListOfPnts, isGeomInt);
myIsDone = myIntersector.IsDone();
@@ -592,10 +559,6 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
return;
}
//
if(RestrictLine) {
myListOfPnts.Clear(); // to use LineConstructor
}
//
const Standard_Integer aNbLinIntersector = myIntersector.NbLines();
for (Standard_Integer i=1; i <= aNbLinIntersector; ++i) {
MakeCurve(i, dom1, dom2, TolArc);

View File

@@ -2361,7 +2361,16 @@ SeekPointOnBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
{
aP1.SetXYZ(line->Value(aPInd).Value().XYZ());
if (aP1.SquareDistance(aPInt) > Precision::SquareConfusion())
{
break;
}
else if (aPInd == 1)
{
// After insertion, we will obtain
// two coincident points in the line.
// Therefore, insertion is forbidden.
return isOK;
}
}
for (++aPInd; aPInd <= aNbPnts; aPInd++)
@@ -2402,7 +2411,16 @@ SeekPointOnBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
{
aPCurr.SetXYZ(line->Value(aPInd).Value().XYZ());
if (aPCurr.SquareDistance(aPInt) > Precision::SquareConfusion())
{
break;
}
else if (aPInd == aNbPnts)
{
// After insertion, we will obtain
// two coincident points in the line.
// Therefore, insertion is forbidden.
return isOK;
}
}
for (--aPInd; aPInd > 0; aPInd--)

View File

@@ -887,7 +887,7 @@ Standard_Boolean LocOpe_SplitShape::AddOpenWire(const TopoDS_Wire& W,
aLocalFace = FaceRef.Oriented(wfirst.Orientation());
GetDirection(LastEdge, TopoDS::Face(aLocalFace),plast , dlast, Standard_False);
Standard_Boolean cond;
Standard_Boolean cond = Standard_True;
if(IsPeriodic) {
@@ -1511,7 +1511,7 @@ Standard_Boolean ChoixUV(const TopoDS_Edge& Last,
BRepAdaptor_Surface surf(F,Standard_False); // no restriction
surf.D0 (plst.X(), plst.Y(), aPlst);
gp_Dir2d ref2d(dlst);
Handle(Geom2d_Curve) C2d;
@@ -1524,6 +1524,8 @@ Standard_Boolean ChoixUV(const TopoDS_Edge& Last,
TopoDS_Edge anEdge = TopoDS::Edge (Poss.FindKey (index));
GetDirection(anEdge, F, p2d, v2d, Standard_True);
if(!SameUV(plst,p2d,surf))
continue;
surf.D0 (p2d.X(), p2d.Y(), aPCur);

View File

@@ -18,4 +18,5 @@
018 mesh
019 heal
020 stlvrml
021 splitshape
021 splitshape
022 splitshape1

View File

@@ -6,17 +6,16 @@ puts ""
# Cannot project point on curve
#########################################################################
cpulimit 1500
bsplinecurve r3 2 6 1 3 2 1 3 1 4 1 5 1 6 3 2 5 3 1 3 7 3 1 4 8 3 1 4 8 3 1 4 8 3 1 5 9 3 1 9 7 3 1
bsplinecurve r4 2 6 2 3 2.5 1 3 1 3.5 1 4 1 4.5 3 -1 2 3 1 1 11 3 1 3 9 3 1 3 9 3 1 3 9 3 1 5 7 3 1 7 4 3 1
set info [extrema r3 r4]
regexp {Infinite number of extremas, distance = +([-0-9.+eE]+)} $info full dist
if { $dist > 4.0e-13 } {
puts "Error : Extrema distance is too big"
if {[regexp "ext_1" $info]} {
set dist [lindex [length ext_1] end]
if { $dist > 4.0e-13 } {
puts "Error: Extrema distance is too big"
}
} else {
puts "OK: Extrema distance is good"
puts "Error: Extrema is not found"
}

View File

@@ -6,6 +6,10 @@ puts ""
## Wrong section curves
###############################
puts "TODO OCC29501 ALL: Error in ii12_22"
set MaxToler 1.5e-4
restore [locate_data_file bug24472_Pipe_1.brep] b1
explode b1 f
@@ -19,43 +23,51 @@ mksurface s3 f3
puts ""
puts "First test"
# 1.1 geometry
intersect i s1 s2
intersect ii12 s1 s2
#donly i_22; fit
xdistcs i_22 s1 0 1 10 1e-7
foreach c [directory ii12*] {
bounds $c U1 U2
if {[dval U2-U1] < 1.0e-9} {
puts "Error: Wrong curve's range!"
}
xdistcs $c s1 U1 U2 10 $MaxToler
xdistcs $c s2 U1 U2 10 $MaxToler
}
puts ""
puts "Second test"
# 1.2 topology
bsection r f1 f2
bopcheck r
# r is self interfered
explode r e
mkcurve c r_1
bsection r12 f1 f2
bopcheck r12
# OK
#donly r_1; fit
xdistcs c s1 0.0714822451660209 1 10 1e-12 1e-7
regexp {Tolerance MAX=([-0-9.+eE]+)} [tolerance r12] full toler
if { $toler > $MaxToler } { puts "Error: Tolerance of the section r12 is too large" }
puts ""
puts "Third test"
# 2.1 geometry
intersect i s1 s3
intersect ii13 s1 s3
#donly i_4; fit
xdistcs i_4 s1 0 1 10 1e-6 1e-7
foreach c [directory ii13*] {
bounds $c U1 U2
if {[dval U2-U1] < 1.0e-9} {
puts "Error: Wrong curve's range!"
}
xdistcs $c s1 U1 U2 10 $MaxToler
xdistcs $c s2 U1 U2 10 $MaxToler
}
puts ""
puts "Fourth test"
# 2.2 topology
bsection r f1 f3
bopcheck r
#r is self interfered
explode r
mkcurve c r_1
bsection r13 f1 f3
bopcheck r13
# OK
#donly r_1; fit
xdistcs c s1 0.0714822451660209 1 10 1e-12 1e-7
regexp {Tolerance MAX=([-0-9.+eE]+)} [tolerance r13] full toler
if { $toler > $MaxToler } { puts "Error: Tolerance of the section r13 is too large" }

View File

@@ -6,35 +6,50 @@ puts ""
## Intersection algorithm produces curves overlaped
###############################
set ExpToler 1.0422975608071429e-007
set ExpLen 5.0363617398558773
restore [locate_data_file bug25890_f1.brep] f1
restore [locate_data_file bug25890_f2.brep] f2
set log [bopcurves f1 f2]
set log [ bopcurves f1 f2 -2d ]
regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv
if { ${NbCurv} != 5 } {
puts "Error : NbCurv is bad"
}
checkreal TolReached $Toler $ExpToler 0.0 0.1
set nbshapes_expected "
Number of shapes in shape
VERTEX : 0
EDGE : 0
WIRE : 0
FACE : 0
SHELL : 0
SOLID : 0
COMPSOLID : 0
COMPOUND : 1
SHAPE : 1
"
if { ${NbCurv} != 1 } {
puts "Error : NbCurv is bad"
set nbshapes_expected "
Number of shapes in shape
VERTEX : 0
EDGE : 0
WIRE : 0
FACE : 0
SHELL : 0
SOLID : 0
COMPSOLID : 0
COMPOUND : 1
SHAPE : 1
"
for {set i 1} {$i <= $NbCurv} {incr i} {
for {set j [expr $i+1]} {$j <= $NbCurv} {incr j} {
puts " Check c_$i and c_$j"
mkedge e1 c_$i
mkedge e2 c_$j
bcommon rr e1 e2
checknbshapes rr -ref "${nbshapes_expected}" -t -m "Partition of 2 shapes"
set SumLen 0.0
# Check for overlapping
for {set i 1} {$i <= $NbCurv} {incr i} {
regexp "The +length+ c_$i +is +(\[-0-9.+eE\]+)" [ length c_$i ] full m
set SumLen [ expr $SumLen + $m]
for {set j [expr $i+1]} {$j <= $NbCurv} {incr j} {
puts " Check c_$i and c_$j"
mkedge e1 c_$i
mkedge e2 c_$j
bcommon rr e1 e2
checknbshapes rr -ref "${nbshapes_expected}" -t -m "Partition of 2 shapes"
}
}
checkreal Length $SumLen $ExpLen 1.0e-7 0.0
} else {
checklength c_1 -l $ExpLen
}

View File

@@ -24,7 +24,7 @@ whatis result_1
checkshape result_1
checkprops result_1 -v 15041.2 -s 8245.4
checkprops result_1 -v 15287.7 -s 8383.16
checkview -display result_1 -2d -path ${imagedir}/${test_image}.png

View File

@@ -9,10 +9,28 @@ puts ""
restore [locate_data_file bug25994_body.brep] body
restore [locate_data_file bug25994_wing.brep] wing
bfuse result body wing
bclearobjects
bcleartools
baddobjects body
baddtools wing
bfillds
bbop rs 4
regexp {nb alone Vertices : ([-0-9.+eE]+)} [checksection result] full nbv
if { $nbv != 0 } { puts "Error : Section is not closed" }
regexp {Tolerance MAX=([-0-9.+eE]+)} [tolerance rs] full toler
if { $toler > 5.0e-5 } {
puts "Error: Tolerance after section is too large"
}
bbop result 1
checkshape result
checknbshapes result -solid 1 -shell 1 -face 13 -wire 15
checkprops result -s 1.76161e+006 -v 1.07392e+008
smallview
fit
checkview -screenshot -2d -path ${imagedir}/${test_image}.png
checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,26 @@
puts "========"
puts "OCC29488"
puts "========"
puts ""
#################################################
# Regression: boolean operation " general fuse" creates solid containing 5 not connected shells lying on the one level
#################################################
restore [locate_data_file bug29488_shapes.brep] s
eval mkvolume result [lrange [explode s] 1 end]
checkshape result
checknbshapes result -wire 74 -face 74 -shell 1 -solid 1
checkprops result -s 3073.39 -v 10240.8
set MinArea 0.001
foreach f [explode result f] {
regexp {Mass +: +([-0-9.+eE]+)} [sprops $f 1.0e-4] full anArea
if { $anArea == 0.0 } {
puts "Error in area computation: it is equal to 0"
} elseif {$anArea < $MinArea} {
puts "Error: Too small face has been created (S < $MinArea)"
}
}
checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,31 @@
puts "========"
puts "OCC29488"
puts "========"
puts ""
#################################################
# Regression: boolean operation " general fuse" creates solid containing 5 not connected shells lying on the one level
#################################################
restore [locate_data_file bug29488_shapes.brep] s
bclearobjects
bcleartools
eval baddobjects [explode s]
bfillds
bbuild result
checkshape result
checknbshapes result -wire 390 -face 366 -shell 10 -solid 2
checkprops result -s 77135.9 -v 245074
set MinArea 0.001
foreach f [explode result f] {
regexp {Mass +: +([-0-9.+eE]+)} [sprops $f 1.0e-4] full anArea
if { $anArea == 0.0 } {
puts "Error in area computation: it is equal to 0"
} elseif {$anArea < $MinArea} {
puts "Error: Too small face has been created (S < $MinArea)"
}
}
checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,35 @@
puts "========"
puts "OCC29494"
puts "========"
puts ""
#################################################
# Intersection line between two parametric surfaces is restricted incorrectly if it matches
# the surface boundary
#################################################
restore [locate_data_file bug29488_shapes.brep] s
explode s
explode s_4 f; copy s_4_13 f1
explode s_6 f; copy s_6_18 f2
smallview
clear
bopcurves f1 f2 -2d
regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves f1 f2 -2d] full Toler NbCurv
if {$Toler > 1.0e-7} {
puts "Error: Big tolerance is returned by intersector"
}
if {$NbCurv != 1} {
puts "Error: Please check NbCurves for intersector"
} else {
checklength c_1 -l 19.2
}
fit
disp f1 f2
checkview -screenshot -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,57 @@
puts "========"
puts "OCC29496"
puts "========"
puts ""
#################################################
# No intersection curve between faces if starting points are given
#################################################
restore [locate_data_file bug29488_shapes.brep] s
explode s shell
set i 1
explode s_2 f; copy s_2_27 f1
explode s_6 f; copy s_6_20 f2
bsection r$i f1 f2
checknbshapes r$i -vertex 2 -edge 1
checkprops r$i -l 2.14991
incr i
explode s_2 f; copy s_2_27 f1
explode s_7 f; copy s_7_8 f2
bsection r$i f1 f2
checknbshapes r$i -vertex 2 -edge 1
checkprops r$i -l 2.15901
incr i
explode s_3 f; copy s_3_27 f1
explode s_7 f; copy s_7_8 f2
bsection r$i f1 f2
checknbshapes r$i -vertex 2 -edge 1
checkprops r$i -l 2.15901
incr i
explode s_3 f; copy s_3_27 f1
explode s_6 f; copy s_6_16 f2
bsection r$i f1 f2
checknbshapes r$i -vertex 2 -edge 1
checkprops r$i -l 2.14991
incr i
explode s_2 f; copy s_2_26 f1
explode s_7 f; copy s_7_2 f2
bsection r$i f1 f2
checknbshapes r$i -vertex 2 -edge 1
checkprops r$i -l 2.22733
incr i
explode s_3 f; copy s_3_26 f1
explode s_7 f; copy s_7_2 f2
bsection r$i f1 f2
checknbshapes r$i -vertex 2 -edge 1
checkprops r$i -l 2.22733

View File

@@ -0,0 +1,24 @@
puts "========"
puts "OCC29887: Wrong result of CUT operation due to incorrect point-face classification"
puts "========"
puts ""
brestore [locate_data_file bug29887_ar_shape_to_cuts.brep] s1
brestore [locate_data_file bug29887_ar_cutting_shapes.brep] s2
bcut result s1 s2
checknbshapes result -face 2 -wire 2
checkshape result
if {[regexp "Faulties" [bopargcheck result]]} {
puts "Error: bopargcheck has found some faulties in result"
}
checkprops result -s 319.71
smallview
don result
fit
checkview -screenshot -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,28 @@
puts "========"
puts "OCC29887: Wrong result of CUT operation due to incorrect point-face classification"
puts "========"
puts ""
brestore [locate_data_file bug29887_ar_shape_to_cuts.brep] s1
point p 11.633693861603586 -0.88940231049090079
if { ![regexp {IN} [ b2dclassifx s1 p ] ] } {
puts "Error : Wrong result of 2d classifier algorithm"
} else {
puts "OK : Good result of 2d classifier algorithm"
}
if { ![regexp {IN} [ b2dclassify s1 p ] ] } {
puts "Error : Wrong result of 2d classifier algorithm"
} else {
puts "OK : Good result of 2d classifier algorithm"
}
smallview -2D-
2dclear
display p
pcurve s1
2dfit
checkview -screenshot -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,19 @@
puts "=============="
puts " splitshape_1 "
puts " "
puts "=============="
puts ""
#puts " 0029473 "
###################################################
# Operation "splitshape" in the Test Harness give invalid result on the attached case.
###################################################
restore [locate_data_file bug29473_Split.brep] a
explode a
explode a_1
explode a_2
wire w1 a_2_1 a_2_2 a_2_3
wire w2 a_2_4 a_2_5
explode a_1_5 e
splitshape r1 a_1 a_1_1 w1 a_1_3 w2 a_1_4 a_2_6 a_1_5 a_2_7 @ a_1_5_4 a_2_8
explode r1 f
copy r1_1 result

View File

@@ -0,0 +1,11 @@
# test script to check validity of shape
########################################################################
checkshape result
maxtolerance result
smallview
display result
fit
checkview -screenshot -2d -path ${imagedir}/${test_image}.png

14
tests/lowalgos/begin Normal file
View File

@@ -0,0 +1,14 @@
if { [array get Draw_Groups "TOPOLOGY Check commands"] == "" } {
pload TOPTEST
pload AISV
}
# To prevent loops limit to 1 minutes
cpulimit 60
if { [info exists imagedir] == 0 } {
set imagedir .
}
if { [info exists test_image ] == 0 } {
set test_image photo
}

View File

@@ -0,0 +1,21 @@
puts "========"
puts "OCC29463"
puts "========"
puts ""
#################################################
# Method BndBox::IsOut() returns true for point lying on the planar face
#################################################
restore [locate_data_file bug29463_face13_691.brep] f
set x 165.16888924444618
set y 16.119975403493935
set z 6.6799998283386177
# check that vertex with coordinates (x, y, z) is inside the bounding box of f
boundingstr f xmin ymin zmin xmax ymax zmax
if {$x < [dval xmin] || $x > [dval xmax] || $y < [dval ymin] || $y > [dval ymax] || $z < [dval zmin] || $z > [dval zmax]} {
puts "Error: bounding box works incorrect"
}

2
tests/lowalgos/end Normal file
View File

@@ -0,0 +1,2 @@
# to end a test script
puts "TEST COMPLETED"

View File

@@ -0,0 +1,12 @@
proc CheckExtResult {info ref_dist} {
global ext_1
if {[regexp "ext_1" $info]} {
set dist [lindex [length ext_1] end]
if { $dist > $ref_dist } {
puts "Error: Extrema distance is too big"
}
} else {
puts "Error: Extrema is not found"
}
}

View File

@@ -0,0 +1,29 @@
puts "============"
puts "OCC29465"
puts "============"
puts ""
#########################################################################
# Regression relation to 691 version: Extrema_ExtCC returns IsParallel equal to true for not parallel curves
#########################################################################
set dist 3.e-5
restore [locate_data_file bug29465.brep] ce
explode ce e
mkcurve c1 ce_1
mkcurve c2 ce_2
CheckExtResult [extrema c1 c2] $dist
CheckExtResult [extrema c2 c1] $dist
reverse c1
CheckExtResult [extrema c1 c2] $dist
CheckExtResult [extrema c2 c1] $dist
reverse c2
CheckExtResult [extrema c1 c2] $dist
CheckExtResult [extrema c2 c1] $dist
reverse c1
CheckExtResult [extrema c1 c2] $dist
CheckExtResult [extrema c2 c1] $dist

View File

@@ -0,0 +1,31 @@
puts "============"
puts "OCC29465"
puts "============"
puts ""
#########################################################################
# Regression relation to 691 version: Extrema_ExtCC returns IsParallel equal to true for not parallel curves
#########################################################################
set dist 0.2
restore [locate_data_file bug27371.brep] s
explode s
explode s_1 e
mkcurve c1 s_1_1
explode s_2 e
mkcurve c2 s_2_20
CheckExtResult [extrema c1 c2] $dist
CheckExtResult [extrema c2 c1] $dist
reverse c1
CheckExtResult [extrema c1 c2] $dist
CheckExtResult [extrema c2 c1] $dist
reverse c2
CheckExtResult [extrema c1 c2] $dist
CheckExtResult [extrema c2 c1] $dist
reverse c1
CheckExtResult [extrema c1 c2] $dist
CheckExtResult [extrema c2 c1] $dist

View File

@@ -0,0 +1,3 @@
001 2dinter
002 bnd
003 extcc

View File

@@ -0,0 +1 @@
FAILED /\bFaulty\b/ bad shape