From 964ddd087ffa4478c26455e75853c04d8587957d Mon Sep 17 00:00:00 2001 From: mpv Date: Tue, 6 Nov 2018 17:37:14 +0300 Subject: [PATCH] Geometrical naming for edges and intersections debug. --- src/Model/Model_BodyBuilder.cpp | 50 +++++++----- src/ModelAPI/CMakeLists.txt | 1 + src/ModelAPI/Test/TestGeomNamingRevolution.py | 78 +++++++++++++++++++ src/Selector/Selector_Selector.cpp | 19 ++++- 4 files changed, 129 insertions(+), 19 deletions(-) create mode 100644 src/ModelAPI/Test/TestGeomNamingRevolution.py diff --git a/src/Model/Model_BodyBuilder.cpp b/src/Model/Model_BodyBuilder.cpp index 9b05c442d..c137ecc8d 100755 --- a/src/Model/Model_BodyBuilder.cpp +++ b/src/Model/Model_BodyBuilder.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -476,6 +477,29 @@ TopAbs_ShapeEnum typeOfAncestor(const TopAbs_ShapeEnum theSubType) { return TopAbs_VERTEX; // bad case } +/// Checks that shape is presented in the tree with not-selection evolution +static bool isShapeInTree(const TDF_Label& theAccess1, const TDF_Label& theAccess2, + TopoDS_Shape theShape) +{ + bool aResult = TNaming_Tool::HasLabel(theAccess1, theShape); + if (aResult) { //check evolution and a label of this shape + for(TNaming_SameShapeIterator aShapes(theShape, theAccess1); aShapes.More(); aShapes.Next()) + { + static Handle(TNaming_NamedShape) aNS; + if (aShapes.Label().FindAttribute(TNaming_NamedShape::GetID(), aNS)) { + if (aNS->Evolution() != TNaming_SELECTED) { + return true; + } + } + } + } + if (!theAccess2.IsNull()) { + static const TDF_Label anEmpty; + return isShapeInTree(theAccess2, anEmpty, theShape); + } + return false; +} + void Model_BodyBuilder::loadModifiedShapes(const GeomMakeShapePtr& theAlgo, const GeomShapePtr& theOldShape, const GeomAPI_Shape::ShapeType theShapeTypeToExplore, @@ -503,15 +527,10 @@ void Model_BodyBuilder::loadModifiedShapes(const GeomMakeShapePtr& theAlgo, // There is no sense to write history if shape already processed // or old shape does not exist in the document. bool anOldSubShapeAlreadyProcessed = !anAlreadyProcessedShapes.Add(anOldSubShape_); - bool anOldSubShapeNotInTree = !TNaming_Tool::HasLabel(aData->shapeLab(), anOldSubShape_); - if (anOldSubShapeNotInTree) {// check this is in the module document - TDF_Label anAccess = std::dynamic_pointer_cast( - ModelAPI_Session::get()->moduleDocument())->generalLabel(); - anOldSubShapeNotInTree = !TNaming_Tool::HasLabel(anAccess, anOldSubShape_); - } - if (anOldSubShapeAlreadyProcessed - || anOldSubShapeNotInTree) - { + TDF_Label anAccess2 = std::dynamic_pointer_cast( + ModelAPI_Session::get()->moduleDocument())->generalLabel(); + bool anOldSubShapeNotInTree = !isShapeInTree(aData->shapeLab(), anAccess2, anOldSubShape_); + if (anOldSubShapeAlreadyProcessed || anOldSubShapeNotInTree) { continue; } @@ -591,15 +610,10 @@ void Model_BodyBuilder::loadGeneratedShapes(const GeomMakeShapePtr& theAlgo, // There is no sense to write history if shape already processed // or old shape does not exist in the document. bool anOldSubShapeAlreadyProcessed = !anAlreadyProcessedShapes.Add(anOldSubShape_); - bool anOldSubShapeNotInTree = !TNaming_Tool::HasLabel(aData->shapeLab(), anOldSubShape_); - if (anOldSubShapeNotInTree) {// check this is in the module document - TDF_Label anAccess = std::dynamic_pointer_cast( - ModelAPI_Session::get()->moduleDocument())->generalLabel(); - anOldSubShapeNotInTree = !TNaming_Tool::HasLabel(anAccess, anOldSubShape_); - } - if (anOldSubShapeAlreadyProcessed - || anOldSubShapeNotInTree) - { + TDF_Label anAccess2 = std::dynamic_pointer_cast( + ModelAPI_Session::get()->moduleDocument())->generalLabel(); + bool anOldSubShapeNotInTree = !isShapeInTree(aData->shapeLab(), anAccess2, anOldSubShape_); + if (anOldSubShapeAlreadyProcessed || anOldSubShapeNotInTree) { continue; } diff --git a/src/ModelAPI/CMakeLists.txt b/src/ModelAPI/CMakeLists.txt index 96ad5bed3..da074e70d 100644 --- a/src/ModelAPI/CMakeLists.txt +++ b/src/ModelAPI/CMakeLists.txt @@ -225,4 +225,5 @@ ADD_UNIT_TESTS(TestConstants.py TestWeakNaming2452.py Test2685.py TestGeomNamingPlacement.py + TestGeomNamingRevolution.py ) diff --git a/src/ModelAPI/Test/TestGeomNamingRevolution.py b/src/ModelAPI/Test/TestGeomNamingRevolution.py new file mode 100644 index 000000000..7f2e9357a --- /dev/null +++ b/src/ModelAPI/Test/TestGeomNamingRevolution.py @@ -0,0 +1,78 @@ +## Copyright (C) 2014-2017 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 +## + +# -*- coding: utf-8 -*- + +from SketchAPI import * + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +param = model.addParameter(Part_1_doc, "p", "10") +Box_1 = model.addBox(Part_1_doc, 10, 10, 10) +Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Box_1_1/Top")) +SketchLine_1 = Sketch_1.addLine(6.82842712474619, 7.171572875253809, 2.82842712474619, 7.171572875253809) +SketchLine_2 = Sketch_1.addLine(2.82842712474619, 7.171572875253809, 2.82842712474619, 3.171572875253809) +SketchLine_3 = Sketch_1.addLine(2.82842712474619, 3.171572875253809, 6.82842712474619, 3.171572875253809) +SketchLine_4 = Sketch_1.addLine(6.82842712474619, 3.171572875253809, 6.82842712474619, 7.171572875253809) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint()) +SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint()) +SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.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()) +SketchCircle_1 = Sketch_1.addCircle(4.440892098500626e-16, 0, 1) +SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 4) +SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_4.result(), 4) +SketchLine_5 = Sketch_1.addLine(0, 10, 10, 0) +SketchLine_5.setAuxiliary(True) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Right][Box_1_1/Top]"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_5.startPoint(), SketchPoint_1.result()) +SketchProjection_2 = Sketch_1.addProjection(model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Left][Box_1_1/Top]"), False) +SketchPoint_2 = SketchProjection_2.createdFeature() +SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchPoint_2.result()) +SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_5.result(), SketchLine_2.startPoint()) +SketchConstraintDistance_1 = Sketch_1.setDistance(SketchLine_2.startPoint(), SketchLine_5.startPoint(), 4, True) +SketchProjection_3 = Sketch_1.addProjection(model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"), False) +SketchLine_6 = SketchProjection_3.createdFeature() +SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_6.result(), SketchCircle_1.center()) +SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 1) +SketchConstraintDistance_2 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_6).endPoint(), SketchCircle_1.center(), "p", True) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2f")], model.selection(), 1, 1) +Cut_1 = model.addCut(Part_1_doc, [model.selection("SOLID", "Box_1_1")], [model.selection("SOLID", "Extrusion_1_1")]) +Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("WIRE", "Sketch_1/Face-SketchLine_1r-SketchLine_2f-SketchLine_3f-SketchLine_4f_wire")], model.selection("EDGE", "[Cut_1_1/Modified_Face&Box_1_1/Left][Cut_1_1/Modified_Face&Box_1_1/Top]"), 45, 0) +model.do() +# relocate circle to split the edge - axis of revolution +param.setValue(5) +model.end() + +# check that revolution is valid +from ModelAPI import * +aFactory = ModelAPI_Session.get().validators() +assert(aFactory.validate(Revolution_1.feature())) + +assert(model.checkPythonDump(model.ModelHighAPI.CHECK_NAMING)) diff --git a/src/Selector/Selector_Selector.cpp b/src/Selector/Selector_Selector.cpp index b0cc3a1f5..5ea73e6af 100644 --- a/src/Selector/Selector_Selector.cpp +++ b/src/Selector/Selector_Selector.cpp @@ -206,7 +206,7 @@ static bool sameGeometry(const TopoDS_Shape theShape1, const TopoDS_Shape theSha TopoDS_Face aFace2 = TopoDS::Face(theShape2); Handle(Geom_Surface) aSurf2 = BRep_Tool::Surface(aFace2, aLoc2); return aSurf1 == aSurf2 && aLoc1.IsEqual(aLoc2); - } else if (theShape1.ShapeType() == TopAbs_FACE) { // check curves + } else if (theShape1.ShapeType() == TopAbs_EDGE) { // check curves TopLoc_Location aLoc1, aLoc2; Standard_Real aFirst, aLast; TopoDS_Edge anEdge1 = TopoDS::Edge(theShape1); @@ -926,6 +926,23 @@ bool Selector_Selector::solve(const TopoDS_Shape& theContext) if (myWeakIndex != -1) { Selector_NExplode aNexp(aCommon); aResult = aNexp.shape(myWeakIndex); + } else if (myGeometricalNaming && aCommon.Extent() > 1) { + // check results are on the same geometry, create compound + TopoDS_ListOfShape::Iterator aCommonIter(aCommon); + TopoDS_Shape aFirst = aCommonIter.Value(); + for(aCommonIter.Next(); aCommonIter.More(); aCommonIter.Next()) { + if (!sameGeometry(aFirst, aCommonIter.Value())) + break; + } + if (!aCommonIter.More()) { // all geometry is same, create a result compound + TopoDS_Builder aBuilder; + TopoDS_Compound aCompound; + aBuilder.MakeCompound(aCompound); + for(aCommonIter.Initialize(aCommon); aCommonIter.More(); aCommonIter.Next()) { + aBuilder.Add(aCompound, aCommonIter.Value()); + } + aResult = aCompound; + } } else { return false; } -- 2.39.2