Implementation of move in the history of the whole objects.
TestGroupMove18.py
TestGroupMove19.py
TestGroupMove20.py
+ TestGroupMove21.py
+ TestGroupMove22.py
+ TestGroupMove23.py
+ TestGroupMove24.py
+ TestGroupMove25.py
TestGroupShareTopology.py
TestGroupAddition.py
TestGroupAddition_Error.py
--- /dev/null
+# Copyright (C) 2014-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
+#
+
+# Test move the group in history for selection of a whole result
+
+from salome.shaper import model
+from GeomAPI import *
+
+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(35.07635467980296, 23.01108374384237, -25.74753694581282, 23.01108374384237)
+SketchLine_2 = Sketch_1.addLine(-25.74753694581282, 23.01108374384237, -25.74753694581282, -23.13546798029557)
+SketchLine_3 = Sketch_1.addLine(-25.74753694581282, -23.13546798029557, 35.07635467980296, -23.13546798029557)
+SketchLine_4 = Sketch_1.addLine(35.07635467980296, -23.13546798029557, 35.07635467980296, 23.01108374384237)
+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())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2f-SketchLine_3f-SketchLine_4f")], model.selection(), 80, 0)
+# selection of a whole result: 6 faces of a box
+Group_1 = model.addGroup(Part_1_doc, "Faces", [model.selection("SOLID", "Extrusion_1_1")])
+model.testNbSubShapes(Group_1, GeomAPI_Shape.FACE, [6])
+ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [], model.selection(), 0, 10, [model.selection("SOLID", "Extrusion_1_1")])
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3"))
+SketchCircle_1 = Sketch_2.addCircle(-7.736745115674536, 52.14422040986419, 6.760003867274182)
+ExtrusionCut_1.setNestedSketch(Sketch_2)
+model.do()
+# move group after the extrusion-cut, so, it refers to it
+Part_1_doc.moveFeature(Group_1.feature(), ExtrusionCut_1.feature())
+model.end()
+
+# check that there is a hole appeared in the group-results
+assert(len(Group_1.feature().results())==1)
+model.testNbSubShapes(Group_1, GeomAPI_Shape.FACE, [8])
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2014-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
+#
+
+# Test move the group in history for selection of a whole result of a compsolid
+
+from salome.shaper import model
+from GeomAPI import *
+
+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(-25.00123152709361, 27.48891625615764, 27.86206896551725, 27.48891625615764)
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchLine_2 = Sketch_1.addLine(27.86206896551725, 27.48891625615764, -23.88177339901478, -20.02586206896552)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(-23.88177339901478, -20.02586206896552, 28.73275862068966, -20.02586206896552)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchLine_4 = Sketch_1.addLine(28.73275862068966, -20.02586206896552, 27.86206896551725, 27.48891625615764)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_4.endPoint())
+SketchLine_5 = Sketch_1.addLine(-25.00123152709361, 27.48891625615764, 28.73275862068966, -20.02586206896552)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_5.endPoint())
+model.do()
+Extrusion_1_objects = [model.selection("FACE", "Sketch_1/Face-SketchLine_5f-SketchLine_2r-SketchLine_1r"), model.selection("FACE", "Sketch_1/Face-SketchLine_2f-SketchLine_5f-SketchLine_4f"), model.selection("FACE", "Sketch_1/Face-SketchLine_2f-SketchLine_3f-SketchLine_5r")]
+Extrusion_1 = model.addExtrusion(Part_1_doc, Extrusion_1_objects, model.selection(), 10, 0)
+# selection of a whole result: 5x3-2 faces (2 faces are shared)
+Group_1 = model.addGroup(Part_1_doc, "Faces", [model.selection("COMPSOLID", "Extrusion_1_1")])
+model.testNbSubShapes(Group_1, GeomAPI_Shape.FACE, [13])
+ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [], model.selection(), 0, 10, [model.selection("COMPSOLID", "Extrusion_1_1")])
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1_1/To_Face"))
+SketchCircle_1 = Sketch_2.addCircle(13.4282260278248, 11.79859034244854, 3.718064241992405)
+ExtrusionCut_1.setNestedSketch(Sketch_2)
+model.do()
+# move group after the extrusion-cut, so, it refers to it
+Part_1_doc.moveFeature(Group_1.feature(), ExtrusionCut_1.feature())
+model.end()
+
+# check that there is a hole appeared in two solids: +4 faces (1 splitted planar, 3 faces of cylinder, divided by seam)
+assert(len(Group_1.feature().results())==1)
+model.testNbSubShapes(Group_1, GeomAPI_Shape.FACE, [17])
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2014-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
+#
+
+# Test move the group in history for selection of a whole feature
+
+from salome.shaper import model
+from GeomAPI import *
+
+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(35.07635467980296, 23.01108374384237, -25.74753694581282, 23.01108374384237)
+SketchLine_2 = Sketch_1.addLine(-25.74753694581282, 23.01108374384237, -25.74753694581282, -23.13546798029557)
+SketchLine_3 = Sketch_1.addLine(-25.74753694581282, -23.13546798029557, 35.07635467980296, -23.13546798029557)
+SketchLine_4 = Sketch_1.addLine(35.07635467980296, -23.13546798029557, 35.07635467980296, 23.01108374384237)
+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())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2f-SketchLine_3f-SketchLine_4f")], model.selection(), 80, 0)
+# selection of a whole feature: 6 faces of a box
+Group_1 = model.addGroup(Part_1_doc, "Faces", [model.selection("COMPOUND", "all-in-Extrusion_1")])
+model.testNbSubShapes(Group_1, GeomAPI_Shape.FACE, [6])
+ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [], model.selection(), 0, 10, [model.selection("SOLID", "Extrusion_1_1")])
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3"))
+SketchCircle_1 = Sketch_2.addCircle(-7.736745115674536, 52.14422040986419, 6.760003867274182)
+ExtrusionCut_1.setNestedSketch(Sketch_2)
+model.do()
+# move group after the extrusion-cut, so, it refers to it
+Part_1_doc.moveFeature(Group_1.feature(), ExtrusionCut_1.feature())
+model.end()
+
+# check that there is a hole appeared in the group-results
+assert(len(Group_1.feature().results())==1)
+model.testNbSubShapes(Group_1, GeomAPI_Shape.FACE, [8])
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2014-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
+#
+
+# Test move the group in history for selection of a whole feature that produces compsolid
+
+from salome.shaper import model
+from GeomAPI import *
+
+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(-25.00123152709361, 27.48891625615764, 27.86206896551725, 27.48891625615764)
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchLine_2 = Sketch_1.addLine(27.86206896551725, 27.48891625615764, -23.88177339901478, -20.02586206896552)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(-23.88177339901478, -20.02586206896552, 28.73275862068966, -20.02586206896552)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchLine_4 = Sketch_1.addLine(28.73275862068966, -20.02586206896552, 27.86206896551725, 27.48891625615764)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_4.endPoint())
+SketchLine_5 = Sketch_1.addLine(-25.00123152709361, 27.48891625615764, 28.73275862068966, -20.02586206896552)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_5.endPoint())
+model.do()
+Extrusion_1_objects = [model.selection("FACE", "Sketch_1/Face-SketchLine_5f-SketchLine_2r-SketchLine_1r"), model.selection("FACE", "Sketch_1/Face-SketchLine_2f-SketchLine_5f-SketchLine_4f"), model.selection("FACE", "Sketch_1/Face-SketchLine_2f-SketchLine_3f-SketchLine_5r")]
+Extrusion_1 = model.addExtrusion(Part_1_doc, Extrusion_1_objects, model.selection(), 10, 0)
+# selection of a whole result: 5x3-2 faces (2 faces are shared)
+Group_1 = model.addGroup(Part_1_doc, "Faces", [model.selection("COMPOUND", "all-in-Extrusion_1")])
+model.testNbSubShapes(Group_1, GeomAPI_Shape.FACE, [13])
+ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [], model.selection(), 0, 10, [model.selection("COMPSOLID", "Extrusion_1_1")])
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1_1/To_Face"))
+SketchCircle_1 = Sketch_2.addCircle(13.4282260278248, 11.79859034244854, 3.718064241992405)
+ExtrusionCut_1.setNestedSketch(Sketch_2)
+model.do()
+# move group after the extrusion-cut, so, it refers to it
+Part_1_doc.moveFeature(Group_1.feature(), ExtrusionCut_1.feature())
+model.end()
+
+# check that there is a hole appeared in two solids: +4 faces (1 splitted planar, 3 faces of cylinder, divided by seam)
+assert(len(Group_1.feature().results())==1)
+model.testNbSubShapes(Group_1, GeomAPI_Shape.FACE, [17])
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2014-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
+#
+
+# Test move the group in history for selection of a whole features
+# with many modifications of this feature, and joining them in one.
+
+from SketchAPI import *
+
+from salome.shaper import model
+from ModelAPI import *
+
+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(-20, 9.999999999999998, -40, 10)
+SketchLine_2 = Sketch_1.addLine(-40, 10, -40, -10)
+SketchLine_3 = Sketch_1.addLine(-40, -10, -20, -9.999999999999998)
+SketchLine_4 = Sketch_1.addLine(-20, -9.999999999999998, -20, 9.999999999999998)
+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())
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchCircle_1 = Sketch_1.addCircle(0, 0, 10)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchPoint_1.result(), SketchCircle_1.center())
+SketchConstraintTangent_1 = Sketch_1.setTangent(SketchLine_1.result(), SketchCircle_1.results()[1])
+SketchConstraintTangent_2 = Sketch_1.setTangent(SketchLine_3.result(), SketchCircle_1.results()[1])
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_1).coordinates(), SketchLine_4.result(), 20, True)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 10)
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_1.result(), SketchLine_4.result())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2f-SketchLine_3f-SketchLine_4f")], model.selection(), 30, 0)
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2f")], model.selection(), 15, 0)
+Group_1 = model.addGroup(Part_1_doc, "Vertices", [model.selection("COMPOUND", "all-in-Extrusion_1")])
+Group_2 = model.addGroup(Part_1_doc, "Vertices", [model.selection("COMPOUND", "all-in-Extrusion_2")])
+Group_3 = model.addGroup(Part_1_doc, "Faces", [model.selection("COMPOUND", "all-in-Extrusion_1"), model.selection("COMPOUND", "all-in-Extrusion_2")])
+ExtrusionFuse_1 = model.addExtrusionFuse(Part_1_doc, [], model.selection(), 12, 0, [model.selection("SOLID", "Extrusion_1_1")])
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4"))
+SketchCircle_2 = Sketch_2.addCircle(-2.3396523840492e-15, 15, 7)
+SketchConstraintRadius_2 = Sketch_2.setRadius(SketchCircle_2.results()[1], 7)
+SketchProjection_2 = Sketch_2.addProjection(model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_1][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4]"), False)
+SketchLine_5 = SketchProjection_2.createdFeature()
+SketchConstraintDistance_2 = Sketch_2.setDistance(SketchCircle_2.center(), SketchLine_5.result(), 10, True)
+SketchProjection_3 = Sketch_2.addProjection(model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4][Extrusion_1_1/To_Face]"), False)
+SketchLine_6 = SketchProjection_3.createdFeature()
+SketchConstraintDistance_3 = Sketch_2.setDistance(SketchCircle_2.center(), SketchLine_6.result(), 15, True)
+ExtrusionFuse_1.setNestedSketch(Sketch_2)
+ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [], model.selection(), 50, 50, [model.selection("SOLID", "ExtrusionFuse_1_1"), model.selection("SOLID", "Extrusion_2_1")])
+Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionFuse_1_1/To_Face"))
+SketchProjection_4 = Sketch_3.addProjection(model.selection("VERTEX", "[ExtrusionFuse_1_1/Generated_Face&Sketch_2/SketchCircle_2_2][ExtrusionFuse_1_1/To_Face]__cc"), False)
+SketchPoint_2 = SketchProjection_4.createdFeature()
+SketchCircle_3 = Sketch_3.addCircle(-2.3396523840492e-15, 15, 5)
+SketchConstraintCoincidence_6 = Sketch_3.setCoincident(SketchPoint_2.result(), SketchCircle_3.center())
+SketchConstraintRadius_3 = Sketch_3.setRadius(SketchCircle_3.results()[1], 5)
+ExtrusionCut_1.setNestedSketch(Sketch_3)
+Fuse_1 = model.addFuse(Part_1_doc, [model.selection("SOLID", "ExtrusionCut_1_1"), model.selection("SOLID", "ExtrusionCut_1_2")], True, 20190506)
+model.do()
+# move groups after the final fuse
+Part_1_doc.moveFeature(Group_1.feature(), Fuse_1.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+Part_1_doc.moveFeature(Group_3.feature(), Group_2.feature())
+model.end()
+
+aFactory = ModelAPI_Session.get().validators()
+for group in [Group_1, Group_2, Group_3]:
+ selectionList = group.feature().selectionList("group_list")
+ assert(selectionList.size() == 1)
+ assert(aFactory.validate(group.feature()))
return false;
}
-/// Returns all sub-shapes of the given shape in theResult
-static void allSubShapes(const GeomShapePtr theShape, GeomAPI_Shape::ShapeType theType,
- std::list<GeomShapePtr>& theResult)
-{
- if (theShape->shapeType() == theType) {
- theResult.push_back(theShape);
- } else {
- GeomAPI_DataMapOfShapeShape aUnique; // to keep only unique shapes
- for(GeomAPI_ShapeExplorer anExp(theShape, theType); anExp.more(); anExp.next()) {
- if (aUnique.bind(anExp.current(), anExp.current()))
- theResult.push_back(anExp.current());
- }
- }
-}
-
void ExchangePlugin_ExportFeature::exportXAO(const std::string& theFileName)
{
try {
}
}
+
+void Model_AttributeSelection::concealedFeature(
+ const FeaturePtr theFeature, const FeaturePtr theStop, std::list<FeaturePtr>& theConcealers)
+{
+ std::set<FeaturePtr> alreadyProcessed;
+ alreadyProcessed.insert(theFeature);
+ if (theStop.get())
+ alreadyProcessed.insert(theStop);
+ /// iterate all results to find the concealment-attribute
+ const std::list<ResultPtr>& aRootRes = theFeature->results();
+ std::list<ResultPtr>::const_iterator aRootIter = aRootRes.cbegin();
+ for(; aRootIter != aRootRes.cend(); aRootIter++) {
+ std::list<ResultPtr> allRes;
+ allRes.push_back(*aRootIter);
+ ResultBodyPtr aRootBody = ModelAPI_Tools::bodyOwner(*aRootIter, true);
+ if (aRootBody.get()) {
+ ModelAPI_Tools::allSubs(aRootBody, allRes);
+ }
+ for(std::list<ResultPtr>::iterator aRIter = allRes.begin(); aRIter != allRes.end(); aRIter++) {
+ const std::set<AttributePtr>& aRefs = (*aRIter)->data()->refsToMe();
+ std::set<AttributePtr>::const_iterator aRef = aRefs.cbegin();
+ for (; aRef != aRefs.cend(); aRef++) {
+ if (!aRef->get() || !(*aRef)->owner().get())
+ continue;
+ // concealed attribute only
+ FeaturePtr aRefFeat = std::dynamic_pointer_cast<ModelAPI_Feature>((*aRef)->owner());
+ if (alreadyProcessed.find(aRefFeat) != alreadyProcessed.end()) // optimization
+ continue;
+ alreadyProcessed.insert(aRefFeat);
+ if (ModelAPI_Session::get()->validators()->isConcealed(aRefFeat->getKind(), (*aRef)->id()))
+ {
+ // for extrusion cut in python script the nested sketch reference may be concealed before
+ // it is nested, so, check this composite feature is valid
+ static ModelAPI_ValidatorsFactory* aFactory = ModelAPI_Session::get()->validators();
+ // need to be validated to update the "Apply" state if not previewed
+ if (aFactory->validate(aRefFeat)) {
+ if (theStop.get()) {
+ std::shared_ptr<Model_Document> aDoc =
+ std::dynamic_pointer_cast<Model_Document>(theStop->document());
+ if (!aDoc->isLaterByDep(theStop, aRefFeat)) // skip feature later than stop
+ continue;
+ }
+ theConcealers.push_back(aRefFeat);
+ }
+ }
+ }
+ }
+ }
+}
+
bool Model_AttributeSelection::searchNewContext(std::shared_ptr<Model_Document> theDoc,
const TopoDS_Shape theContShape, ResultPtr theContext, TopoDS_Shape theValShape,
TDF_Label theAccessLabel,
if (aResults.empty()) {
// check the context become concealed by operation which is earlier than this selection
- std::list<ResultPtr> allRes;
- ResultPtr aRoot = ModelAPI_Tools::bodyOwner(theContext, true);
- if (!aRoot.get())
- aRoot = theContext;
- ResultBodyPtr aRootBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aRoot);
- if (aRootBody.get()) {
- ModelAPI_Tools::allSubs(aRootBody, allRes);
- allRes.push_back(aRootBody);
- } else
- allRes.push_back(aRoot);
-
FeaturePtr aThisFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(owner());
- for (std::list<ResultPtr>::iterator aSub = allRes.begin(); aSub != allRes.end(); aSub++) {
- ResultPtr aResCont = *aSub;
- const std::set<AttributePtr>& aRefs = aResCont->data()->refsToMe();
- std::set<AttributePtr>::const_iterator aRef = aRefs.begin();
- for (; aRef != aRefs.end(); aRef++) {
- if (!aRef->get() || !(*aRef)->owner().get())
- continue;
- // concealed attribute only
- FeaturePtr aRefFeat = std::dynamic_pointer_cast<ModelAPI_Feature>((*aRef)->owner());
- if (aRefFeat == aThisFeature)
+ FeaturePtr aContextOwner = theDoc->feature(theContext);
+ std::list<FeaturePtr> aConcealers;
+ concealedFeature(aContextOwner, aThisFeature, aConcealers);
+ std::list<FeaturePtr>::iterator aConcealer = aConcealers.begin();
+ for(; aConcealer != aConcealers.end(); aConcealer++) {
+ std::list<ResultPtr> aRefResults;
+ ModelAPI_Tools::allResults(*aConcealer, aRefResults);
+ std::list<ResultPtr>::iterator aRefIter = aRefResults.begin();
+ for(; aRefIter != aRefResults.end(); aRefIter++) {
+ ResultBodyPtr aRefBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aRefIter);
+ if (!aRefBody.get() || aRefBody->numberOfSubs() != 0) // iterate only leafs
continue;
- if (!ModelAPI_Session::get()->validators()->isConcealed(
- aRefFeat->getKind(), (*aRef)->id()))
+ GeomShapePtr aRefShape = aRefBody->shape();
+ if (!aRefShape.get() || aRefShape->isNull())
continue;
- if (theDoc->isLaterByDep(aThisFeature, aRefFeat)) {
- // for extrusion cut in python script the nested sketch reference may be concealed before
- // it is nested, so, check this composite feature is valid
- static ModelAPI_ValidatorsFactory* aFactory = ModelAPI_Session::get()->validators();
- // need to be validated to update the "Apply" state if not previewed
- if (aFactory->validate(aRefFeat)) {
- // there could be a reference to unmodified object, check result contain same shape
- std::list<ResultPtr> aRefResults;
- ModelAPI_Tools::allResults(aRefFeat, aRefResults);
- std::list<ResultPtr>::iterator aRefIter = aRefResults.begin();
- for(; aRefIter != aRefResults.end(); aRefIter++) {
- ResultBodyPtr aRefBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aRefIter);
- if (!aRefBody.get() || aRefBody->numberOfSubs() != 0) // iterate only leafs
- continue;
- GeomShapePtr aRefShape = aRefBody->shape();
- if (!aRefShape.get() || aRefShape->isNull())
- continue;
- if (aRefShape->impl<TopoDS_Shape>().IsSame(theContShape)) {
- // add the new context result with the same shape
- aResults.insert(aRefBody);
- }
- }
- if (aResults.empty())
- return true; // feature conceals result, return true, so the context will be removed
- }
+ if (aRefShape->impl<TopoDS_Shape>().IsSame(theContShape)) {
+ // add the new context result with the same shape
+ aResults.insert(aRefBody);
}
}
+ if (aResults.empty())
+ return true; // feature conceals result, return true, so the context will be removed
}
if (aResults.empty())
return false; // no modifications found, must stay the same
void Model_AttributeSelection::updateInHistory(bool& theRemove)
{
+ static std::shared_ptr<GeomAPI_Shape> anEmptyShape;
+
ResultPtr aContext = std::dynamic_pointer_cast<ModelAPI_Result>(myRef.value());
- // only bodies and parts may be modified later in the history, don't do anything otherwise
if (!aContext.get() || (aContext->groupName() != ModelAPI_ResultBody::group() &&
- aContext->groupName() != ModelAPI_ResultPart::group()))
- return;
+ aContext->groupName() != ModelAPI_ResultPart::group())) {
+ // but check the case the whole results are allowed: whole features may be selected
+ if (myParent && myParent->isWholeResultAllowed()) {
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(myRef.value());
+ if (aFeature.get()) {
+ FeaturePtr aThisFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(owner());
+ std::list<FeaturePtr> aConcealers;
+ concealedFeature(aFeature, aThisFeature, aConcealers);
+ if (aConcealers.empty())
+ return;
+ bool aChanged = false;
+ std::list<FeaturePtr>::iterator aConcealer = aConcealers.begin();
+ for(; aConcealer != aConcealers.end(); aConcealer++)
+ if (!myParent->isInList(*aConcealer, anEmptyShape)) {// avoid addition of duplicates
+ setValue(*aConcealer, anEmptyShape);
+ aChanged = true;
+ }
+ if (aConcealer == aConcealers.end()) {
+ if (!aChanged) // remove this
+ theRemove = true;
+ } else { // append new
+ for(aConcealer++; aConcealer != aConcealers.end(); aConcealer++)
+ if (!myParent->isInList(*aConcealer, anEmptyShape)) // avoid addition of duplicates
+ myParent->append(*aConcealer, anEmptyShape);
+ }
+ if (aChanged) // searching for the further modifications
+ updateInHistory(theRemove);
+ }
+ }
+ return;// only bodies and parts may be modified later in the history, skip otherwise
+ }
+
std::shared_ptr<Model_Document> aDoc =
std::dynamic_pointer_cast<Model_Document>(aContext->document());
std::shared_ptr<Model_Data> aContData = std::dynamic_pointer_cast<Model_Data>(aContext->data());
aShapeShapeType = (*aNewCont)->shape()->shapeType();
}
if (aListShapeType != GeomAPI_Shape::SHAPE && aListShapeType != aShapeShapeType) {
- continue;
+ // exception is for whole results selected
+ if (!myParent || !myParent->isWholeResultAllowed() || aSubShape.get()) {
+ continue;
+ }
}
ResultPtr aNewContext = *aNewCont;
if (myParent) {
theRemove = true;
} else {
- ResultPtr anEmptyContext;
- std::shared_ptr<GeomAPI_Shape> anEmptyShape;
+ static ResultPtr anEmptyContext;
setValue(anEmptyContext, anEmptyShape); // nullify the selection
return;
}
/// Returns null label otherwise.
TDF_Label baseDocumentLab();
+ /// Returns features that conceals theFeature and located in history before theStop
+ void Model_AttributeSelection::concealedFeature(
+ const FeaturePtr theFeature, const FeaturePtr theStop, std::list<FeaturePtr>& theConcealers);
+
friend class Model_Data;
friend class Model_AttributeSelectionList;
};
const std::shared_ptr<GeomAPI_Shape>& theSubShape,
const bool theTemporarily)
{
- ResultPtr aResCont = std::dynamic_pointer_cast<ModelAPI_Result>(theContext);
if (myIsCashed) { // the cashing is active
- if (aResCont.get()) {
- std::map<ResultPtr, std::list<std::shared_ptr<GeomAPI_Shape> > >::iterator aContext =
- myCash.find(aResCont);
+ if (theContext.get()) {
+ std::map<ObjectPtr, std::list<std::shared_ptr<GeomAPI_Shape> > >::iterator aContext =
+ myCash.find(theContext);
if (aContext != myCash.end()) {
// iterate shapes because "isSame" method must be called for each shape
std::list<std::shared_ptr<GeomAPI_Shape> >::iterator aShapes = aContext->second.begin();
for(; aShapes != aContext->second.end(); aShapes++) {
if (!theSubShape.get()) {
- if (!aShapes->get() || (*aShapes)->isSame(aContext->first->shape()))
+ if (!aShapes->get())
+ return true;
+ ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(aContext->first);
+ if (aRes.get() && (*aShapes)->isSame(aRes->shape()))
return true;
} else {
// we need to call here isSame instead of isEqual to do not check shapes orientation
}
}
// no-cash method
+ bool isFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theContext).get() != NULL;
+ ResultPtr aRes;
+ if (!isFeature)
+ aRes = std::dynamic_pointer_cast<ModelAPI_Result>(theContext);
for(int anIndex = size() - 1; anIndex >= 0; anIndex--) {
AttributeSelectionPtr anAttr = value(anIndex);
if (anAttr.get()) {
- if (anAttr->context() == theContext) { // contexts are equal, so, check that values are also
+ if (isFeature && anAttr->contextFeature() == theContext)
+ return true; // for the feature value should not be compared
+ if (!isFeature && anAttr->context() == theContext) {
+ // contexts are equal, so, check that values are also
std::shared_ptr<GeomAPI_Shape> aValue = anAttr->value();
if (!theSubShape.get()) {
- if (!aValue.get() || (aResCont.get() && aValue->isSame(aResCont->shape()))) {// both null
+ if (!aValue.get() || (aRes.get() && aValue->isSame(aRes->shape())))
return true;
- }
} else {
// we need to call here isSame instead of isEqual to do not check shapes orientation
if (isIn(aValue, theSubShape)) // shapes are equal
Handle(TDataStd_Comment) mySelectionType;
std::shared_ptr<Model_AttributeSelection> myTmpAttr; ///< temporary attribute (the last one)
/// the cashed shapes to optimize isInList method: from context to set of shapes in this context
- std::map<ResultPtr, std::list<std::shared_ptr<GeomAPI_Shape> > > myCash;
+ std::map<ObjectPtr, std::list<std::shared_ptr<GeomAPI_Shape> > > myCash;
bool myIsCashed; ///< true if cashing is performed
public:
/// Adds the new reference to the end of the list