When splitting the shell/face with internal faces/edges use the 'internal' criteria of the face to choose the way to create loops.
Side effect changes:
- When performing Boolean operation - move the objects located far from Origin to the Origin to increase the accuracy of intersections.
Handle(BOPDS_PaveBlock)& PaveBlock2() {
return myPB2;
}
- //
+ //
+ void SetBoxes (const Bnd_Box& theBox1,
+ const Bnd_Box& theBox2)
+ {
+ myBox1 = theBox1;
+ myBox2 = theBox2;
+ }
+ //
void SetFuzzyValue(const Standard_Real theFuzz) {
IntTools_EdgeEdge::SetFuzzyValue(theFuzz);
}
//
virtual void Perform() {
BOPAlgo_Algo::UserBreak();
+ TopoDS_Edge anE1 = myEdge1, anE2 = myEdge2;
+ Standard_Boolean hasTrsf = false;
try
{
OCC_CATCH_SIGNALS
+ gp_Trsf aTrsf;
+ if (BOPAlgo_Tools::TrsfToPoint (myBox1, myBox2, aTrsf))
+ {
+ // Shapes are located far from origin, move the shapes to the origin,
+ // to increase the accuracy of intersection.
+ TopLoc_Location aLoc (aTrsf);
+ myEdge1.Move (aLoc);
+ myEdge2.Move (aLoc);
+ hasTrsf = Standard_True;
+ }
+
IntTools_EdgeEdge::Perform();
}
catch (Standard_Failure const&)
{
AddError(new BOPAlgo_AlertIntersectionFailed);
}
+
+ myEdge1 = anE1;
+ myEdge2 = anE2;
+ if (hasTrsf)
+ {
+ for (Standard_Integer i = 1; i <= myCommonParts.Length(); ++i)
+ {
+ IntTools_CommonPrt& aCPart = myCommonParts (i);
+ aCPart.SetEdge1 (myEdge1);
+ aCPart.SetEdge2 (myEdge2);
+ }
+ }
+
}
//
protected:
Handle(BOPDS_PaveBlock) myPB1;
Handle(BOPDS_PaveBlock) myPB2;
+ Bnd_Box myBox1;
+ Bnd_Box myBox2;
};
//
//=======================================================================
//
anEdgeEdge.SetEdge1(aE1, aT11, aT12);
anEdgeEdge.SetEdge2(aE2, aT21, aT22);
+ anEdgeEdge.SetBoxes (aBB1, aBB2);
anEdgeEdge.SetFuzzyValue(myFuzzyValue);
anEdgeEdge.SetProgressIndicator(myProgressIndicator);
}//for (; aIt2.More(); aIt2.Next()) {
if (!aNbPB)
return;
+ const Standard_Boolean bSICheckMode = (myArguments.Extent() == 1);
+
// Prepare pave blocks with the same vertices for intersection.
BOPAlgo_VectorOfEdgeEdge aVEdgeEdge;
const TopoDS_Vertex& aV1 = TopoDS::Vertex(myDS->Shape(nV1));
const TopoDS_Vertex& aV2 = TopoDS::Vertex(myDS->Shape(nV2));
- // Use the max tolerance of vertices as Fuzzy value for intersection
- // of edges
- Standard_Real aTolAdd = 2 * Max(BRep_Tool::Tolerance(aV1),
- BRep_Tool::Tolerance(aV2));
+ // Use the max tolerance of vertices as Fuzzy value for intersection of edges.
+ // In the Self-Interference check mode we are interested in real
+ // intersections only, so use only the real tolerance of edges,
+ // no need to use the extended tolerance.
+ Standard_Real aTolAdd = (bSICheckMode ? myFuzzyValue :
+ 2 * Max(BRep_Tool::Tolerance(aV1), BRep_Tool::Tolerance(aV2)));
// All possible pairs combined from the list <aLPB> should be checked
BOPDS_ListIteratorOfListOfPaveBlock aItLPB1(aLPB);
anEdgeEdge.SetPaveBlock2(aPB2);
anEdgeEdge.SetEdge1(aE1, aT11, aT12);
anEdgeEdge.SetEdge2(aE2, aT21, aT22);
+ anEdgeEdge.SetBoxes (myDS->ShapeInfo(nE1).Box(), myDS->ShapeInfo (nE2).Box());
if (bUseAddTol)
anEdgeEdge.SetFuzzyValue(myFuzzyValue + aTolAdd);
else
IntTools_EdgeFace::SetFuzzyValue(theFuzz);
}
//
+ void SetBoxes (const Bnd_Box& theBox1,
+ const Bnd_Box& theBox2)
+ {
+ myBox1 = theBox1;
+ myBox2 = theBox2;
+ }
+ //
virtual void Perform() {
BOPAlgo_Algo::UserBreak();
+ TopoDS_Face aFace = myFace;
+ TopoDS_Edge anEdge = myEdge;
+ Standard_Boolean hasTrsf = false;
try
{
OCC_CATCH_SIGNALS
+ gp_Trsf aTrsf;
+ if (BOPAlgo_Tools::TrsfToPoint (myBox1, myBox2, aTrsf))
+ {
+ // Shapes are located far from origin, move the shapes to the origin,
+ // to increase the accuracy of intersection.
+ TopLoc_Location aLoc (aTrsf);
+ myEdge.Move (aLoc);
+ myFace.Move (aLoc);
+ hasTrsf = Standard_True;
+ }
+
IntTools_EdgeFace::Perform();
}
catch (Standard_Failure const&)
{
AddError(new BOPAlgo_AlertIntersectionFailed);
}
+ myFace = aFace;
+ myEdge = anEdge;
+
+ if (hasTrsf)
+ {
+ for (Standard_Integer i = 1; i <= mySeqOfCommonPrts.Length(); ++i)
+ {
+ IntTools_CommonPrt& aCPart = mySeqOfCommonPrts (i);
+ aCPart.SetEdge1 (myEdge);
+ }
+ }
}
//
protected:
Standard_Integer myIF;
IntTools_Range myNewSR;
Handle(BOPDS_PaveBlock) myPB;
+ Bnd_Box myBox1;
+ Bnd_Box myBox2;
};
//
//=======================================================================
//
aEdgeFace.SetEdge (aE);
aEdgeFace.SetFace (aF);
+ aEdgeFace.SetBoxes (myDS->ShapeInfo(nE).Box(), myDS->ShapeInfo (nF).Box());
aEdgeFace.SetFuzzyValue(myFuzzyValue);
aEdgeFace.UseQuickCoincidenceCheck(bExpressCompute);
//
// Shake the tree
aBBTree.Build();
+ const Standard_Boolean bSICheckMode = (myArguments.Extent() == 1);
+
// Find pairs of Face/PaveBlock containing the same vertices
// and prepare those pairs for intersection.
BOPAlgo_VectorOfEdgeFace aVEdgeFace;
// tolerance as the criteria.
const TopoDS_Vertex& aV1 = TopoDS::Vertex(myDS->Shape(nV1));
const TopoDS_Vertex& aV2 = TopoDS::Vertex(myDS->Shape(nV2));
- Standard_Real aTolCheck = 2 * Max(BRep_Tool::Tolerance(aV1),
- BRep_Tool::Tolerance(aV2));
+
+ // In the Self-Interference check mode we are interested in real
+ // intersections only, so use only the real tolerance of edges,
+ // no need to use the extended tolerance.
+ Standard_Real aTolCheck = (bSICheckMode ? myFuzzyValue :
+ 2 * Max(BRep_Tool::Tolerance(aV1), BRep_Tool::Tolerance(aV2)));
if (aProjPS.LowerDistance() > aTolCheck + myFuzzyValue)
continue;
aEdgeFace.SetPaveBlock(aPB);
aEdgeFace.SetEdge(aE);
aEdgeFace.SetFace(aF);
+ aEdgeFace.SetBoxes (myDS->ShapeInfo(nE).Box(), myDS->ShapeInfo (nF).Box());
aEdgeFace.SetFuzzyValue(myFuzzyValue + aTolAdd);
aEdgeFace.UseQuickCoincidenceCheck(Standard_True);
aEdgeFace.SetRange(IntTools_Range(aPB->Pave1().Parameter(), aPB->Pave2().Parameter()));
myF2=aF2;
}
//
+ void SetBoxes(const Bnd_Box& theBox1,
+ const Bnd_Box& theBox2) {
+ myBox1 = theBox1;
+ myBox2 = theBox2;
+ }
+ //
const TopoDS_Face& Face1()const {
return myF1;
}
IntTools_FaceFace::SetFuzzyValue(theFuzz);
}
//
+ const gp_Trsf& Trsf() const { return myTrsf; }
+ //
virtual void Perform() {
BOPAlgo_Algo::UserBreak();
try
{
OCC_CATCH_SIGNALS
- IntTools_FaceFace::Perform(myF1, myF2);
+ gp_Trsf aTrsf;
+ TopoDS_Face aF1 = myF1, aF2 = myF2;
+ if (BOPAlgo_Tools::TrsfToPoint (myBox1, myBox2, aTrsf))
+ {
+ // Shapes are located far from origin, move the shapes to the origin,
+ // to increase the accuracy of intersection.
+ TopLoc_Location aLoc (aTrsf);
+ aF1.Move (aLoc);
+ aF2.Move (aLoc);
+
+ // The starting point is initialized only with the UV parameters
+ // on the faces - 3D point is not set (see GetEFPnts method),
+ // so no need to transform anything.
+ //for (IntSurf_ListOfPntOn2S::Iterator it (myListOfPnts); it.More(); it.Next())
+ //{
+ // IntSurf_PntOn2S& aP2S = it.ChangeValue();
+ // aP2S.SetValue (aP2S.Value().Transformed (aTrsf));
+ //}
+
+ myTrsf = aTrsf.Inverted();
+ }
+
+ IntTools_FaceFace::Perform (aF1, aF2);
}
catch (Standard_Failure const&)
{
}
}
//
+ void ApplyTrsf()
+ {
+ if (IsDone())
+ {
+ // Update curves
+ for (Standard_Integer i = 1; i <= mySeqOfCurve.Length(); ++i)
+ {
+ IntTools_Curve& aIC = mySeqOfCurve (i);
+ aIC.Curve()->Transform (myTrsf);
+ }
+ // Update points
+ for (Standard_Integer i = 1; i <= myPnts.Length(); ++i)
+ {
+ IntTools_PntOn2Faces& aP2F = myPnts (i);
+ IntTools_PntOnFace aPOnF1 = aP2F.P1(), aPOnF2 = aP2F.P2();
+ aPOnF1.SetPnt (aPOnF1.Pnt().Transformed (myTrsf));
+ aPOnF2.SetPnt (aPOnF2.Pnt().Transformed (myTrsf));
+ aP2F.SetP1 (aPOnF1);
+ aP2F.SetP2 (aPOnF2);
+ }
+ }
+ }
+
+ //
protected:
Standard_Integer myIF1;
Standard_Integer myIF2;
Standard_Real myTolFF;
TopoDS_Face myF1;
TopoDS_Face myF2;
+ Bnd_Box myBox1;
+ Bnd_Box myBox2;
+ gp_Trsf myTrsf;
};
//
//=======================================================================
//
aFaceFace.SetIndices(nF1, nF2);
aFaceFace.SetFaces(aF1, aF2);
+ aFaceFace.SetBoxes (myDS->ShapeInfo (nF1).Box(), myDS->ShapeInfo (nF2).Box());
// compute minimal tolerance for the curves
Standard_Real aTolFF = ToleranceFF(aBAS1, aBAS2);
aFaceFace.SetTolFF(aTolFF);
//
aFaceFace.PrepareLines3D(bSplitCurve);
//
+ aFaceFace.ApplyTrsf();
+ //
const IntTools_SequenceOfCurves& aCvsX = aFaceFace.Lines();
const IntTools_SequenceOfPntOn2Faces& aPntsX = aFaceFace.Points();
//
getBoundPaves(myDS, aNC, aBndNV);
//
Standard_Real aTolVnew = Precision::Confusion();
+ Standard_Boolean isClosed = aP[1].IsEqual (aP[0], aTolVnew);
+ if (isClosed && (aBndNV[0] > 0 || aBndNV[1] > 0))
+ return;
+
for (Standard_Integer j = 0; j<2; ++j)
{
if (aBndNV[j] < 0)
{
// no vertex on this end
- if (j && aP[1].IsEqual(aP[0], aTolVnew)) {
+ if (j && isClosed) {
//if curve is closed, process only one bound
continue;
}
//
// use only connected faces
TopTools_ListOfShape aLFConnected;
+ // Boundary faces
+ TopTools_MapOfShape aBoundaryFaces;
aItF.Initialize (myShapes);
for (; aItF.More(); aItF.Next()) {
const TopoDS_Shape& aF = aItF.Value();
if (aMFaces.Contains(aF)) {
aLFConnected.Append(aF);
+ if (!aBoundaryFaces.Add (aF))
+ aBoundaryFaces.Remove (aF);
}
}
//
aItS.Initialize(aShell);
for (; aItS.More(); aItS.Next()) {
const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItS.Value()));
+ Standard_Boolean isBoundary = aBoundaryFaces.Contains (aF);
//
// loop on edges of aF; find a good neighbor face of aF by aE
aExp.Init(aF, TopAbs_EDGE);
// take only not-processed faces as a candidates
BOPTools_ListOfCoupleOfShape aLCSOff;
//
+ Standard_Integer aNbWaysInside = 0;
+ TopoDS_Face aSelF;
TopTools_ListIteratorOfListOfShape aItLF(aLF);
for (; aItLF.More(); aItLF.Next()) {
const TopoDS_Face& aFL = (*(TopoDS_Face*)(&aItLF.Value()));
continue;
}
//
+ if (isBoundary && !aBoundaryFaces.Contains (aFL))
+ {
+ ++aNbWaysInside;
+ aSelF = aFL;
+ }
aCSOff.SetShape1(aEL);
aCSOff.SetShape2(aFL);
aLCSOff.Append(aCSOff);
//
// among all the adjacent faces chose one with the minimal
// angle to the current one
- TopoDS_Face aSelF;
- if (aNbOff == 1) {
- aSelF = (*(TopoDS_Face*)(&aLCSOff.First().Shape2()));
- }
- else if (aNbOff > 1) {
- BOPTools_AlgoTools::GetFaceOff(aE, aF, aLCSOff, aSelF, aContext);
+ if (!isBoundary || aNbWaysInside != 1)
+ {
+ if (aNbOff == 1) {
+ aSelF = (*(TopoDS_Face*)(&aLCSOff.First().Shape2()));
+ }
+ else if (aNbOff > 1) {
+ BOPTools_AlgoTools::GetFaceOff(aE, aF, aLCSOff, aSelF, aContext);
+ }
}
//
if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) {
}
}
}
+
+//=======================================================================
+//function : TrsfToPoint
+//purpose :
+//=======================================================================
+Standard_Boolean BOPAlgo_Tools::TrsfToPoint (const Bnd_Box& theBox1,
+ const Bnd_Box& theBox2,
+ gp_Trsf& theTrsf,
+ const gp_Pnt& thePoint,
+ const Standard_Real theCriteria)
+{
+ // Unify two boxes
+ Bnd_Box aBox = theBox1;
+ aBox.Add (theBox2);
+
+ gp_XYZ aBCenter = (aBox.CornerMin().XYZ() + aBox.CornerMax().XYZ()) / 2.;
+ Standard_Real aPBDist = (thePoint.XYZ() - aBCenter).Modulus();
+ if (aPBDist < theCriteria)
+ return Standard_False;
+
+ Standard_Real aBSize = Sqrt (aBox.SquareExtent());
+ if ((aBSize / aPBDist) > (1. / theCriteria))
+ return Standard_False;
+
+ theTrsf.SetTranslation (gp_Vec (aBox.CornerMin(), thePoint));
+ return Standard_True;
+}
const TopTools_DataMapOfShapeListOfShape& theImages,
const Handle(IntTools_Context)& theContext);
+ //! Computes the transformation needed to move the objects
+ //! to the given point to increase the quality of computations.
+ //! Returns true if the objects are located far from the given point
+ //! (relatively given criteria), false otherwise.
+ //! @param theBox1 the AABB of the first object
+ //! @param theBox2 the AABB of the second object
+ //! @param theTrsf the computed transformation
+ //! @param thePoint the Point to compute transformation to
+ //! @param theCriteria the Criteria to check whether thranformation is required
+ Standard_EXPORT static Standard_Boolean TrsfToPoint (const Bnd_Box& theBox1,
+ const Bnd_Box& theBox2,
+ gp_Trsf& theTrsf,
+ const gp_Pnt& thePoint = gp_Pnt (0.0, 0.0, 0.0),
+ const Standard_Real theCriteria = 1.e+5);
};
#endif // _BOPAlgo_Tools_HeaderFile
BOPAlgo_EdgeInfo() :
myPassed(Standard_False),
myInFlag(Standard_False),
- myAngle (-1.) {
+ myIsInside (Standard_False),
+ myAngle (-1.)
+ {
};
//
void SetEdge(const TopoDS_Edge& theE) {
return myAngle;
};
//
+ Standard_Boolean IsInside() const {
+ return myIsInside;
+ };
+ //
+ void SetIsInside (const Standard_Boolean theIsInside) {
+ myIsInside = theIsInside;
+ };
+ //
protected:
TopoDS_Edge myEdge;
Standard_Boolean myPassed;
Standard_Boolean myInFlag;
+ Standard_Boolean myIsInside;
Standard_Real myAngle;
};
MyDataMapOfShapeBoolean aVertMap;
//
const TopTools_ListOfShape& myEdges=aCB.Shapes();
+
+ TopTools_MapOfShape aMS;
//
// 1.Filling mySmartMap
aIt.Initialize(myEdges);
//
bIsClosed = BRep_Tool::Degenerated(aE) ||
BRep_Tool::IsClosed(aE, myFace);
+
+ if (!aMS.Add (aE) && !bIsClosed)
+ aMS.Remove (aE);
+
//
aItS.Initialize(aE);
for(i = 0; aItS.More(); aItS.Next(), ++i) {
for (i=1; i<=aNb; i++) {
aCntIn=0;
aCntOut=0;
- const BOPAlgo_ListOfEdgeInfo& aLEInfo= mySmartMap(i);
+ const BOPAlgo_ListOfEdgeInfo& aLEInfo = mySmartMap(i);
BOPAlgo_ListIteratorOfListOfEdgeInfo anIt(aLEInfo);
for (; anIt.More(); anIt.Next()) {
const BOPAlgo_EdgeInfo& aEI=anIt.Value();
for (; aItLEI.More(); aItLEI.Next()) {
BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
const TopoDS_Edge& aE=aEI.Edge();
+ aEI.SetIsInside (!aMS.Contains (aE));
//
aVV = aV;
bIsIN = aEI.IsIn();
Standard_Integer i, j, aNb, aNbj;
Standard_Real anAngleIn, anAngleOut, anAngle, aMinAngle;
Standard_Real aTol2D, aTol2D2, aD2, aTwoPI;
- Standard_Boolean anIsSameV2d, anIsSameV, anIsFound, anIsOut, anIsNotPassed;
+ Standard_Boolean anIsSameV2d, anIsSameV, anIsOut, anIsNotPassed;
Standard_Boolean bIsClosed;
TopoDS_Vertex aVa, aVb;
TopoDS_Edge aEOuta;
//
anAngleIn = AngleIn(aEOuta, aLEInfo);
aMinAngle = 100.;
- anIsFound = Standard_False;
Standard_Integer iCnt = NbWaysOut(aLEInfo);
+
+ Standard_Boolean isBoundary = !anEdgeInfo->IsInside();
+ Standard_Integer aNbWaysInside = 0;
+ BOPAlgo_EdgeInfo *pOnlyWayIn = NULL;
+
Standard_Integer aCurIndexE = 0;
anIt.Initialize(aLEInfo);
for (; anIt.More(); anIt.Next()) {
if (iCnt==1) {
// the one and only way to go out .
pEdgeInfo=&anEI;
- anIsFound=Standard_True;
break;
}
//
anAngleOut=anEI.Angle();
anAngle=ClockWiseAngle(anAngleIn, anAngleOut);
}
+
+ if (isBoundary && anEI.IsInside())
+ {
+ ++aNbWaysInside;
+ pOnlyWayIn = &anEI;
+ }
+
if (anAngle < aMinAngle - eps) {
aMinAngle=anAngle;
pEdgeInfo=&anEI;
- anIsFound=Standard_True;
}
}
} // for (; anIt.More(); anIt.Next())
+ if (aNbWaysInside == 1)
+ {
+ pEdgeInfo = pOnlyWayIn;
+ }
//
- if (!anIsFound) {
+ if (!pEdgeInfo) {
// no way to go . (Error)
return;
}
struct EdgeData {
const TopoDS_Edge* Edge; // Edge
Standard_Real VParameter; // Parameter of the vertex on the edge
+ Standard_Boolean IsClosed; // Closed flag of the edge
Geom2dAdaptor_Curve GAdaptor; // 2D adaptor for PCurve of the edge on the face
Standard_Real First; // First parameter in the range
Standard_Real Last; // Last parameter in the rage
continue;
}
//
- if (Abs(aTint1 - aT1) > aHalfR1 ||
- Abs(aTint2 - aT2) > aHalfR2) {
- // intersection on the other end of the closed edge
+ if ((!theEData1.IsClosed && Abs (aTint1 - aT1) > aHalfR1) ||
+ (!theEData2.IsClosed && Abs (aTint2 - aT2) > aHalfR2)) {
+ // intersection is on the other end of the edge
continue;
}
//
const TopTools_IndexedMapOfShape& aMapToAvoid)
{
Standard_Integer i, aNbV;
- Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2, aT;
+ Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2;
gp_Pnt aP, aPV;
gp_Pnt2d aP2D;
TopoDS_Face aF;
aF=aFx;
aF.Orientation(TopAbs_FORWARD);
const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aFx);
- //
- TopExp::MapShapesAndAncestors(aF,
- TopAbs_VERTEX,
- TopAbs_EDGE,
- aMVE);
+
+ TopExp::MapShapesAndUniqueAncestors (aF, TopAbs_VERTEX, TopAbs_EDGE, aMVE, Standard_True);
+
NCollection_DataMap<TopoDS_Shape, Standard_Real> aMapEdgeLen;
aNbV=aMVE.Extent();
for (i=1; i<=aNbV; ++i) {
const TopoDS_Edge& aE=*(TopoDS_Edge*)(&aIt.Value());
const Handle(Geom2d_Curve)& aC2D=
BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
- aT=BRep_Tool::Parameter(aV, aE);
+ Standard_Real aT = BRep_Tool::Parameter (aV, aE);
+ Standard_Boolean isClosed = Standard_False;
+ {
+ TopoDS_Vertex aV1, aV2;
+ TopExp::Vertices (aE, aV1, aV2);
+ isClosed = aV1.IsSame (aV2);
+ }
//
aC2D->D0(aT, aP2D);
aS->D0(aP2D.X(), aP2D.Y(), aP);
if (aD2>aD2max) {
aD2max=aD2;
}
- EdgeData anEData = {&aE, aT, Geom2dAdaptor_Curve(aC2D), aT1, aT2};
+ EdgeData anEData = {&aE, aT, isClosed, Geom2dAdaptor_Curve(aC2D), aT1, aT2};
aLEPars.Append(anEData);
}
//
aRj2.Range(aTj21, aTj22);
//
bCond = (fabs(aTi12 - aTj11) < dTR1) ||
+ (aTj11 > aTi11 && aTj11 < aTi12) ||
+ (aTi11 > aTj11 && aTi11 < aTj12) ||
(bSplit2 && (fabs(aTj12 - aTi11) < dTR1));
if (bCond && bSplit2) {
bCond = (fabs((Max(aTi22, aTj22) - Min(aTi21, aTj21)) -
- ((aTi22 - aTi21) + (aTj22 - aTj21))) < dTR2);
+ ((aTi22 - aTi21) + (aTj22 - aTj21))) < dTR2) ||
+ (aTj21 > aTi21 && aTj21 < aTi22) ||
+ (aTi21 > aTj21 && aTi21 < aTj22);
}
//
if (bCond) {
//! Checks if the edge is in the face really.
Standard_EXPORT Standard_Boolean IsCoincident();
-private:
+protected:
TopoDS_Edge myEdge;
TopoDS_Face myFace;
//! and surfaces is computed.
Standard_EXPORT void ComputeTolReached3d();
-private:
+protected:
Standard_Boolean myIsDone;
IntPatch_Intersection myIntersector;
--- /dev/null
+puts "============================================================================"
+puts "0026876: Modeling Algorithms - Boolean algorithm fails or produce faulty shape"
+puts "============================================================================"
+puts ""
+
+restore [locate_data_file bug26883_object.brep] o
+restore [locate_data_file bug26883_fuse_tool1.brep] ft1
+restore [locate_data_file bug26883_fuse_tool2.brep] ft2
+restore [locate_data_file bug26876_cut_tool1.brep] ct1
+restore [locate_data_file bug26876_cut_tool2.brep] ct2
+
+bclearobjects
+bcleartools
+baddobjects o
+baddtools ft1 ft2
+bfillds
+bbop result_fuse 1
+
+checkshape result_fuse
+if {![regexp "OK" [bopcheck result_fuse]]} {
+ puts "Error: the result of FUSE operation is a self-interfering shape"
+}
+checkprops result_fuse -s 2117 -v 607.602
+checknbshapes result_fuse -wire 52 -face 44 -shell 3 -solid 1 -t
+
+bclearobjects
+bcleartools
+baddobjects result_fuse
+baddtools ct1 ct2
+bfillds
+bbop result 2
+
+checkshape result
+if {![regexp "OK" [bopcheck result]]} {
+ puts "Error: the result of CUT operation is a self-interfering shape"
+}
+checkprops result -s 2112.67 -v 607.132
+checknbshapes result -wire 50 -face 42 -shell 2 -solid 1 -t
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
-puts "TODO OCC26882 ALL: Error : is WRONG because number of VERTEX entities in shape"
-puts "TODO OCC26882 ALL: Error : is WRONG because number of EDGE entities in shape"
-
puts "========"
puts "OCC26882"
puts "========"
baddtools b2
bfillds
-bbop result 1
+bbop r_0 0
+bbop r_1 1
+bbop r_2 2
+bbop r_3 3
+bbop r_4 4
+bbuild r_5
-checkshape result
-checkprops result -s 2116.44 -v 607.276
-checknbshapes result -wire 39 -face 32 -shell 3 -solid 1
+foreach i { 0 1 2 3 4 5} {
+ checkshape r_$i
+ if {![regexp "OK" [bopcheck r_$i]]} {
+ puts "Error: r_$i is self-intersecting shape"
+ }
+}
-checkview -display result -2d -path ${imagedir}/${test_image}.png
+checkprops r_0 -s 9.84822 -v 0.639566
+checknbshapes r_0 -wire 7 -face 5 -shell 1 -solid 1 -t
+
+checkprops r_1 -s 2116.61 -v 607.386
+checknbshapes r_1 -wire 40 -face 34 -shell 3 -solid 1 -t
+
+checkprops r_2 -s 2110.46 -v 606.532
+checknbshapes r_2 -wire 36 -face 30 -shell 3 -solid 2 -t
+
+checkprops r_3 -s 15.9958 -v 0.215358
+checknbshapes r_3 -wire 11 -face 9 -shell 2 -solid 2 -t
+
+checkprops r_4 -l 24.818
+checksection r_4 -r 0
+
+checkprops r_5 -s 2146.15 -v 608.026
+checknbshapes r_5 -wire 47 -face 39 -shell 6 -solid 5 -t
+
+
+checkview -display r_1 -2d -path ${imagedir}/${test_image}.png
--- /dev/null
+puts "========"
+puts "0029843: Modeling Algorithms - Boolean FUSE produces incorrect result"
+puts "========"
+puts ""
+
+restore [locate_data_file bug29843.brep] s
+
+explode s
+bclearobjects
+bcleartools
+baddobjects s_1
+baddtools s_2
+bfillds
+
+bbop r_0 0
+bbop r_1 1
+bbop r_2 2
+bbop r_3 3
+bbop r_4 4
+bbuild r_5
+
+foreach i { 0 1 2 3 4 5} {
+ checkshape r_$i
+ if {![regexp "OK" [bopcheck r_$i]]} {
+ puts "Error: r_$i is self-intersecting shape"
+ }
+}
+
+checkprops r_0 -s 9.84429 -v 0.639311
+checknbshapes r_0 -wire 7 -face 5 -shell 1 -solid 1 -t
+
+checkprops r_1 -s 2121.39 -v 612.41
+checknbshapes r_1 -wire 38 -face 32 -shell 2 -solid 1 -t
+
+checkprops r_2 -s 2113.85 -v 611.569
+checknbshapes r_2 -wire 32 -face 26 -shell 2 -solid 1 -t
+
+checkprops r_3 -s 15.9893 -v 0.215264
+checknbshapes r_3 -wire 11 -face 9 -shell 2 -solid 2 -t
+
+checkprops r_4 -l 24.9725
+checksection r_4 -r 2
+
+checkprops r_5 -s 2139.68 -v 612.402
+checknbshapes r_5 -wire 44 -face 36 -shell 5 -solid 4 -t
+
+checkview -display r_0 -2d -path ${imagedir}/${test_image}.png
+
--- /dev/null
+puts "========"
+puts "0029843: Modeling Algorithms - Boolean FUSE produces incorrect result"
+puts "========"
+puts ""
+
+puts "Boolean operation fails on the objects located far from origin (1.e+8)"
+
+restore [locate_data_file bug29843_loc.brep] s
+
+explode s
+bclearobjects
+bcleartools
+baddobjects s_1
+baddtools s_2
+bfillds
+
+bbop r_0 0
+bbop r_1 1
+bbop r_2 2
+bbop r_3 3
+bbop r_4 4
+bbuild r_5
+
+foreach i { 0 1 2 3 4 5} {
+ checkshape r_$i
+ if {![regexp "OK" [bopcheck r_$i]]} {
+ puts "Error: r_$i is self-intersecting shape"
+ }
+}
+
+checkprops r_0 -s 62185.2 -v 1.1761e+06
+checknbshapes r_0 -vertex 6 -edge 9 -wire 5 -face 5 -shell 1 -solid 1 -t
+
+checkprops r_1 -s 1.85327e+06 -v 5.92874e+07
+checknbshapes r_1 -vertex 15 -edge 24 -wire 11 -face 11 -shell 1 -solid 1 -t
+
+checkprops r_2 -s 1.85376e+06 -v 5.78639e+07
+checknbshapes r_2 -vertex 14 -edge 21 -wire 9 -face 9 -shell 1 -solid 1 -t
+
+checkprops r_3 -s 37189.7 -v 247431
+checknbshapes r_3 -vertex 6 -edge 9 -wire 5 -face 5 -shell 1 -solid 1 -t
+
+checkprops r_4 -l 952.189
+checksection r_4 -r 2
+checknbshapes r_4 -vertex 6 -edge 7 -t
+
+checkprops r_5 -s 2.01533e+06 -v 6.04635e+07
+checknbshapes r_5 -vertex 15 -edge 26 -wire 15 -face 15 -shell 3 -solid 3 -t
+
+checkview -display r_2 -2d -path ${imagedir}/${test_image}.png
+