From: azv Date: Tue, 13 Aug 2019 13:24:53 +0000 (+0300) Subject: Issue #17621: Wrong extrusion result by bounding planes X-Git-Tag: VEDF2019Lot4~56 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=d5799aff9edf48b6a9c4c4deec1cdb213e519aa2;p=modules%2Fshaper.git Issue #17621: Wrong extrusion result by bounding planes Make cutting solids finite to avoid problems in Boolean operation. --- diff --git a/src/FeaturesPlugin/CMakeLists.txt b/src/FeaturesPlugin/CMakeLists.txt index 0e5ed0f99..1a7ee6023 100644 --- a/src/FeaturesPlugin/CMakeLists.txt +++ b/src/FeaturesPlugin/CMakeLists.txt @@ -523,4 +523,5 @@ ADD_UNIT_TESTS(TestExtrusion.py TestRemoveResultsConstruction.py TestRemoveResultsPart.py Test17000.py + Test17261.py ) diff --git a/src/FeaturesPlugin/Test/Test17261.py b/src/FeaturesPlugin/Test/Test17261.py new file mode 100644 index 000000000..bb8749509 --- /dev/null +++ b/src/FeaturesPlugin/Test/Test17261.py @@ -0,0 +1,147 @@ +# Copyright (C) 2019 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +from SketchAPI import * + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) +SketchLine_1 = Sketch_1.addLine(0.5, 0, 0, 0) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchPoint_1.result()) +SketchLine_2 = Sketch_1.addLine(0, 37.39521866225591, 0, 40) +SketchLine_3 = Sketch_1.addLine(0, 40, 0.5, 40) +SketchLine_4 = Sketch_1.addLine(1, 40, 1, 0.5) +SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint()) +SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result()) +SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result()) +SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result()) +SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result()) +SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_2.result(), 2.604781337744086) +SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_3.result(), 0.5) +SketchPoint_2 = Sketch_1.addPoint(0.5, 40) +SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchPoint_2.coordinates(), SketchLine_3.endPoint()) +SketchLine_5 = Sketch_1.addLine(1, 40, 0.5, 40) +SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_4.startPoint(), SketchLine_5.startPoint()) +SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_5.endPoint()) +SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_4.startPoint(), SketchLine_5.result()) +SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_5.endPoint()) +SketchPoint_3 = Sketch_1.addPoint(0, 36.39521866225591) +SketchPoint_4 = Sketch_1.addPoint(0, 37.39521866225591) +SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchPoint_4.coordinates(), SketchPoint_3.coordinates(), 1) +SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchPoint_4.coordinates(), SketchLine_2.startPoint()) +SketchLine_6 = Sketch_1.addLine(0, 36.39521866225591, 0, 37.39521866225591) +SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchPoint_3.coordinates(), SketchLine_6.startPoint()) +SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_2.startPoint(), SketchLine_6.endPoint()) +SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_2.result()) +SketchLine_7 = Sketch_1.addLine(0, 0, 0, 36.39521866225591) +SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_7.startPoint()) +SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchPoint_3.coordinates(), SketchLine_7.endPoint()) +SketchConstraintCoincidence_14 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_6.result()) +SketchConstraintCoincidence_15 = Sketch_1.setCoincident(SketchLine_7.result(), SketchLine_1.endPoint()) +SketchLine_8 = Sketch_1.addLine(1, 0.5, 0.5, 0) +SketchConstraintCoincidence_16 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_1.startPoint()) +SketchConstraintCoincidence_17 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_1.startPoint()) +SketchConstraintCoincidence_18 = Sketch_1.setCoincident(SketchLine_8.startPoint(), SketchLine_4.endPoint()) +SketchConstraintCoincidence_19 = Sketch_1.setCoincident(SketchLine_8.startPoint(), SketchLine_4.endPoint()) +SketchConstraintCoincidence_20 = Sketch_1.setCoincident(SketchLine_8.startPoint(), SketchLine_4.endPoint()) +SketchConstraintParallel_1 = Sketch_1.setParallel(SketchLine_7.result(), SketchLine_4.result()) +SketchConstraintParallel_2 = Sketch_1.setParallel(SketchLine_2.result(), SketchLine_6.result()) +SketchConstraintCoincidence_21 = Sketch_1.setCoincident(SketchLine_2.result(), SketchLine_6.endPoint()) +SketchConstraintCoincidence_22 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_6.result()) +SketchConstraintCoincidence_23 = Sketch_1.setCoincident(SketchLine_3.result(), SketchLine_2.endPoint()) +SketchConstraintCoincidence_24 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_3.result()) +SketchConstraintLength_3 = Sketch_1.setLength(SketchLine_1.result(), 0.5) +SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False) +SketchLine_9 = SketchProjection_2.createdFeature() +SketchConstraintDistance_1 = Sketch_1.setDistance(SketchLine_8.startPoint(), SketchLine_9.result(), 0.5, True) +SketchConstraintCoincidence_25 = Sketch_1.setCoincident(SketchLine_4.result(), SketchLine_8.startPoint()) +SketchConstraintCoincidence_26 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_8.result()) +SketchConstraintCoincidence_27 = Sketch_1.setCoincident(SketchLine_8.result(), SketchLine_8.startPoint()) +SketchConstraintParallel_3 = Sketch_1.setParallel(SketchLine_3.result(), SketchLine_5.result()) +SketchConstraintLength_4 = Sketch_1.setLength(SketchLine_5.result(), 0.5) +SketchConstraintCoincidence_28 = Sketch_1.setCoincident(SketchLine_5.result(), SketchLine_4.startPoint()) +SketchConstraintCoincidence_29 = Sketch_1.setCoincident(SketchLine_5.result(), SketchLine_3.endPoint()) +SketchConstraintLength_5 = Sketch_1.setLength(SketchLine_4.result(), 39.5) +model.do() +Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("COMPOUND", "all-in-Sketch_1")], model.selection("EDGE", "Sketch_1/SketchLine_4"), 360, 0) +Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Revolution_1_1/Generated_Face&Sketch_1/SketchLine_1")) +SketchLine_10 = Sketch_2.addLine(1, 1, 1, -1) +SketchProjection_3 = Sketch_2.addProjection(model.selection("EDGE", "[Revolution_1_1/Generated_Face&Sketch_1/SketchLine_7][Revolution_1_1/Generated_Face&Sketch_1/SketchLine_1]"), False) +SketchCircle_1 = SketchProjection_3.createdFeature() +SketchConstraintCoincidence_30 = Sketch_2.setCoincident(SketchLine_10.startPoint(), SketchCircle_1.results()[1]) +SketchConstraintCoincidence_31 = Sketch_2.setCoincident(SketchLine_10.endPoint(), SketchCircle_1.results()[1]) +SketchConstraintVertical_3 = Sketch_2.setVertical(SketchLine_10.result()) +SketchConstraintCoincidence_32 = Sketch_2.setCoincident(SketchAPI_Circle(SketchCircle_1).center(), SketchLine_10.result()) +SketchLine_11 = Sketch_2.addLine(0, 0, 2, 0) +SketchProjection_4 = Sketch_2.addProjection(model.selection("VERTEX", "[Revolution_1_1/Generated_Face&Sketch_1/SketchLine_7][Revolution_1_1/Generated_Face&Sketch_1/SketchLine_1]"), False) +SketchPoint_5 = SketchProjection_4.createdFeature() +SketchConstraintCoincidence_33 = Sketch_2.setCoincident(SketchLine_11.startPoint(), SketchPoint_5.result()) +SketchProjection_5 = Sketch_2.addProjection(model.selection("EDGE", "[Revolution_1_1/Generated_Face&Sketch_1/SketchLine_7][Revolution_1_1/Generated_Face&Sketch_1/SketchLine_1]"), False) +SketchCircle_2 = SketchProjection_5.createdFeature() +SketchConstraintCoincidence_34 = Sketch_2.setCoincident(SketchLine_11.endPoint(), SketchCircle_2.results()[1]) +SketchConstraintCoincidence_35 = Sketch_2.setCoincident(SketchAPI_Circle(SketchCircle_1).center(), SketchLine_11.result()) +SketchLine_12 = Sketch_2.addLine(1.25, 0, 1.176776695296637, 0.1767766952966369) +SketchConstraintCoincidence_36 = Sketch_2.setCoincident(SketchLine_12.startPoint(), SketchLine_11.result()) +SketchLine_13 = Sketch_2.addLine(1.176776695296637, 0.1767766952966369, 1, 0.25) +SketchConstraintCoincidence_37 = Sketch_2.setCoincident(SketchLine_12.endPoint(), SketchLine_13.startPoint()) +SketchConstraintCoincidence_38 = Sketch_2.setCoincident(SketchLine_13.endPoint(), SketchLine_10.result()) +SketchProjection_6 = Sketch_2.addProjection(model.selection("EDGE", "[Revolution_1_1/Generated_Face&Sketch_1/SketchLine_8][Revolution_1_1/Generated_Face&Sketch_1/SketchLine_1]"), True) +SketchCircle_3 = SketchProjection_6.createdFeature() +SketchLine_14 = Sketch_2.addLine(1.176776695296637, 0.1767766952966369, 1.738436468990353, 0.6743230541046004) +SketchConstraintCoincidence_39 = Sketch_2.setCoincident(SketchLine_12.endPoint(), SketchLine_14.startPoint()) +SketchProjection_7 = Sketch_2.addProjection(model.selection("EDGE", "[Revolution_1_1/Generated_Face&Sketch_1/SketchLine_7][Revolution_1_1/Generated_Face&Sketch_1/SketchLine_1]"), False) +SketchCircle_4 = SketchProjection_7.createdFeature() +SketchConstraintCoincidence_40 = Sketch_2.setCoincident(SketchLine_14.endPoint(), SketchCircle_4.results()[1]) +SketchCircle_5 = Sketch_2.addCircle(1, 0, 0.25) +SketchCircle_5.setAuxiliary(True) +SketchConstraintCoincidence_41 = Sketch_2.setCoincident(SketchAPI_Circle(SketchCircle_1).center(), SketchCircle_5.center()) +SketchConstraintCoincidence_42 = Sketch_2.setCoincident(SketchLine_12.startPoint(), SketchCircle_5.results()[1]) +SketchConstraintCoincidence_43 = Sketch_2.setCoincident(SketchLine_12.endPoint(), SketchCircle_5.results()[1]) +SketchConstraintRadius_1 = Sketch_2.setRadius(SketchCircle_5.results()[1], 0.25) +SketchConstraintEqual_1 = Sketch_2.setEqual(SketchLine_13.result(), SketchLine_12.result()) +SketchConstraintCoincidence_44 = Sketch_2.setCoincident(SketchLine_13.endPoint(), SketchCircle_5.results()[1]) +SketchConstraintMirror_1_objects = [SketchLine_13.result(), SketchLine_12.result(), SketchLine_14.result()] +SketchConstraintMirror_1 = Sketch_2.addMirror(SketchLine_10.result(), SketchConstraintMirror_1_objects) +[SketchLine_15, SketchLine_16, SketchLine_17] = SketchConstraintMirror_1.mirrored() +SketchConstraintMirror_2_objects = [SketchLine_14.result(), SketchLine_12.result(), SketchLine_13.result(), SketchLine_15.result(), SketchLine_16.result(), SketchLine_17.result()] +SketchConstraintMirror_2 = Sketch_2.addMirror(SketchLine_11.result(), SketchConstraintMirror_2_objects) +[SketchLine_18, SketchLine_19, SketchLine_20, SketchLine_21, SketchLine_22, SketchLine_23] = SketchConstraintMirror_2.mirrored() +model.do() +Edge_1_objects = [model.selection("EDGE", "Sketch_2/SketchLine_23"), model.selection("EDGE", "Sketch_2/SketchLine_21"), model.selection("EDGE", "Sketch_2/SketchLine_22"), model.selection("EDGE", "Sketch_2/SketchLine_10"), model.selection("EDGE", "Sketch_2/SketchLine_15"), model.selection("EDGE", "Sketch_2/SketchLine_16"), model.selection("EDGE", "Sketch_2/SketchLine_17"), model.selection("EDGE", "Sketch_2/SketchLine_11"), model.selection("EDGE", "Sketch_2/SketchLine_12"), model.selection("EDGE", "Sketch_2/SketchLine_20"), model.selection("EDGE", "Sketch_2/SketchLine_19"), model.selection("EDGE", "Sketch_2/SketchLine_18"), model.selection("EDGE", "Sketch_2/SketchLine_13"), model.selection("EDGE", "Sketch_2/SketchLine_14"), model.selection("EDGE", "Sketch_2/SketchProjection_6")] +Edge_1 = model.addEdge(Part_1_doc, Edge_1_objects) +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "all-in-Edge_1")], model.selection("EDGE", "PartSet/OY"), model.selection("FACE", "Revolution_1_1/Generated_Face&Sketch_1/SketchLine_3"), 0, model.selection(), 0) +model.end() + +from GeomAPI import * + +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [15]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [15]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [102]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [204]) +model.testResultsVolumes(Extrusion_1, [466.947878]) + +assert(model.checkPythonDump()) diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp index 500fbf8e6..35c54509c 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp @@ -382,6 +382,9 @@ void GeomAlgoAPI_Prism::buildByPlanes(const GeomShapePtr theBaseShap new GeomAlgoAPI_MakeShape(aPrismBuilder))); TopoDS_Shape aResult = aPrismBuilder->Shape(); + BRepBndLib::Add(aResult, aBndBox); + Standard_Real aBndBoxSize = aBndBox.CornerMin().Distance(aBndBox.CornerMax()); + // Orienting bounding planes. std::shared_ptr aCentreOfMass = GeomAlgoAPI_ShapeTools::centreOfMass(theBaseShape); const gp_Pnt& aCentrePnt = aCentreOfMass->impl(); @@ -394,42 +397,45 @@ void GeomAlgoAPI_Prism::buildByPlanes(const GeomShapePtr theBaseShap gp_Vec aVec = aToDir->impl(); if((aVec * anExtVec) > 0) { aToDir->setImpl(new gp_Dir(aVec.Reversed())); - aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir); + aBoundingToShape = + GeomAlgoAPI_FaceBuilder::squareFace(aToPnt, aToDir, 2.0 * aBndBoxSize); } aVec = aFromDir->impl(); if((aVec * anExtVec) < 0) { aFromDir->setImpl(new gp_Dir(aVec.Reversed())); - aBoundingFromShape = GeomAlgoAPI_FaceBuilder::planarFace(aFromPnt, aFromDir); + aBoundingFromShape = + GeomAlgoAPI_FaceBuilder::squareFace(aFromPnt, aFromDir, 2.0 * aBndBoxSize); } } else { gp_Vec aVec = aToDir->impl(); if((aVec * anExtVec) < 0) { aToDir->setImpl(new gp_Dir(aVec.Reversed())); - aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir); + aBoundingToShape = + GeomAlgoAPI_FaceBuilder::squareFace(aToPnt, aToDir, 2.0 * aBndBoxSize); } aVec = aFromDir->impl(); if((aVec * anExtVec) > 0) { aFromDir->setImpl(new gp_Dir(aVec.Reversed())); - aBoundingFromShape = GeomAlgoAPI_FaceBuilder::planarFace(aFromPnt, aFromDir); + aBoundingFromShape = + GeomAlgoAPI_FaceBuilder::squareFace(aFromPnt, aFromDir, 2.0 * aBndBoxSize); } } - // Making solids from bounding planes. - TopoDS_Shell aToShell, aFromShell; - TopoDS_Solid aToSolid, aFromSolid; + // bounding planes const TopoDS_Shape& aToShape = aBoundingToShape->impl(); const TopoDS_Shape& aFromShape = aBoundingFromShape->impl(); TopoDS_Face aToFace = TopoDS::Face(aToShape); TopoDS_Face aFromFace = TopoDS::Face(aFromShape); - BRep_Builder aBoundingBuilder; - aBoundingBuilder.MakeShell(aToShell); - aBoundingBuilder.Add(aToShell, aToShape); - aBoundingBuilder.MakeShell(aFromShell); - aBoundingBuilder.Add(aFromShell, aFromShape); - aBoundingBuilder.MakeSolid(aToSolid); - aBoundingBuilder.Add(aToSolid, aToShell); - aBoundingBuilder.MakeSolid(aFromSolid); - aBoundingBuilder.Add(aFromSolid, aFromShell); + + // Solid based on "To" bounding plane + gp_Vec aNormal = aToDir->impl(); + aPrismBuilder = new BRepPrimAPI_MakePrism(aToShape, aNormal * (-aBndBoxSize)); + if (!aPrismBuilder || !aPrismBuilder->IsDone()) { + return; + } + this->appendAlgo(std::shared_ptr( + new GeomAlgoAPI_MakeShape(aPrismBuilder))); + TopoDS_Shape aToSolid = aPrismBuilder->Shape(); // Cutting with to plane. BRepAlgoAPI_Cut* aToCutBuilder = new BRepAlgoAPI_Cut(aResult, aToSolid); @@ -444,14 +450,27 @@ void GeomAlgoAPI_Prism::buildByPlanes(const GeomShapePtr theBaseShap aResult = GeomAlgoAPI_DFLoader::refineResult(aResult); } if (theTypeToExp == GeomAPI_Shape::FACE || theTypeToExp == GeomAPI_Shape::COMPOUND) { - const TopTools_ListOfShape& aToShapes = aToCutBuilder->Modified(aToShape); - for(TopTools_ListIteratorOfListOfShape anIt(aToShapes); anIt.More(); anIt.Next()) { - GeomShapePtr aGeomSh = toShape(anIt.Value()); - fixOrientation(aGeomSh); - this->addToShape(aGeomSh); + const TopTools_ListOfShape& aPrismShapes = aPrismBuilder->Modified(aToShape); + for (TopTools_ListIteratorOfListOfShape anIt1(aPrismShapes); anIt1.More(); anIt1.Next()) { + const TopTools_ListOfShape& aToShapes = aToCutBuilder->Modified(anIt1.Value()); + for (TopTools_ListIteratorOfListOfShape anIt2(aToShapes); anIt2.More(); anIt2.Next()) { + GeomShapePtr aGeomSh = toShape(anIt2.Value()); + fixOrientation(aGeomSh); + this->addToShape(aGeomSh); + } } } + // Solid based on "From" bounding plane + aNormal = aFromDir->impl(); + aPrismBuilder = new BRepPrimAPI_MakePrism(aFromShape, aNormal * (-aBndBoxSize)); + if (!aPrismBuilder || !aPrismBuilder->IsDone()) { + return; + } + this->appendAlgo(std::shared_ptr( + new GeomAlgoAPI_MakeShape(aPrismBuilder))); + TopoDS_Shape aFromSolid = aPrismBuilder->Shape(); + // Cutting with from plane. BRepAlgoAPI_Cut* aFromCutBuilder = new BRepAlgoAPI_Cut(aResult, aFromSolid); aFromCutBuilder->Build(); @@ -469,11 +488,14 @@ void GeomAlgoAPI_Prism::buildByPlanes(const GeomShapePtr theBaseShap aResult = GeomAlgoAPI_DFLoader::refineResult(aResult); } if (theTypeToExp == GeomAPI_Shape::FACE || theTypeToExp == GeomAPI_Shape::COMPOUND) { - const TopTools_ListOfShape& aFromShapes = aFromCutBuilder->Modified(aFromShape); - for(TopTools_ListIteratorOfListOfShape anIt(aFromShapes); anIt.More(); anIt.Next()) { - GeomShapePtr aGeomSh = toShape(anIt.Value()); - fixOrientation(aGeomSh); - this->addFromShape(aGeomSh); + const TopTools_ListOfShape& aPrismShapes = aPrismBuilder->Modified(aFromShape); + for (TopTools_ListIteratorOfListOfShape anIt1(aPrismShapes); anIt1.More(); anIt1.Next()) { + const TopTools_ListOfShape& aFromShapes = aFromCutBuilder->Modified(anIt1.Value()); + for (TopTools_ListIteratorOfListOfShape anIt2(aFromShapes); anIt2.More(); anIt2.Next()) { + GeomShapePtr aGeomSh = toShape(anIt2.Value()); + fixOrientation(aGeomSh); + this->addFromShape(aGeomSh); + } } }