From: Artem Zhidkov Date: Wed, 10 Feb 2021 08:19:45 +0000 (+0300) Subject: Merge remote-tracking branch 'remotes/origin/CEA_2020_Lot2_1' X-Git-Tag: V9_7_0a1~44 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=d5db68d0ef6b0baa2435923268dc69167d970c81;p=modules%2Fshaper.git Merge remote-tracking branch 'remotes/origin/CEA_2020_Lot2_1' --- d5db68d0ef6b0baa2435923268dc69167d970c81 diff --cc src/FeaturesAPI/FeaturesAPI_BoundingBox.cpp index 000000000,d72009d39..ccd1e3453 mode 000000,100644..100644 --- a/src/FeaturesAPI/FeaturesAPI_BoundingBox.cpp +++ b/src/FeaturesAPI/FeaturesAPI_BoundingBox.cpp @@@ -1,0 -1,84 +1,83 @@@ + // Copyright (C) 2018-2020 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 + // + + #include "FeaturesAPI_BoundingBox.h" + + #include + #include + #include + #include + + #include + #include + #include + + //================================================================================================= + FeaturesAPI_BoundingBox::FeaturesAPI_BoundingBox( + const std::shared_ptr& theFeature) + : ModelHighAPI_Interface(theFeature) + { + initialize(); + } + + //================================================================================================= + FeaturesAPI_BoundingBox::FeaturesAPI_BoundingBox( + const std::shared_ptr& theFeature, + const ModelHighAPI_Selection& theObject) + :ModelHighAPI_Interface(theFeature) + { + if (initialize()) { + fillAttribute(theObject, myobjectSelected); + execute(); + } + } + + //================================================================================================= + FeaturesAPI_BoundingBox::~FeaturesAPI_BoundingBox() + { + } + + //================================================================================================= + void FeaturesAPI_BoundingBox::dump(ModelHighAPI_Dumper& theDumper) const + { + FeaturePtr aBase = feature(); + const std::string& aDocName = theDumper.name(aBase->document()); + + AttributeSelectionPtr anAttrObject; + anAttrObject = aBase->selection(FeaturesPlugin_CreateBoundingBox::OBJECT_ID()); + + theDumper << aBase << " = model.getBoundingBox(" << aDocName << ", " << anAttrObject; + + theDumper << ")" << std::endl; + } + + //================================================================================================= + BoundingBoxPtr getBoundingBox(const std::shared_ptr& thePart, + const ModelHighAPI_Selection& theObject) + { + + FeaturePtr aFeature = + thePart->addFeature(FeaturesPlugin_CreateBoundingBox::ID()); + + BoundingBoxPtr aBoundingBox; + + aBoundingBox.reset(new FeaturesAPI_BoundingBox(aFeature, theObject)); + + return aBoundingBox; + } - diff --cc src/FeaturesAPI/FeaturesAPI_GeometryCalculation.cpp index 000000000,666489e0a..3cce850fd mode 000000,100644..100644 --- a/src/FeaturesAPI/FeaturesAPI_GeometryCalculation.cpp +++ b/src/FeaturesAPI/FeaturesAPI_GeometryCalculation.cpp @@@ -1,0 -1,46 +1,45 @@@ + // Copyright (C) 2018-2020 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 + // + + #include "FeaturesAPI_GeometryCalculation.h" + + #include + #include + #include + #include + + //================================================================================================= + std::list getGeometryCalculation(const std::shared_ptr& thePart, + const ModelHighAPI_Selection& theObject) + { + FeaturePtr aPointCoodFeat = thePart->addFeature(FeaturesPlugin_GeometryCalculation::ID()); + + fillAttribute(theObject, aPointCoodFeat + ->selection(FeaturesPlugin_GeometryCalculation::OBJECT_SELECTED_ID())); + std::list res; + + // obtain result + AttributeDoubleArrayPtr aResult = std::dynamic_pointer_cast( + aPointCoodFeat->attribute(FeaturesPlugin_GeometryCalculation::RESULT_VALUES_ID())); + + for (int i : {0, 1, 2}) + res.push_back(aResult->value(i)); + + return res; + } - diff --cc src/FeaturesAPI/FeaturesAPI_PointCoordinates.cpp index 000000000,8898319f7..8982268cb mode 000000,100644..100644 --- a/src/FeaturesAPI/FeaturesAPI_PointCoordinates.cpp +++ b/src/FeaturesAPI/FeaturesAPI_PointCoordinates.cpp @@@ -1,0 -1,45 +1,44 @@@ + // Copyright (C) 2018-2020 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 + // + + #include "FeaturesAPI_PointCoordinates.h" + + #include + #include + #include + #include + + std::list getPointCoordinates(const std::shared_ptr& thePart, + const ModelHighAPI_Selection& thePoint) + { + FeaturePtr aPointCoordFeat = thePart->addFeature(FeaturesPlugin_PointCoordinates::ID()); + + fillAttribute(thePoint, aPointCoordFeat + ->selection(FeaturesPlugin_PointCoordinates::POINT_SELECTED_ID())); + std::list res; + + // obtain result + AttributeDoubleArrayPtr aResult = std::dynamic_pointer_cast( + aPointCoordFeat->attribute(FeaturesPlugin_PointCoordinates::RESULT_VALUES_ID())); + + for ( int i : {0, 1, 2}) + res.push_back( aResult->value(i)); + + return res; + } - diff --cc src/FeaturesPlugin/CMakeLists.txt index ae6ccc7ce,7a793e03b..e45e5136b --- a/src/FeaturesPlugin/CMakeLists.txt +++ b/src/FeaturesPlugin/CMakeLists.txt @@@ -688,5 -704,7 +704,8 @@@ ADD_UNIT_TESTS(TestExtrusion.p Test20245_2.py Test20245_3.py Test20247.py + Test22847.py + TestPointCoordinates.py + TestGeometryCalculation.py + TestBoundingBox.py ) diff --cc src/FeaturesPlugin/FeaturesPlugin_GeometryCalculation.cpp index 000000000,648e88bcd..106c01949 mode 000000,100644..100644 --- a/src/FeaturesPlugin/FeaturesPlugin_GeometryCalculation.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_GeometryCalculation.cpp @@@ -1,0 -1,106 +1,105 @@@ + // Copyright (C) 2018-2020 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 + // + + #include "FeaturesPlugin_GeometryCalculation.h" + + #include + #include + + #include + #include + #include + + #include + + #include + #include + + + #include + #include + + //================================================================================================= + FeaturesPlugin_GeometryCalculation::FeaturesPlugin_GeometryCalculation() + { + } + + //================================================================================================= + void FeaturesPlugin_GeometryCalculation::initAttributes() + { + // attribute for point selected + data()->addAttribute(OBJECT_SELECTED_ID(), ModelAPI_AttributeSelection::typeId()); + + // attributes for result message and values + data()->addAttribute(LENGTH_ID(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(AREA_ID(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(VOLUME_ID(), ModelAPI_AttributeString::typeId()); + + data()->addAttribute(RESULT_VALUES_ID(), ModelAPI_AttributeDoubleArray::typeId()); + data()->realArray(RESULT_VALUES_ID())->setSize(3); + + } + + //================================================================================================= + void FeaturesPlugin_GeometryCalculation::execute() + { + } + + //================================================================================================= + void FeaturesPlugin_GeometryCalculation::attributeChanged(const std::string& theID) + { + if (theID == OBJECT_SELECTED_ID()) { + + AttributeSelectionPtr aSelection = selection(OBJECT_SELECTED_ID()); + AttributeDoubleArrayPtr aValues = + std::dynamic_pointer_cast(attribute(RESULT_VALUES_ID())); + std::stringstream streamL; + std::stringstream streamA; + std::stringstream streamV; + GeomShapePtr aShape; + + if (aSelection && aSelection->isInitialized()) { + aShape = aSelection->value(); + if (!aShape && aSelection->context()) + aShape = aSelection->context()->shape(); + } + + if (aShape) { + double aTolerance = 0.0001; + double aLength; + double aSurfArea; + double aVolume; + + aLength = GeomAlgoAPI_ShapeTools::length(aShape); + aSurfArea = GeomAlgoAPI_ShapeTools::area(aShape); + aVolume = GeomAlgoAPI_ShapeTools::volume(aShape); + + streamL << std::setprecision(14) << aLength; + aValues->setValue(0, aLength); + streamA << std::setprecision(14) << aSurfArea; + aValues->setValue(1, aSurfArea); + streamV << std::setprecision(14) << aVolume; + aValues->setValue(2, aVolume); + } + + string(LENGTH_ID())->setValue(streamL.str()); + string(AREA_ID())->setValue(streamA.str()); + string(VOLUME_ID())->setValue(streamV.str()); + } + } - diff --cc src/FeaturesPlugin/FeaturesPlugin_PointCoordinates.cpp index 000000000,a3aed9848..e01dd5faa mode 000000,100644..100644 --- a/src/FeaturesPlugin/FeaturesPlugin_PointCoordinates.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_PointCoordinates.cpp @@@ -1,0 -1,96 +1,95 @@@ + // Copyright (C) 2018-2020 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 + // + + #include "FeaturesPlugin_PointCoordinates.h" + + #include + #include + + #include + #include + #include + + #include + + #include + #include + #include + + #include + + #include + #include + + FeaturesPlugin_PointCoordinates::FeaturesPlugin_PointCoordinates() + { + } + + void FeaturesPlugin_PointCoordinates::initAttributes() + { + // attribute for point selected + data()->addAttribute(POINT_SELECTED_ID(), ModelAPI_AttributeSelection::typeId()); + + // attribute for x, y and z coordinates + data()->addAttribute(X_COORD_ID(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(Y_COORD_ID(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(Z_COORD_ID(), ModelAPI_AttributeString::typeId()); + + // attributes for result message and values + data()->addAttribute(RESULT_VALUES_ID(), ModelAPI_AttributeDoubleArray::typeId()); + data()->realArray(RESULT_VALUES_ID())->setSize(3); + } + + void FeaturesPlugin_PointCoordinates::execute() + { + } + + void FeaturesPlugin_PointCoordinates::attributeChanged(const std::string& theID) + { + if (theID == POINT_SELECTED_ID()) { + AttributeSelectionPtr aSelection = selection(POINT_SELECTED_ID()); + GeomShapePtr aShape; + GeomPointPtr aPoint; + if (aSelection && aSelection->isInitialized()) { + aShape = aSelection->value(); + if (!aShape && aSelection->context()) + aShape = aSelection->context()->shape(); + } + + AttributeDoubleArrayPtr aValues = + std::dynamic_pointer_cast(attribute(RESULT_VALUES_ID())); + std::stringstream streamx; + std::stringstream streamy; + std::stringstream streamz; + if (aShape) { + aPoint = GeomAlgoAPI_PointBuilder::point(aShape); + streamx << std::setprecision(14) << aPoint->x(); + aValues->setValue(0, aPoint->x()); + streamy << std::setprecision(14) << aPoint->y(); + aValues->setValue(1, aPoint->y()); + streamz << std::setprecision(14) << aPoint->z(); + aValues->setValue(2, aPoint->z()); + } + + string(X_COORD_ID() )->setValue( "X = " + streamx.str() ); + string(Y_COORD_ID() )->setValue( "Y = " + streamy.str() ); + string(Z_COORD_ID() )->setValue( "Z = " + streamz.str() ); + } + + } - diff --cc src/FeaturesPlugin/Test/TestBoundingBox.py index 000000000,49f90f8e0..dba0e1b2f mode 000000,100644..100644 --- a/src/FeaturesPlugin/Test/TestBoundingBox.py +++ b/src/FeaturesPlugin/Test/TestBoundingBox.py @@@ -1,0 -1,82 +1,82 @@@ + # Copyright (C) 2014-2020 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 + # + + """ + Unit test of ... + """ + #========================================================================= + # Initialization of the test + #========================================================================= + + + import os + import math + + from ModelAPI import * + from salome.shaper import model + + + __updated__ = "2020-11-12" + + + #========================================================================= -# test Bounding Box ++# test Bounding Box + #========================================================================= + def test_Bounding_Box(): + + model.begin() + partSet = model.moduleDocument() + Part_1 = model.addPart(partSet) + Part_1_doc = Part_1.document() + ### Create Cone + Cone_1 = model.addCone(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 10, 5, 10) + + model.do() + ### Create BoundingBox + BoundingBox_1 = model.getBoundingBox(Part_1_doc, model.selection("SOLID", "Cone_1_1")) + model.end() + + myDelta = 1e-6 + Props = model.getGeometryCalculation(Part_1_doc,model.selection("SOLID", "BoundingBox_1_1")) + + print(" Basic Properties:") + print(" Wires length: ", Props[0]) + print(" Surface area: ", Props[1]) - print(" Volume : ", Props[2]) - ++ print(" Volume : ", Props[2]) ++ + aReflength = 200 + aReslength = Props[0] + assert (math.fabs(aReslength - aReflength) < myDelta), "The surface is wrong: expected = {0}, real = {1}".format(aReflength, aReslength) + + aRefSurface = 1600 + aResSurface = Props[1] + assert (math.fabs(aResSurface - aRefSurface) < myDelta), "The surface is wrong: expected = {0}, real = {1}".format(aRefSurface, aResSurface) + + aRefVolume = 4000 + aResVolume = Props[2] + assert (math.fabs(aResVolume - aRefVolume) < myDelta), "The volume is wrong: expected = {0}, real = {1}".format(aRefVolume, aResVolume) + - ++ + if __name__ == '__main__': + + test_Bounding_Box() - ++ + #========================================================================= + # End of test + #========================================================================= diff --cc src/FeaturesPlugin/Test/TestGeometryCalculation.py index 000000000,a3e1f1ec2..11e6bdba5 mode 000000,100644..100644 --- a/src/FeaturesPlugin/Test/TestGeometryCalculation.py +++ b/src/FeaturesPlugin/Test/TestGeometryCalculation.py @@@ -1,0 -1,80 +1,80 @@@ + # Copyright (C) 2014-2020 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 + # + + """ + Unit test of ... + """ + #========================================================================= + # Initialization of the test + #========================================================================= + + import salome + + import os + import math + + from ModelAPI import * + from salome.shaper import model + + + + __updated__ = "2020-11-12" + + + #========================================================================= + # test Geometry calculation + #========================================================================= + def test_Geometry_Calculation(): + + model.begin() + file_path = os.path.join(os.getenv("DATA_DIR"),"Shapes","Brep","box1.brep") + partSet = model.moduleDocument() + Part_1 = model.addPart(partSet) + Part_1_doc = Part_1.document() + Import_1 = model.addImport(Part_1_doc,file_path) + model.do() - ++ + myDelta = 1e-6 + Props = model.getGeometryCalculation(Part_1_doc,model.selection("SOLID", "box1_1")) + + print(" Geometry calculation:") + print(" Wires length: ", Props[0]) + print(" Surface area: ", Props[1]) - print(" Volume : ", Props[2]) - ++ print(" Volume : ", Props[2]) ++ + aReflength = 2400 + aReslength = Props[0] + assert (math.fabs(aReslength - aReflength) < myDelta), "The surface is wrong: expected = {0}, real = {1}".format(aReflength, aReslength) + + aRefSurface = 240000 + aResSurface = Props[1] + assert (math.fabs(aResSurface - aRefSurface) < myDelta), "The surface is wrong: expected = {0}, real = {1}".format(aRefSurface, aResSurface) + + aRefVolume = 8000000 + aResVolume = Props[2] + assert (math.fabs(aResVolume - aRefVolume) < myDelta), "The volume is wrong: expected = {0}, real = {1}".format(aRefVolume, aResVolume) + - ++ + if __name__ == '__main__': + + test_Geometry_Calculation() - ++ + #========================================================================= + # End of test + #========================================================================= diff --cc src/FeaturesPlugin/Test/TestPointCoordinates.py index 000000000,8b5c5b954..f2b03fe92 mode 000000,100644..100644 --- a/src/FeaturesPlugin/Test/TestPointCoordinates.py +++ b/src/FeaturesPlugin/Test/TestPointCoordinates.py @@@ -1,0 -1,73 +1,73 @@@ + # Copyright (C) 2014-2020 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 + # + + """ + Unit test of ... + """ + #========================================================================= + # Initialization of the test + #========================================================================= + + import os + import math + + from salome.shaper import model + + __updated__ = "2020-11-12" + + #========================================================================= + # test get point coordinates + #========================================================================= + def test_point_coordinates(): + + model.begin() + file_path = os.path.join(os.getenv("DATA_DIR"),"Shapes","Brep","box1.brep") + partSet = model.moduleDocument() + Part_1 = model.addPart(partSet) + Part_1_doc = Part_1.document() + Import_1 = model.addImport(Part_1_doc,file_path) + model.do() - ++ + myDelta = 1e-6 + coordinates = model.getPointCoordinates(Part_1_doc,model.selection("VERTEX", "[box1_1/Shape_2][box1_1/Shape_3][box1_1/Shape_6]")) + + print(" x: ", coordinates[0]) + print(" y: ", coordinates[1]) - print(" z: ", coordinates[2]) ++ print(" z: ", coordinates[2]) + + aRef = 200 + aRes = coordinates[0] + assert (math.fabs(aRes - aRef) < myDelta), "The coordinate X is wrong: expected = {0}, real = {1}".format(aRef, aRes) + + aRef = 0 + aRes= coordinates[1] + assert (math.fabs(aRes - aRef) < myDelta), "The coordinate Y is wrong: expected = {0}, real = {1}".format(aRef, aRes) + + aRef = 200 + aRes = coordinates[2] + assert (math.fabs(aRes - aRef) < myDelta), "The coordinate Z is wrong: expected = {0}, real = {1}".format(aRef, aRes) + - ++ + if __name__ == '__main__': + + test_point_coordinates() - ++ + #========================================================================= + # End of test + #========================================================================= diff --cc src/FeaturesPlugin/doc/examples/geometry_calculation.py index 000000000,e1e340a3b..2562da94d mode 000000,100644..100644 --- a/src/FeaturesPlugin/doc/examples/geometry_calculation.py +++ b/src/FeaturesPlugin/doc/examples/geometry_calculation.py @@@ -1,0 -1,13 +1,13 @@@ + import os + from salome.shaper import model + + model.begin() + partSet = model.moduleDocument() + Part_1 = model.addPart(partSet) + Part_1_doc = Part_1.document() + Box_1 = model.addBox(Part_1_doc, 10, 10, 10) + properties = model.getGeometryCalculation(Part_1_doc,model.selection("SOLID", "Box_1_1")) + print(" length: ", properties[0]) + print(" area: ", properties[1]) -print(" volume: ", properties[2]) ++print(" volume: ", properties[2]) + model.end() diff --cc src/FeaturesPlugin/doc/examples/point_coordinates.py index 000000000,d7e0e0eee..e8d902de6 mode 000000,100644..100644 --- a/src/FeaturesPlugin/doc/examples/point_coordinates.py +++ b/src/FeaturesPlugin/doc/examples/point_coordinates.py @@@ -1,0 -1,13 +1,13 @@@ + import os + from salome.shaper import model + + model.begin() + partSet = model.moduleDocument() + Part_1 = model.addPart(partSet) + Part_1_doc = Part_1.document() + Box_1 = model.addBox(Part_1_doc, 10, 10, 10) + coordinates = model.getPointCoordinates(Part_1_doc,model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Left][Box_1_1/Top]")) + print(" x: ", coordinates[0]) + print(" y: ", coordinates[1]) -print(" z: ", coordinates[2]) ++print(" z: ", coordinates[2]) + model.end() diff --cc src/GeomAlgoAPI/GeomAlgoAPI_BoundingBox.cpp index 000000000,157823bb9..0589a8c10 mode 000000,100644..100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_BoundingBox.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_BoundingBox.cpp @@@ -1,0 -1,391 +1,390 @@@ + // Copyright (C) 2014-2020 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 + // + + #include "GeomAlgoAPI_BoundingBox.h" + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + /** + * This function constructs and returns modified shape from the original one + * for singular cases. It is used for the method GetMinDistanceSingular. + * + * \param theShape the original shape + * \param theModifiedShape output parameter. The modified shape. + * \param theAddDist output parameter. The added distance for modified shape. + * \retval true if the shape is modified; false otherwise. + * + * \internal + */ + Standard_Boolean ModifyShape(const TopoDS_Shape &theShape, + TopoDS_Shape &theModifiedShape, + Standard_Real &theAddDist) + { + TopExp_Explorer anExp; + int nbf = 0; + + theAddDist = 0.; + theModifiedShape.Nullify(); + + for ( anExp.Init( theShape, TopAbs_FACE ); anExp.More(); anExp.Next() ) { + nbf++; + theModifiedShape = anExp.Current(); + } + if(nbf==1) { + TopoDS_Shape sh = theShape; + while(sh.ShapeType()==TopAbs_COMPOUND) { + TopoDS_Iterator it(sh); + sh = it.Value(); + } + Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(theModifiedShape)); + if(S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) || + S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) || + S->IsUPeriodic()) { + const Standard_Boolean isShell = + (sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE); + + if (!isShell && S->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) { + Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(S); + gp_Pnt PC = SS->Location(); + BRep_Builder B; + TopoDS_Vertex V; + B.MakeVertex(V,PC,1.e-7); + theModifiedShape = V; + theAddDist = SS->Radius(); + return Standard_True; + } + if (!isShell && S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) { + Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(S); + gp_Ax3 ax3 = TS->Position(); + Handle(Geom_Circle) C = new Geom_Circle(ax3.Ax2(),TS->MajorRadius()); + BRep_Builder B; + TopoDS_Edge E; + B.MakeEdge(E,C,1.e-7); + theModifiedShape = E; + theAddDist = TS->MinorRadius(); + return Standard_True; + } + + // non solid case or any periodic surface (Mantis 22454). + double U1,U2,V1,V2; + // changes for 0020677: EDF 1219 GEOM: MinDistance gives 0 instead of 20.88 + //S->Bounds(U1,U2,V1,V2); changed by + ShapeAnalysis::GetFaceUVBounds(TopoDS::Face(theModifiedShape),U1,U2,V1,V2); + // end of changes for 020677 (dmv) + Handle(Geom_RectangularTrimmedSurface) TrS1 = + new Geom_RectangularTrimmedSurface(S,U1,(U1+U2)/2.,V1,V2); + Handle(Geom_RectangularTrimmedSurface) TrS2 = + new Geom_RectangularTrimmedSurface(S,(U1+U2)/2.,U2,V1,V2); + TopoDS_Shape aMShape; + + TopoDS_Face F1 = BRepBuilderAPI_MakeFace(TrS1, Precision::Confusion()); + TopoDS_Face F2 = BRepBuilderAPI_MakeFace(TrS2, Precision::Confusion()); + + if (isShell) { + BRep_Builder B; + B.MakeCompound(TopoDS::Compound(aMShape)); + B.Add(aMShape, F1); + B.Add(aMShape, F2); + } else { + // The original shape is a solid. + BRepBuilderAPI_Sewing aSewing (Precision::Confusion()*10.0); + aSewing.Add(F1); + aSewing.Add(F2); + aSewing.Perform(); + aMShape = aSewing.SewedShape(); + BRep_Builder B; + TopoDS_Solid aSolid; + B.MakeSolid(aSolid); + B.Add(aSolid, aMShape); + aMShape = aSolid; + } + + Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape; + sfs->Init(aMShape); + sfs->SetPrecision(1.e-6); + sfs->SetMaxTolerance(1.0); + sfs->Perform(); + theModifiedShape = sfs->Shape(); + return Standard_True; + } + } + + theModifiedShape = theShape; + return Standard_False; + } + + //======================================================================= + // function : GetMinDistanceSingular + //======================================================================= + double GetMinDistanceSingular(const TopoDS_Shape& aSh1, + const TopoDS_Shape& aSh2, + gp_Pnt& Ptmp1, gp_Pnt& Ptmp2) + { + TopoDS_Shape tmpSh1; + TopoDS_Shape tmpSh2; + Standard_Real AddDist1 = 0.; + Standard_Real AddDist2 = 0.; + Standard_Boolean IsChange1 = ModifyShape(aSh1, tmpSh1, AddDist1); + Standard_Boolean IsChange2 = ModifyShape(aSh2, tmpSh2, AddDist2); + + if( !IsChange1 && !IsChange2 ) + return -2.0; + + BRepExtrema_DistShapeShape dst(tmpSh1,tmpSh2); + if (dst.IsDone()) { + double MinDist = 1.e9; + gp_Pnt PMin1, PMin2, P1, P2; + for (int i = 1; i <= dst.NbSolution(); i++) { + P1 = dst.PointOnShape1(i); + P2 = dst.PointOnShape2(i); + Standard_Real Dist = P1.Distance(P2); + if (MinDist > Dist) { + MinDist = Dist; + PMin1 = P1; + PMin2 = P2; + } + } + if(MinDist<1.e-7) { + Ptmp1 = PMin1; + Ptmp2 = PMin2; + } + else { + gp_Dir aDir(gp_Vec(PMin1,PMin2)); + if( MinDist > (AddDist1+AddDist2) ) { + Ptmp1 = gp_Pnt(PMin1.X() + aDir.X()*AddDist1, + PMin1.Y() + aDir.Y()*AddDist1, + PMin1.Z() + aDir.Z()*AddDist1); + Ptmp2 = gp_Pnt(PMin2.X() - aDir.X()*AddDist2, + PMin2.Y() - aDir.Y()*AddDist2, + PMin2.Z() - aDir.Z()*AddDist2); + return (MinDist - AddDist1 - AddDist2); + } + else { + if( AddDist1 > 0 ) { + Ptmp1 = gp_Pnt(PMin1.X() + aDir.X()*AddDist1, + PMin1.Y() + aDir.Y()*AddDist1, + PMin1.Z() + aDir.Z()*AddDist1); + Ptmp2 = Ptmp1; + } + else { + Ptmp2 = gp_Pnt(PMin2.X() - aDir.X()*AddDist2, + PMin2.Y() - aDir.Y()*AddDist2, + PMin2.Z() - aDir.Z()*AddDist2); + Ptmp1 = Ptmp2; + } + } + } + double res = MinDist - AddDist1 - AddDist2; + if(res<0.) res = 0.0; + return res; + } + return -2.0; + } + + //======================================================================= + // function : GetMinDistance + //======================================================================= + Standard_Real GetMinDistance(const TopoDS_Shape& theShape1, + const TopoDS_Shape& theShape2, + gp_Pnt& thePnt1, gp_Pnt& thePnt2) + { + Standard_Real aResult = 1.e9; + + // Issue 0020231: A min distance bug with torus and vertex. + // Make GetMinDistance() return zero if a sole VERTEX is inside any of SOLIDs + + // which of shapes consists of only one vertex? + TopExp_Explorer exp1(theShape1,TopAbs_VERTEX), exp2(theShape2,TopAbs_VERTEX); + TopoDS_Shape V1 = exp1.More() ? exp1.Current() : TopoDS_Shape(); + TopoDS_Shape V2 = exp2.More() ? exp2.Current() : TopoDS_Shape(); + exp1.Next(); exp2.Next(); + if ( exp1.More() ) V1.Nullify(); + if ( exp2.More() ) V2.Nullify(); + // vertex and container of solids + TopoDS_Shape V = V1.IsNull() ? V2 : V1; + TopoDS_Shape S = V1.IsNull() ? theShape1 : theShape2; + if ( !V.IsNull() ) { + // classify vertex against solids + gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( V ) ); + for ( exp1.Init( S, TopAbs_SOLID ); exp1.More(); exp1.Next() ) { + BRepClass3d_SolidClassifier classifier( exp1.Current(), p, 1e-6); + if ( classifier.State() == TopAbs_IN ) { + thePnt1 = p; + thePnt2 = p; + return 0.0; + } + } + } + + aResult = GetMinDistanceSingular(theShape1, theShape2, thePnt1, thePnt2); + + + BRepExtrema_DistShapeShape dst (theShape1, theShape2); + if (dst.IsDone()) { + gp_Pnt P1, P2; + + for (int i = 1; i <= dst.NbSolution(); i++) { + P1 = dst.PointOnShape1(i); + P2 = dst.PointOnShape2(i); + + Standard_Real Dist = P1.Distance(P2); + if (aResult < 0 || aResult > Dist) { + aResult = Dist; + thePnt1 = P1; + thePnt2 = P2; + } + } + } + + return aResult; + } + + //======================================================================= + // function : PreciseBoundingBox + //======================================================================= + Standard_Boolean PreciseBoundingBox(const TopoDS_Shape &theShape, Bnd_Box &theBox) + { + if (theBox.IsVoid()) BRepBndLib::Add( theShape, theBox ); + if (theBox.IsVoid()) return Standard_False; + + Standard_Real aBound[6]; + theBox.Get(aBound[0], aBound[2], aBound[4], aBound[1], aBound[3], aBound[5]); + + Standard_Integer i; + const gp_Pnt aMid(0.5*(aBound[1] + aBound[0]), // XMid + 0.5*(aBound[3] + aBound[2]), // YMid + 0.5*(aBound[5] + aBound[4])); // ZMid + const gp_XYZ aSize(aBound[1] - aBound[0], // DX + aBound[3] - aBound[2], // DY + aBound[5] - aBound[4]); // DZ + const gp_Pnt aPnt[6] = + { + gp_Pnt(aBound[0] - (aBound[1] - aBound[0]), aMid.Y(), aMid.Z()), // XMin + gp_Pnt(aBound[1] + (aBound[1] - aBound[0]), aMid.Y(), aMid.Z()), // XMax + gp_Pnt(aMid.X(), aBound[2] - (aBound[3] - aBound[2]), aMid.Z()), // YMin + gp_Pnt(aMid.X(), aBound[3] + (aBound[3] - aBound[2]), aMid.Z()), // YMax + gp_Pnt(aMid.X(), aMid.Y(), aBound[4] - (aBound[5] - aBound[4])), // ZMin + gp_Pnt(aMid.X(), aMid.Y(), aBound[5] + (aBound[5] - aBound[4])) // ZMax + }; + const gp_Dir aDir[3] = { gp::DX(), gp::DY(), gp::DZ() }; + const Standard_Real aPlnSize[3] = + { + 0.5*Max(aSize.Y(), aSize.Z()), // XMin, XMax planes + 0.5*Max(aSize.X(), aSize.Z()), // YMin, YMax planes + 0.5*Max(aSize.X(), aSize.Y()) // ZMin, ZMax planes + }; + gp_Pnt aPMin[2]; + + for (i = 0; i < 6; i++) { + const Standard_Integer iHalf = i/2; + const gp_Pln aPln(aPnt[i], aDir[iHalf]); + BRepBuilderAPI_MakeFace aMkFace(aPln, -aPlnSize[iHalf], aPlnSize[iHalf], + -aPlnSize[iHalf], aPlnSize[iHalf]); + + if (!aMkFace.IsDone()) { + return Standard_False; + } + + TopoDS_Shape aFace = aMkFace.Shape(); + + // Get minimal distance between planar face and shape. + Standard_Real aMinDist = GetMinDistance(aFace, theShape, aPMin[0], aPMin[1]); + + if (aMinDist < 0.) { + return Standard_False; + } + + aBound[i] = aPMin[1].Coord(iHalf + 1); + } + + // Update Bounding box with the new values. + theBox.SetVoid(); + theBox.Update(aBound[0], aBound[2], aBound[4], aBound[1], aBound[3], aBound[5]); + + return Standard_True; + } + + //================================================================================================= + bool GetBoundingBox(const std::shared_ptr& theShape, + Standard_Real& theXmin,Standard_Real& theXmax, + Standard_Real& theYmin,Standard_Real& theYmax, + Standard_Real& theZmin,Standard_Real& theZmax, + std::string& theError) + { + #ifdef _DEBUG + std::cout << "GetBoundingBox " << std::endl; + #endif + + if (!theShape.get()) { + theError = "GetBoundingBox : An invalid argument"; + return false; + } + + TopoDS_Shape aShape = theShape->impl(); + + //Compute the parameters + Bnd_Box B; + try { + OCC_CATCH_SIGNALS; + BRepBuilderAPI_Copy aCopyTool (aShape); + if (!aCopyTool.IsDone()) { + theError = "GetBoundingBox Error: Bad shape detected"; + return false; + } + + aShape = aCopyTool.Shape(); + + // remove triangulation to obtain more exact boundaries + BRepTools::Clean(aShape); + + BRepBndLib::Add(aShape, B); + + if (!PreciseBoundingBox(aShape, B)) { + theError = "GetBoundingBox Error: Bounding box cannot be precised"; + return false; + } + + B.Get(theXmin, theYmin, theZmin, theXmax, theYmax, theZmax); + } + catch (Standard_Failure& aFail) { + theError = aFail.GetMessageString(); + return false; + } + return true; + } -