Added treatment of the inverted edges while removing the inside faces (collapsed ones) - RemoveInsideFaces method:
- Removing the invalid hanging blocks containing the inverted edges.
- Considering the face containing the inverted edges as the invalid one.
Test cases for the issue.
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,
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,
const TopTools_DataMapOfShapeShape& theDMFImF,
const TopTools_IndexedMapOfShape& theMFInv,
const TopTools_IndexedMapOfShape& theInvEdges,
+ const TopTools_MapOfShape& theInvertedEdges,
TopTools_MapOfShape& theMFToRem);
static
void AppendToList(TopTools_ListOfShape& theL,
const TopoDS_Shape& theS);
+template <class ContainerType, class FenceMapType = TopTools_MapOfShape>
+static Standard_Boolean TakeModified(const TopoDS_Shape& theS,
+ const TopTools_DataMapOfShapeListOfShape& theImages,
+ ContainerType& theMapOut,
+ FenceMapType* theMFence = NULL);
+
//=======================================================================
//function : BuildSplitsOfTrimmedFaces
//purpose : Building splits of already trimmed faces
}
#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
{
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;
// 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);
// find invalid faces
FindInvalidFaces(aLFImages, theInvEdges, theValidEdges, aDMFLVE, aDMFLIE,
*pLNE, *pLIVE, theInvertedEdges, aMEdgeInvalidByVertex,
- aMFHoles, aMFInvInHole, aLFInv);
+ aMFHoles, aMFInvInHole, aLFInv, anInvertedFaces);
}
//
if (aLFInv.Extent()) {
//
// 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
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
// 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
aMEValInverted.Add(aItLE.Value());
}
//
- Standard_Boolean bCheckInverted = (theLFImages.Extent() == 1);
+ Standard_Boolean bTreatInvertedAsInvalid = (theLFImages.Extent() == 1);
//
// neutral edges to remove
TopTools_IndexedMapOfShape aMENRem;
bAllInvalid = Standard_True;
bHasReallyInvalid = Standard_False;
bAllInvNeutral = Standard_True;
+ bIsInvalidByInverted = Standard_True;
aNbChecked = 0;
//
const TopoDS_Wire& aWIm = BRepTools::OuterWire(aFIm);
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) {
continue;
}
//
+ if (bIsInvalidByInverted && !(bHasValid || bAllValid))
+ {
+ // The face contains only the inverted and localy invalid edges
+ theInvertedFaces.Append(aFIm);
+ }
+
if (!bAllInvNeutral) {
aLFPT.Append(aFIm);
}
bNeutral = aMEN.Contains(aEIm);
bValidLoc = aMVE.Contains(aEIm);
//
- if (!bInvalid && bCheckInverted) {
+ if (!bInvalid && bTreatInvertedAsInvalid) {
bInvalid = theMEInverted.Contains(aEIm);
}
//
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,
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
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
//
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) {
}
// 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);
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
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);
}
}
// 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
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();
}
}
// 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());
+ }
}
}
}
(!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());
}
}
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);
}
//
// 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);
}
}
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 <class ContainerType, class FenceMapType>
+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;
+ }
+}
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
-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
-#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
+}