diff --git a/src/BRepOffset/BRepOffset_MakeOffset_1.cxx b/src/BRepOffset/BRepOffset_MakeOffset_1.cxx index a4e1c43fb7..cda7b25f21 100644 --- a/src/BRepOffset/BRepOffset_MakeOffset_1.cxx +++ b/src/BRepOffset/BRepOffset_MakeOffset_1.cxx @@ -179,7 +179,8 @@ static const TopTools_MapOfShape& theEdgesInvalidByVertex, const TopTools_MapOfShape& theMFHoles, TopTools_IndexedMapOfShape& theMFInvInHole, - TopTools_ListOfShape& theInvFaces); + TopTools_ListOfShape& theInvFaces, + TopTools_ListOfShape& theInvertedFaces); static void FindFacesInsideHoleWires(const TopoDS_Face& theFOrigin, @@ -238,6 +239,8 @@ static TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, const TopTools_DataMapOfShapeShape& theArtInvFaces, const TopTools_IndexedMapOfShape& theInvEdges, + const TopTools_MapOfShape& theInvertedEdges, + const TopTools_ListOfShape& theInvertedFaces, const TopTools_IndexedMapOfShape& theMFToCheckInt, const TopTools_IndexedMapOfShape& theMFInvInHole, const TopoDS_Shape& theFHoles, @@ -258,6 +261,7 @@ static const TopTools_DataMapOfShapeShape& theDMFImF, const TopTools_IndexedMapOfShape& theMFInv, const TopTools_IndexedMapOfShape& theInvEdges, + const TopTools_MapOfShape& theInvertedEdges, TopTools_MapOfShape& theMFToRem); static @@ -596,6 +600,21 @@ static void AppendToList(TopTools_ListOfShape& theL, const TopoDS_Shape& theS); +template +static Standard_Boolean TakeModified(const TopoDS_Shape& theS, + const TopTools_DataMapOfShapeListOfShape& theImages, + ContainerType& theMapOut, + FenceMapType* theMFence); + +template +static Standard_Boolean TakeModified(const TopoDS_Shape& theS, + const TopTools_DataMapOfShapeListOfShape& theImages, + ContainerType& theMapOut) +{ + TopTools_MapOfShape* aDummy = NULL; + return TakeModified (theS, theImages, theMapOut, aDummy); +} + //======================================================================= //function : BuildSplitsOfTrimmedFaces //purpose : Building splits of already trimmed faces @@ -988,6 +1007,12 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF, } #endif +#ifdef OFFSET_DEBUG + // Show all obtained splits of faces + TopoDS_Compound aCFIm1; + BRep_Builder().MakeCompound(aCFIm1); +#endif + // Build Edge-Face connectivity map to find faces which removal // may potentially lead to creation of the holes in the faces // preventing from obtaining closed volume in the result @@ -997,7 +1022,12 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF, { TopTools_ListIteratorOfListOfShape itLFIm(theFImages(i)); for (; itLFIm.More(); itLFIm.Next()) + { TopExp::MapShapesAndAncestors(itLFIm.Value(), TopAbs_EDGE, TopAbs_FACE, anEFMap); +#ifdef OFFSET_DEBUG + BRep_Builder().Add(aCFIm1, itLFIm.Value()); +#endif + } } TopTools_ListOfShape anEmptyList; @@ -1006,6 +1036,8 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF, // all hole faces TopoDS_Compound aFHoles; aBB.MakeCompound(aFHoles); + // Find the faces containing only the inverted edges and the invalid ones + TopTools_ListOfShape anInvertedFaces; // find invalid faces // considering faces containing only invalid edges as invalid aItLF.Initialize(aLFDone); @@ -1044,7 +1076,7 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF, // find invalid faces FindInvalidFaces(aLFImages, theInvEdges, theValidEdges, aDMFLVE, aDMFLIE, *pLNE, *pLIVE, theInvertedEdges, aMEdgeInvalidByVertex, - aMFHoles, aMFInvInHole, aLFInv); + aMFHoles, aMFInvInHole, aLFInv, anInvertedFaces); } // if (aLFInv.Extent()) { @@ -1095,8 +1127,8 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF, // // remove inside faces TopTools_IndexedMapOfShape aMEInside; - RemoveInsideFaces(theFImages, theInvFaces, theArtInvFaces, theInvEdges, - aMFToCheckInt, aMFInvInHole, aFHoles, theSSInterfs, + RemoveInsideFaces(theFImages, theInvFaces, theArtInvFaces, theInvEdges, theInvertedEdges, + anInvertedFaces, aMFToCheckInt, aMFInvInHole, aFHoles, theSSInterfs, aMERemoved, aMEInside, theSolids); // // make compound of valid splits @@ -1819,7 +1851,8 @@ void FindInvalidFaces(TopTools_ListOfShape& theLFImages, const TopTools_MapOfShape& theEdgesInvalidByVertex, const TopTools_MapOfShape& theMFHoles, TopTools_IndexedMapOfShape& theMFInvInHole, - TopTools_ListOfShape& theInvFaces) + TopTools_ListOfShape& theInvFaces, + TopTools_ListOfShape& theInvertedFaces) { // The face should be considered as invalid in the following cases: // 1. It has been reverted, i.e. at least two not connected edges @@ -1832,7 +1865,8 @@ void FindInvalidFaces(TopTools_ListOfShape& theLFImages, // The face will be kept in the following cases: // 1. Some of the edges are valid for this face. Standard_Boolean bHasValid, bAllValid, bAllInvalid, bHasReallyInvalid, bAllInvNeutral; - Standard_Boolean bValid, bValidLoc, bInvalid, bInvalidLoc, bNeutral; + Standard_Boolean bValid, bValidLoc, bInvalid, bInvalidLoc, bNeutral, bInverted; + Standard_Boolean bIsInvalidByInverted; Standard_Integer i, aNbChecked; // // neutral edges @@ -1849,7 +1883,7 @@ void FindInvalidFaces(TopTools_ListOfShape& theLFImages, aMEValInverted.Add(aItLE.Value()); } // - Standard_Boolean bCheckInverted = (theLFImages.Extent() == 1); + Standard_Boolean bTreatInvertedAsInvalid = (theLFImages.Extent() == 1); // // neutral edges to remove TopTools_IndexedMapOfShape aMENRem; @@ -1883,6 +1917,7 @@ void FindInvalidFaces(TopTools_ListOfShape& theLFImages, bAllInvalid = Standard_True; bHasReallyInvalid = Standard_False; bAllInvNeutral = Standard_True; + bIsInvalidByInverted = Standard_True; aNbChecked = 0; // const TopoDS_Wire& aWIm = BRepTools::OuterWire(aFIm); @@ -1909,17 +1944,19 @@ void FindInvalidFaces(TopTools_ListOfShape& theLFImages, bNeutral = aMEN.Contains(aEIm); bValidLoc = aMVE.Contains(aEIm); // - if (!bInvalid && bCheckInverted) { - bInvalid = theMEInverted.Contains(aEIm); + bInverted = theMEInverted.Contains(aEIm); + if (!bInvalid && bTreatInvertedAsInvalid) { + bInvalid = bInverted; } // if (bValidLoc && (bNeutral || aMEValInverted.Contains(aEIm))) { bHasValid = Standard_True; } // - bAllValid = bAllValid && bValidLoc; - bAllInvalid = bAllInvalid && bInvalid; - bAllInvNeutral = bAllInvNeutral && bAllInvalid && bNeutral; + bAllValid &= bValidLoc; + bAllInvalid &= bInvalid; + bAllInvNeutral &= (bAllInvalid && bNeutral); + bIsInvalidByInverted &= (bInvalidLoc || bInverted); } // if (!aNbChecked) { @@ -1954,6 +1991,12 @@ void FindInvalidFaces(TopTools_ListOfShape& theLFImages, continue; } // + if (bIsInvalidByInverted && !(bHasValid || bAllValid)) + { + // The face contains only the inverted and locally invalid edges + theInvertedFaces.Append(aFIm); + } + if (!bAllInvNeutral) { aLFPT.Append(aFIm); } @@ -2003,7 +2046,7 @@ void FindInvalidFaces(TopTools_ListOfShape& theLFImages, bNeutral = aMEN.Contains(aEIm); bValidLoc = aMVE.Contains(aEIm); // - if (!bInvalid && bCheckInverted) { + if (!bInvalid && bTreatInvertedAsInvalid) { bInvalid = theMEInverted.Contains(aEIm); } // @@ -2873,6 +2916,8 @@ void RemoveInsideFaces(TopTools_IndexedDataMapOfShapeListOfShape& theFImages, TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces, const TopTools_DataMapOfShapeShape& theArtInvFaces, const TopTools_IndexedMapOfShape& theInvEdges, + const TopTools_MapOfShape& theInvertedEdges, + const TopTools_ListOfShape& theInvertedFaces, const TopTools_IndexedMapOfShape& theMFToCheckInt, const TopTools_IndexedMapOfShape& theMFInvInHole, const TopoDS_Shape& theFHoles, @@ -2932,6 +2977,9 @@ void RemoveInsideFaces(TopTools_IndexedDataMapOfShapeListOfShape& theFImages, aMV.SetArguments(aLS); aMV.SetIntersect(Standard_True); aMV.Perform(); + if (aMV.HasErrors()) + return; + // // get shapes connection for using in the rebuilding process // for the cases in which some of the intersection left undetected @@ -3016,19 +3064,21 @@ void RemoveInsideFaces(TopTools_IndexedDataMapOfShapeListOfShape& theFImages, TopExp::MapShapes(aFIm, TopAbs_EDGE, aMEBoundary); } } - // + + // Tool for getting the splits of faces + const TopTools_DataMapOfShapeListOfShape& aMVIms = aMV.Images(); + // update invalid faces with images aNb = aMFInv.Extent(); for (i = 1; i <= aNb; ++i) { const TopoDS_Shape& aFInv = aMFInv(i); - const TopTools_ListOfShape& aLFInvIm = aMV.Modified(aFInv); - TopTools_ListIteratorOfListOfShape aItLFInvIm(aLFInvIm); - for (; aItLFInvIm.More(); aItLFInvIm.Next()) { - const TopoDS_Shape& aFInvIm = aItLFInvIm.Value(); - aMFInv.Add(aFInvIm); - } + TakeModified(aFInv, aMVIms, aMFInv); } - // + + // Take into account the faces invalid by inverted edges + for (TopTools_ListOfShape::Iterator itLF(theInvertedFaces); itLF.More(); itLF.Next()) + TakeModified(itLF.Value(), aMVIms, aMFInv); + // check if the invalid faces inside the holes are really invalid: // check its normal direction - if it has changed relatively the // original face the offset face is invalid and should be kept for rebuilding @@ -3082,10 +3132,14 @@ void RemoveInsideFaces(TopTools_IndexedDataMapOfShapeListOfShape& theFImages, // if (aFS.Orientation() == TopAbs_INTERNAL) { aMFToRem.Add(aFS); + continue; } - // - bAllRemoved = bAllRemoved && aMFToRem.Contains(aFS); - bAllInv = bAllInv && (aMFToRem.Contains(aFS) || aMFInv.Contains(aFS)); + + if (aMFToRem.Contains(aFS)) + continue; + + bAllRemoved = false; + bAllInv &= aMFInv.Contains(aFS); } // if (bAllInv && !bAllRemoved) { @@ -3116,7 +3170,7 @@ void RemoveInsideFaces(TopTools_IndexedDataMapOfShapeListOfShape& theFImages, } // Remove the invalid hanging parts external to the solids - RemoveHangingParts(aMV, aDMFImF, aMFInv, theInvEdges, aMFToRem); + RemoveHangingParts(aMV, aDMFImF, aMFInv, theInvEdges, theInvertedEdges, aMFToRem); // Remove newly found internal and hanging faces RemoveValidSplits(aMFToRem, theFImages, aMV, theMERemoved); @@ -3302,6 +3356,7 @@ void RemoveHangingParts(const BOPAlgo_MakerVolume& theMV, const TopTools_DataMapOfShapeShape& theDMFImF, const TopTools_IndexedMapOfShape& theMFInv, const TopTools_IndexedMapOfShape& theInvEdges, + const TopTools_MapOfShape& theInvertedEdges, TopTools_MapOfShape& theMFToRem) { // Map the faces of the result solids to filter them from avoided faces @@ -3323,22 +3378,7 @@ void RemoveHangingParts(const BOPAlgo_MakerVolume& theMV, for (; anExpF.More(); anExpF.Next()) { const TopoDS_Shape& aF = anExpF.Current(); - const TopTools_ListOfShape* pLFIm = aMVIms.Seek(aF); - if (pLFIm) - { - TopTools_ListIteratorOfListOfShape aItLFIm(*pLFIm); - for (; aItLFIm.More(); aItLFIm.Next()) - { - const TopoDS_Shape& aFIm = aItLFIm.Value(); - if (!aMFS.Contains(aFIm)) - aBB.Add(aCFHangs, aFIm); - } - } - else - { - if (!aMFS.Contains(aF)) - aBB.Add(aCFHangs, aF); - } + TakeModified(aF, aMVIms, aCFHangs, &aMFS); } } @@ -3364,27 +3404,41 @@ void RemoveHangingParts(const BOPAlgo_MakerVolume& theMV, // Update invalid edges with intersection results TopTools_MapOfShape aMEInv; Standard_Integer i, aNbE = theInvEdges.Extent(); - for (i = 1; i <= aNbE; ++i) { - const TopoDS_Shape& aEInv = theInvEdges(i); - const TopTools_ListOfShape *pLEIm = aMVIms.Seek(aEInv); - if (pLEIm) - { - TopTools_ListIteratorOfListOfShape aItLEIm(*pLEIm); - for (; aItLEIm.More(); aItLEIm.Next()) - aMEInv.Add(aItLEIm.Value()); - } - else - aMEInv.Add(aEInv); - } + for (i = 1; i <= aNbE; ++i) + TakeModified(theInvEdges(i), aMVIms, aMEInv); + + // Update inverted edges with intersection results + TopTools_MapOfShape aMEInverted; + for (TopTools_MapIteratorOfMapOfShape itM(theInvertedEdges); itM.More(); itM.Next()) + TakeModified(itM.Value(), aMVIms, aMEInverted); // Tool for getting the origins of the splits const TopTools_DataMapOfShapeListOfShape& aMVOrs = theMV.Origins(); + // Find hanging blocks to remove + TopTools_ListOfShape aBlocksToRemove; + TopTools_ListIteratorOfListOfShape aItLCBH(aLCBHangs); for (; aItLCBH.More(); aItLCBH.Next()) { const TopoDS_Shape& aCBH = aItLCBH.Value(); + // Remove the block containing the inverted edges + Standard_Boolean bHasInverted = Standard_False; + TopExp_Explorer anExpE(aCBH, TopAbs_EDGE); + for (; anExpE.More() && !bHasInverted; anExpE.Next()) + { + const TopoDS_Shape& aE = anExpE.Current(); + bHasInverted = !aDMEF .Contains(aE) && + aMEInverted.Contains(aE); + } + + if (bHasInverted) + { + aBlocksToRemove.Append(aCBH); + continue; + } + // Check the block to contain invalid split Standard_Boolean bHasInvalidFace = Standard_False; // Check connectivity to invalid parts @@ -3406,7 +3460,7 @@ void RemoveHangingParts(const BOPAlgo_MakerVolume& theMV, if (!bIsConnected) { // check edges - TopExp_Explorer anExpE(aF, TopAbs_EDGE); + anExpE.Init(aF, TopAbs_EDGE); for (; anExpE.More() && !bIsConnected; anExpE.Next()) { const TopoDS_Shape& aE = anExpE.Current(); @@ -3419,17 +3473,20 @@ void RemoveHangingParts(const BOPAlgo_MakerVolume& theMV, } } // check vertices - TopExp_Explorer anExpV(aF, TopAbs_VERTEX); - for (; anExpV.More() && !bIsConnected; anExpV.Next()) + if (!bIsConnected) { - const TopoDS_Shape& aV = anExpV.Current(); - const TopTools_ListOfShape *pLE = aDMVE.Seek(aV); - if (pLE) + TopExp_Explorer anExpV(aF, TopAbs_VERTEX); + for (; anExpV.More() && !bIsConnected; anExpV.Next()) { - TopTools_ListIteratorOfListOfShape aItLE(*pLE); - for (; aItLE.More() && !bIsConnected; aItLE.Next()) - bIsConnected = !aBlockME.Contains(aItLE.Value()) && - aMEInv .Contains(aItLE.Value()); + const TopoDS_Shape& aV = anExpV.Current(); + const TopTools_ListOfShape *pLE = aDMVE.Seek(aV); + if (pLE) + { + TopTools_ListIteratorOfListOfShape aItLE(*pLE); + for (; aItLE.More() && !bIsConnected; aItLE.Next()) + bIsConnected = !aBlockME.Contains(aItLE.Value()) && + aMEInv .Contains(aItLE.Value()); + } } } } @@ -3458,12 +3515,17 @@ void RemoveHangingParts(const BOPAlgo_MakerVolume& theMV, (!bIsConnected || aMOffsetF.Extent() == 1); if (bRemove) - { - // remove the block - anExpF.Init(aCBH, TopAbs_FACE); - for (; anExpF.More(); anExpF.Next()) - theMFToRem.Add(anExpF.Current()); - } + aBlocksToRemove.Append(aCBH); + } + + // remove the invalidated blocks + aItLCBH.Initialize(aBlocksToRemove); + for (; aItLCBH.More(); aItLCBH.Next()) + { + const TopoDS_Shape& aCBH = aItLCBH.Value(); + TopExp_Explorer anExpF(aCBH, TopAbs_FACE); + for (; anExpF.More(); anExpF.Next()) + theMFToRem.Add(anExpF.Current()); } } @@ -6924,13 +6986,16 @@ void UpdateImages(const TopTools_ListOfShape& theLA, TopTools_MapOfShape& theModified) { TopTools_ListIteratorOfListOfShape aIt(theLA); - for (; aIt.More(); aIt.Next()) { + for (; aIt.More(); aIt.Next()) + { const TopoDS_Shape& aS = aIt.Value(); // TopTools_ListOfShape* pLSIm = theImages.ChangeSeek(aS); - if (!pLSIm) { + if (!pLSIm) + { const TopTools_ListOfShape& aLSIm = theGF.Modified(aS); - if (aLSIm.Extent()) { + if (aLSIm.Extent()) + { theImages.Bind(aS, aLSIm); theModified.Add(aS); } @@ -6944,27 +7009,14 @@ void UpdateImages(const TopTools_ListOfShape& theLA, // // check modifications of the images TopTools_ListIteratorOfListOfShape aIt1(*pLSIm); - for (; aIt1.More(); aIt1.Next()) { + for (; aIt1.More(); aIt1.Next()) + { const TopoDS_Shape& aSIm = aIt1.Value(); - const TopTools_ListOfShape& aLSIm1 = theGF.Modified(aSIm); - if (aLSIm1.IsEmpty()) { - if (aMFence.Add(aSIm)) { - aLSImNew.Append(aSIm); - } - } - else { - TopTools_ListIteratorOfListOfShape aIt2(aLSIm1); - for (; aIt2.More(); aIt2.Next()) { - const TopoDS_Shape& aSImIm = aIt2.Value(); - if (aMFence.Add(aSImIm)) { - aLSImNew.Append(aSImIm); - } - } - bModified = Standard_True; - } + bModified |= TakeModified(aSIm, theGF.Images(), aLSImNew, &aMFence); } // - if (bModified) { + if (bModified) + { *pLSIm = aLSImNew; theModified.Add(aS); } @@ -7099,3 +7151,61 @@ void AppendToList(TopTools_ListOfShape& theList, } theList.Append(theShape); } + +//======================================================================= +//function : AddToContainer +//purpose : Set of methods to add a shape into container +//======================================================================= +static void AddToContainer(const TopoDS_Shape& theS, + TopTools_ListOfShape& theList) +{ + theList.Append(theS); +} +static Standard_Boolean AddToContainer(const TopoDS_Shape& theS, + TopTools_MapOfShape& theMap) +{ + return theMap.Add(theS); +} +static Standard_Boolean AddToContainer(const TopoDS_Shape& theS, + TopTools_IndexedMapOfShape& theMap) +{ + const Standard_Integer aNb = theMap.Extent(); + const Standard_Integer anInd = theMap.Add(theS); + return anInd > aNb; +} +static void AddToContainer(const TopoDS_Shape& theS, + TopoDS_Shape& theSOut) +{ + BRep_Builder().Add(theSOut, theS); +} + +//======================================================================= +//function : TakeModified +//purpose : Check if the shape has images in the given images map. +// Puts in the output map either the images or the shape itself. +//======================================================================= +template +Standard_Boolean TakeModified(const TopoDS_Shape& theS, + const TopTools_DataMapOfShapeListOfShape& theImages, + ContainerType& theContainer, + FenceMapType* theMFence) +{ + const TopTools_ListOfShape *pLSIm = theImages.Seek(theS); + if (pLSIm) + { + TopTools_ListIteratorOfListOfShape itLSIm(*pLSIm); + for (; itLSIm.More(); itLSIm.Next()) + { + const TopoDS_Shape& aSIm = itLSIm.Value(); + if (!theMFence || AddToContainer(aSIm, *theMFence)) + AddToContainer(aSIm, theContainer); + } + return Standard_True; + } + else + { + if (!theMFence || AddToContainer(theS, *theMFence)) + AddToContainer(theS, theContainer); + return Standard_False; + } +} diff --git a/tests/offset/shape_type_i_c/XS4 b/tests/offset/shape_type_i_c/XS4 new file mode 100644 index 0000000000..9375d76332 --- /dev/null +++ b/tests/offset/shape_type_i_c/XS4 @@ -0,0 +1,54 @@ +restore [locate_data_file bug30470_input.brep] s + +# perform offset operation with increasing offset value + +# set props and nb reference values to compare with + +# area volume nb_wire nb_face +set ref_values { { 2.1809e+06 4.43828e+07 50 49 } \ + { 2.13057e+06 4.65386e+07 50 49 } \ + { 2.0795e+06 4.86437e+07 50 49 } \ + { 2.02768e+06 5.06974e+07 50 49 } \ + { 1.97511e+06 5.26988e+07 50 49 } \ + { 1.9218e+06 5.46473e+07 50 49 } \ + { 1.86774e+06 5.65422e+07 50 49 } \ + { 1.81293e+06 5.83826e+07 50 49 } \ + { 1.81346e+06 6.01887e+07 23 23 } \ + { 1.82605e+06 6.20098e+07 25 25 } \ + { 1.83436e+06 6.384e+07 25 25 } \ + { 1.84239e+06 6.56784e+07 25 25 } \ + { 1.85014e+06 6.75247e+07 25 25 } \ + { 1.85761e+06 6.93786e+07 27 27 } \ + { 1.86443e+06 7.12397e+07 27 27 } \ + { 1.87034e+06 7.31071e+07 27 27 } \ + { 1.87534e+06 7.498e+07 27 27 } \ + { 1.87945e+06 7.68575e+07 27 27 } \ + { 1.88264e+06 7.87386e+07 27 27 } \ + { 1.88494e+06 8.06225e+07 27 27 } \ + { 1.88632e+06 8.25082e+07 27 27 } \ + { 1.88681e+06 8.43948e+07 27 27 } \ + { 1.88638e+06 8.62815e+07 27 27 } \ + { 1.88506e+06 8.81673e+07 27 27 } \ + { 1.88659e+06 9.0052e+07 25 25 } \ + { 1.89452e+06 9.19426e+07 25 25 } \ + { 1.90186e+06 9.38408e+07 25 25 } \ + { 1.90862e+06 9.57461e+07 25 25 } \ + { 1.91479e+06 9.76578e+07 25 25 } \ + { 1.9206e+06 9.95755e+07 27 26 } \ + { 1.92646e+06 1.01499e+08 27 26 } \ + { 1.93235e+06 1.03428e+08 27 26 } \ + { 1.9383e+06 1.05364e+08 27 26 } \ + { 1.94429e+06 1.07305e+08 27 26 } \ + { 1.95032e+06 1.09252e+08 27 26 } \ + { 1.95641e+06 1.11206e+08 27 26 } \ + { 1.96254e+06 1.13165e+08 27 26 } \ + { 1.96871e+06 1.15131e+08 27 26 } \ + { 1.97494e+06 1.17103e+08 27 26 } \ + { 1.9812e+06 1.19081e+08 27 26 } } + +perform_offset_increasing s 1 40 1 $ref_values + +copy r17 result +copy r17_unif result_unif + +checkview -display result_unif -2d -path ${imagedir}/${test_image}.png diff --git a/tests/offset/shape_type_i_c/XS5 b/tests/offset/shape_type_i_c/XS5 new file mode 100644 index 0000000000..03d1ac0028 --- /dev/null +++ b/tests/offset/shape_type_i_c/XS5 @@ -0,0 +1,54 @@ +restore [locate_data_file bug30470_input_trim1.brep] s + +# perform offset operation with increasing offset value + +# set props and nb reference values to compare with + +# area volume nb_wire nb_face +set ref_values { { 1.31124e+06 2.58872e+07 43 42 } \ + { 1.27726e+06 2.71815e+07 43 42 } \ + { 1.24279e+06 2.84416e+07 43 42 } \ + { 1.20783e+06 2.96669e+07 43 42 } \ + { 1.17237e+06 3.08571e+07 43 42 } \ + { 1.13642e+06 3.20115e+07 43 42 } \ + { 1.09997e+06 3.31297e+07 43 42 } \ + { 1.06303e+06 3.42113e+07 43 42 } \ + { 1.06451e+06 3.52701e+07 19 19 } \ + { 1.07229e+06 3.63398e+07 21 21 } \ + { 1.07578e+06 3.74139e+07 21 21 } \ + { 1.07899e+06 3.84913e+07 21 21 } \ + { 1.08193e+06 3.95718e+07 21 21 } \ + { 1.0846e+06 4.06551e+07 21 21 } \ + { 1.08699e+06 4.17409e+07 21 21 } \ + { 1.0891e+06 4.28289e+07 21 21 } \ + { 1.09094e+06 4.3919e+07 21 21 } \ + { 1.0925e+06 4.50107e+07 21 21 } \ + { 1.09379e+06 4.61039e+07 21 21 } \ + { 1.09481e+06 4.71982e+07 21 21 } \ + { 1.09555e+06 4.82934e+07 21 21 } \ + { 1.09601e+06 4.93892e+07 21 21 } \ + { 1.0962e+06 5.04853e+07 21 21 } \ + { 1.09611e+06 5.15815e+07 21 21 } \ + { 1.09952e+06 5.26781e+07 19 19 } \ + { 1.10994e+06 5.37829e+07 19 19 } \ + { 1.12041e+06 5.4898e+07 19 19 } \ + { 1.13093e+06 5.60237e+07 19 19 } \ + { 1.1415e+06 5.71599e+07 19 19 } \ + { 1.15211e+06 5.83067e+07 19 19 } \ + { 1.16276e+06 5.94641e+07 19 19 } \ + { 1.17347e+06 6.06323e+07 19 19 } \ + { 1.18422e+06 6.18111e+07 19 19 } \ + { 1.19502e+06 6.30007e+07 19 19 } \ + { 1.20586e+06 6.42011e+07 19 19 } \ + { 1.21675e+06 6.54124e+07 19 19 } \ + { 1.22769e+06 6.66347e+07 19 19 } \ + { 1.23867e+06 6.78678e+07 19 19 } \ + { 1.2497e+06 6.9112e+07 19 19 } \ + { 1.26077e+06 7.03672e+07 19 19 } } + +perform_offset_increasing s 1 40 1 $ref_values + +copy r17 result +copy r17_unif result_unif + +checkview -display result_unif -2d -path ${imagedir}/${test_image}.png diff --git a/tests/offset/shape_type_i_c/XS6 b/tests/offset/shape_type_i_c/XS6 new file mode 100644 index 0000000000..d130c77851 --- /dev/null +++ b/tests/offset/shape_type_i_c/XS6 @@ -0,0 +1,54 @@ +restore [locate_data_file bug30470_input_trim2.brep] s + +# perform offset operation with increasing offset value + +# set props and nb reference values to compare with + +# area volume nb_wire nb_face +set ref_values { { 1.0108e+06 1.99437e+07 33 32 } \ + { 981289 2.09398e+07 33 32 } \ + { 951548 2.19062e+07 33 32 } \ + { 921582 2.28428e+07 33 32 } \ + { 891389 2.37493e+07 33 32 } \ + { 860971 2.46255e+07 33 32 } \ + { 830326 2.54712e+07 33 32 } \ + { 799456 2.62861e+07 33 32 } \ + { 800096 2.70819e+07 16 16 } \ + { 808054 2.78866e+07 17 17 } \ + { 813891 2.86976e+07 17 17 } \ + { 819610 2.95143e+07 17 17 } \ + { 825212 3.03368e+07 17 17 } \ + { 830698 3.11647e+07 17 17 } \ + { 836069 3.19981e+07 17 17 } \ + { 841324 3.28368e+07 17 17 } \ + { 846463 3.36807e+07 17 17 } \ + { 851486 3.45297e+07 17 17 } \ + { 856393 3.53837e+07 17 17 } \ + { 861185 3.62425e+07 17 17 } \ + { 865860 3.7106e+07 17 17 } \ + { 870420 3.79741e+07 17 17 } \ + { 874865 3.88468e+07 17 17 } \ + { 879193 3.97238e+07 17 17 } \ + { 885288 4.06055e+07 16 16 } \ + { 894915 4.14956e+07 16 16 } \ + { 904587 4.23953e+07 16 16 } \ + { 914305 4.33047e+07 16 16 } \ + { 924067 4.42239e+07 16 16 } \ + { 933874 4.51529e+07 16 16 } \ + { 943726 4.60917e+07 16 16 } \ + { 953623 4.70404e+07 16 16 } \ + { 963565 4.7999e+07 16 16 } \ + { 973552 4.89675e+07 16 16 } \ + { 983584 4.99461e+07 16 16 } \ + { 993661 5.09347e+07 16 16 } \ + { 1.00378e+06 5.19334e+07 16 16 } \ + { 1.01395e+06 5.29423e+07 16 16 } \ + { 1.02416e+06 5.39613e+07 16 16 } \ + { 1.03442e+06 5.49906e+07 16 16 } } + +perform_offset_increasing s 1 40 1 $ref_values + +copy r17 result +copy r17_unif result_unif + +checkview -display result_unif -2d -path ${imagedir}/${test_image}.png diff --git a/tests/offset/shape_type_i_c/XS7 b/tests/offset/shape_type_i_c/XS7 new file mode 100644 index 0000000000..2843892ede --- /dev/null +++ b/tests/offset/shape_type_i_c/XS7 @@ -0,0 +1,54 @@ +restore [locate_data_file bug30470_input_trim3.brep] s + +# perform offset operation with increasing offset value + +# set props and nb reference values to compare with + +# area volume nb_wire nb_face +set ref_values { { 773892 1.5856e+07 23 22 } \ + { 749115 1.66175e+07 23 22 } \ + { 724383 1.73543e+07 23 22 } \ + { 699696 1.80663e+07 23 22 } \ + { 675053 1.87537e+07 23 22 } \ + { 650456 1.94164e+07 23 22 } \ + { 625904 2.00546e+07 23 22 } \ + { 601396 2.06682e+07 23 22 } \ + { 601493 2.12666e+07 13 13 } \ + { 609929 2.18723e+07 13 13 } \ + { 618409 2.24865e+07 13 13 } \ + { 626935 2.31091e+07 13 13 } \ + { 635505 2.37403e+07 13 13 } \ + { 644121 2.43802e+07 13 13 } \ + { 652781 2.50286e+07 13 13 } \ + { 661486 2.56857e+07 13 13 } \ + { 670236 2.63516e+07 13 13 } \ + { 679032 2.70262e+07 13 13 } \ + { 687872 2.77097e+07 13 13 } \ + { 696757 2.8402e+07 13 13 } \ + { 705687 2.91032e+07 13 13 } \ + { 714662 2.98134e+07 13 13 } \ + { 723682 3.05325e+07 13 13 } \ + { 732747 3.12607e+07 13 13 } \ + { 741857 3.1998e+07 13 13 } \ + { 751012 3.27445e+07 13 13 } \ + { 760212 3.35001e+07 13 13 } \ + { 769456 3.42649e+07 13 13 } \ + { 778746 3.5039e+07 13 13 } \ + { 788081 3.58224e+07 13 13 } \ + { 797461 3.66152e+07 13 13 } \ + { 806885 3.74174e+07 13 13 } \ + { 816355 3.8229e+07 13 13 } \ + { 825869 3.90501e+07 13 13 } \ + { 835429 3.98807e+07 13 13 } \ + { 845033 4.07209e+07 13 13 } \ + { 854683 4.15708e+07 13 13 } \ + { 864377 4.24303e+07 13 13 } \ + { 874116 4.32996e+07 13 13 } \ + { 883901 4.41786e+07 13 13 } } + +perform_offset_increasing s 1 40 1 $ref_values + +copy r17 result +copy r17_unif result_unif + +checkview -display result_unif -2d -path ${imagedir}/${test_image}.png diff --git a/tests/offset/shape_type_i_c/XS8 b/tests/offset/shape_type_i_c/XS8 new file mode 100644 index 0000000000..75520364a6 --- /dev/null +++ b/tests/offset/shape_type_i_c/XS8 @@ -0,0 +1,54 @@ +restore [locate_data_file bug30470_input_trim4.brep] s + +# perform offset operation with increasing offset value + +# set props and nb reference values to compare with + +# area volume nb_wire nb_face +set ref_values { { 289134 4.40968e+06 16 16 } \ + { 288310 4.69842e+06 16 16 } \ + { 287307 4.98625e+06 16 16 } \ + { 286126 5.27298e+06 16 16 } \ + { 284767 5.55844e+06 16 16 } \ + { 283229 5.84245e+06 16 16 } \ + { 281513 6.12484e+06 16 16 } \ + { 279618 6.40542e+06 16 16 } \ + { 284722 6.68669e+06 9 9 } \ + { 292308 6.9752e+06 9 9 } \ + { 299985 7.27133e+06 9 9 } \ + { 307754 7.5752e+06 9 9 } \ + { 315614 7.88687e+06 9 9 } \ + { 323566 8.20645e+06 9 9 } \ + { 331611 8.53403e+06 9 9 } \ + { 339748 8.86971e+06 9 9 } \ + { 347978 9.21356e+06 9 9 } \ + { 356301 9.56569e+06 9 9 } \ + { 364716 9.92619e+06 9 9 } \ + { 373224 1.02952e+07 9 9 } \ + { 381824 1.06727e+07 9 9 } \ + { 390517 1.10588e+07 9 9 } \ + { 399302 1.14537e+07 9 9 } \ + { 408180 1.18575e+07 9 9 } \ + { 417150 1.22701e+07 9 9 } \ + { 426213 1.26918e+07 9 9 } \ + { 435369 1.31226e+07 9 9 } \ + { 444617 1.35626e+07 9 9 } \ + { 453958 1.40118e+07 9 9 } \ + { 463391 1.44705e+07 9 9 } \ + { 472917 1.49387e+07 9 9 } \ + { 482536 1.54164e+07 9 9 } \ + { 492247 1.59038e+07 9 9 } \ + { 502050 1.64009e+07 9 9 } \ + { 511947 1.69079e+07 9 9 } \ + { 521935 1.74248e+07 9 9 } \ + { 532017 1.79518e+07 9 9 } \ + { 542190 1.84889e+07 9 9 } \ + { 552457 1.90362e+07 9 9 } \ + { 562816 1.95938e+07 9 9 } } + +perform_offset_increasing s 1 40 1 $ref_values + +copy r17 result +copy r17_unif result_unif + +checkview -display result_unif -2d -path ${imagedir}/${test_image}.png diff --git a/tests/offset/shape_type_i_c/XS9 b/tests/offset/shape_type_i_c/XS9 new file mode 100644 index 0000000000..46e9515f04 --- /dev/null +++ b/tests/offset/shape_type_i_c/XS9 @@ -0,0 +1,54 @@ +restore [locate_data_file bug30470_input_trim5.brep] s + +# perform offset operation with increasing offset value + +# set props and nb reference values to compare with + +# area volume nb_wire nb_face +set ref_values { { 253148 3.95828e+06 17 17 } \ + { 250484 4.21012e+06 17 17 } \ + { 247598 4.45918e+06 17 17 } \ + { 244489 4.70524e+06 17 17 } \ + { 241158 4.94808e+06 17 17 } \ + { 237603 5.18748e+06 17 17 } \ + { 233826 5.42321e+06 17 17 } \ + { 229826 5.65506e+06 17 17 } \ + { 232781 5.88547e+06 10 10 } \ + { 238173 6.12094e+06 10 10 } \ + { 243612 6.36183e+06 10 10 } \ + { 249098 6.60818e+06 10 10 } \ + { 254631 6.86004e+06 10 10 } \ + { 260212 7.11746e+06 10 10 } \ + { 265841 7.38048e+06 10 10 } \ + { 271519 7.64915e+06 10 10 } \ + { 277245 7.92353e+06 10 10 } \ + { 283018 8.20366e+06 10 10 } \ + { 288841 8.48958e+06 10 10 } \ + { 294711 8.78136e+06 10 10 } \ + { 300630 9.07902e+06 10 10 } \ + { 306597 9.38263e+06 10 10 } \ + { 312612 9.69223e+06 10 10 } \ + { 318675 1.00079e+07 10 10 } \ + { 324787 1.03296e+07 10 10 } \ + { 330946 1.06575e+07 10 10 } \ + { 337154 1.09915e+07 10 10 } \ + { 343411 1.13318e+07 10 10 } \ + { 349715 1.16783e+07 10 10 } \ + { 356068 1.20312e+07 10 10 } \ + { 362469 1.23905e+07 10 10 } \ + { 368918 1.27562e+07 10 10 } \ + { 375415 1.31283e+07 10 10 } \ + { 381961 1.3507e+07 10 10 } \ + { 388555 1.38923e+07 10 10 } \ + { 395197 1.42842e+07 10 10 } \ + { 401887 1.46827e+07 10 10 } \ + { 408625 1.50879e+07 10 10 } \ + { 415412 1.55e+07 10 10 } \ + { 422247 1.59188e+07 10 10 } } + +perform_offset_increasing s 1 40 1 $ref_values + +copy r17 result +copy r17_unif result_unif + +checkview -display result_unif -2d -path ${imagedir}/${test_image}.png diff --git a/tests/offset/shape_type_i_c/XT1 b/tests/offset/shape_type_i_c/XT1 new file mode 100644 index 0000000000..2567e28570 --- /dev/null +++ b/tests/offset/shape_type_i_c/XT1 @@ -0,0 +1,20 @@ +puts "TODO CR27414 ALL: Error : The area of result shape is" +puts "TODO CR27414 ALL: Error : The volume of result shape is" +puts "TODO CR27414 ALL: Error : is WRONG because number of" + +polyline p 0 0 0 0 0 10 2 0 10 2 0 2 3 0 6 5 0 6 5 0 0 0 0 0 +mkplane f p +prism s f 0 5 0 + +offsetparameter 1e-7 c i r +offsetload s 1 +explode s f +offsetonface s_4 6 +offsetperform result + +checkprops result -s 410 -v 504 + +unifysamedom result_unif result +checknbshapes result_unif -vertex 12 -edge 18 -wire 8 -face 8 -shell 1 -solid 1 + +checkview -display result_unif -2d -path ${imagedir}/${test_image}.png diff --git a/tests/offset/shape_type_i_c/XT2 b/tests/offset/shape_type_i_c/XT2 new file mode 100644 index 0000000000..35b34b8f45 --- /dev/null +++ b/tests/offset/shape_type_i_c/XT2 @@ -0,0 +1,16 @@ +polyline p 0 0 0 0 0 10 2 0 10 2 0 2 3 0 6 5 0 6 5 0 0 0 0 0 +mkplane f p +prism s f 0 5 0 + +offsetparameter 1e-7 c i r +offsetload s 1 +explode s f +offsetonface s_4 4.5 +offsetperform result + +checkprops result -s 410 -v 504 + +unifysamedom result_unif result +checknbshapes result_unif -vertex 12 -edge 18 -wire 8 -face 8 -shell 1 -solid 1 + +checkview -display result_unif -2d -path ${imagedir}/${test_image}.png diff --git a/tests/offset/shape_type_i_c/ZC7 b/tests/offset/shape_type_i_c/ZC7 index eb86413722..86335bbec9 100644 --- a/tests/offset/shape_type_i_c/ZC7 +++ b/tests/offset/shape_type_i_c/ZC7 @@ -1,11 +1,10 @@ -puts "TODO OCC27414 ALL: Error: The command cannot be built" -puts "TODO OCC27414 ALL: gives an empty result" -puts "TODO OCC27414 ALL: TEST INCOMPLETE" +puts "TODO CR27414 ALL: Error : The area of result shape is" +puts "TODO CR27414 ALL: Faulty shapes in variables faulty_1 to faulty_" restore [locate_data_file bug26917_M2_trim34.brep] s OFFSETSHAPE 8 {} $calcul $type -checkprops result -v 0 +checkprops result -s 0 checknbshapes result -shell 1 diff --git a/tests/offset/shape_type_i_c/begin b/tests/offset/shape_type_i_c/begin index f6dbca54c8..559778754f 100644 --- a/tests/offset/shape_type_i_c/begin +++ b/tests/offset/shape_type_i_c/begin @@ -1,4 +1,147 @@ -#Shell no rough and rounded mode - +# Mode - Complete set calcul "c" +# Join type - Intersection set type "i" + +proc compare_prop_values {prop m_res m_ref} { + if { ($m_ref != 0 && abs (($m_ref - $m_res) / double($m_ref)) > 1.e-2) || ($m_res == 0 && $m_ref != 0) } { + puts "Error: The $prop of result shape is $m_res, expected $m_ref" + return 0 + } else { + puts "OK: The $prop of result shape is as expected" + return 1 + } +} + +proc compare_nbs {entity nb_res nb_ref} { + if {$nb_res != $nb_ref} { + puts "Error: number of $entity entities in the result shape is $nb_res, expected $nb_ref" + return 0 + } else { + puts "OK: number of $entity entities in the result shape is as expected" + return 1 + } +} + +proc perform_offset {theShape theValue} { + upvar $theShape TheShape + + global r${theValue} + global r${theValue}_unif + + tcopy TheShape sx + offsetparameter 1.e-7 c i r + offsetload sx ${theValue} + offsetperform r${theValue} + + if {![catch { checkshape r${theValue} } ] } { + unifysamedom r${theValue}_unif r${theValue} + return 1 + } + return 0 +} + +proc perform_offsets {theShape theOffsetValues theRefValues} { + + upvar $theShape TheShape + + set nbRefValues [llength $theRefValues] + + set failed_operations {} + set statistics {} + + set i 0 + + foreach offset $theOffsetValues { + + global r${offset} + global r${offset}_unif + + set operation_done [perform_offset TheShape ${offset}] + + # stats + set area_value 0 + set volume_value 0 + set nbwires_value 0 + set nbfaces_value 0 + + set checks_res {} + + if { $operation_done } { + + set area_value [lindex [sprops r${offset}] 2] + set volume_value [lindex [vprops r${offset}] 2] + + set check 0 + set refs {} + + if { $nbRefValues > $i } { + set refs [lindex $theRefValues $i] + if { [llength $refs] == 4} { + set check 1 + } + } + + if { $check } { + lappend checks_res [compare_prop_values "area" ${area_value} [lindex $refs 0]] + lappend checks_res [compare_prop_values "volume" ${volume_value} [lindex $refs 1]] + } + + set nbshapes_value [nbshapes r${offset}_unif] + set nbwires_value [lindex $nbshapes_value 13] + set nbfaces_value [lindex $nbshapes_value 16] + set nbshells_value [lindex $nbshapes_value 19] + set nbsolids_value [lindex $nbshapes_value 22] + + if { $check } { + lappend checks_res [compare_nbs "wire" $nbwires_value [lindex $refs 2]] + lappend checks_res [compare_nbs "face" $nbfaces_value [lindex $refs 3]] + } + + lappend checks_res [compare_nbs "shell" $nbshells_value 1] + lappend checks_res [compare_nbs "solid" $nbsolids_value 1] + } + + set OK $operation_done + + if {$OK == 1} { + foreach x $checks_res { + if {$x == 0} { + set OK 0 + break + } + } + } + + set status "OK" + if { $OK == 0 } { + puts "Error: operation with offset value ${offset} has failed" + + lappend failed_operations ${offset} + set status "KO" + } + + lappend statistics "Offset value ${offset} - $status: area - ${area_value};\t volume - ${volume_value};\t wires - ${nbwires_value};\t faces - ${nbfaces_value}" + incr i + } + + if {[llength $failed_operations] > 0} { + puts "Operations with following offset values have failed: $failed_operations" + } + + puts "Statistics:" + foreach str $statistics { puts "\t$str" } +} + +proc perform_offset_increasing {theShape theMinVal theStopVal theStep theRefValues} { + + upvar $theShape TheShape + + set values {} + + for {set i $theMinVal} {$i <= $theStopVal} {set i [expr $i + $theStep]} { + lappend values $i + } + + perform_offsets TheShape $values $theRefValues +}