.. centered::\r
Construction pop-up menu\r
\r
-The order of features can be changed using *Move to the end* pop-up menu command. It works only for Group features. The selected group will be moved to the end of features list.\r
+The order of features can be changed using *Move to the end* and *Move to the end and split* pop-up menu commands. They work only for Group features. The selected group or several groups will be moved to the end of features list. The *Move to the end and split* also splits the resulting group in several groups: one group per one selection.\r
\r
Folders can be used to arrange long Tree View for features.\r
\r
Test3031.py
TestGroupWholeFeature1.py
TestGroupWholeFeature2.py
+ TestGroupMoveAndSplit1.py
+ TestGroupMoveAndSplit2.py
+ TestGroupMoveAndSplit3.py
)
#include <ModelAPI_AttributeInteger.h>
#include <ModelAPI_AttributeString.h>
#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeIntArray.h>
#include <ModelAPI_ResultGroup.h>
+#include <sstream>
CollectionPlugin_Group::CollectionPlugin_Group()
{
setResult(aGroup);
}
}
+
+// returns name with suffix, not existing in the existing set
+static std::string findName(
+ const std::string theOrigin, int& theSuffix, std::set<std::string>& theExisting)
+{
+ std::string aRes;
+ do {
+ std::ostringstream aName;
+ aName<<theOrigin<<"_"<<theSuffix;
+ aRes = aName.str();
+ theSuffix++;
+ } while(theExisting.count(aRes));
+ theExisting.insert(aRes);
+ return aRes;
+
+}
+
+bool CollectionPlugin_Group::customAction(const std::string& theActionId)
+{
+ if (theActionId == "split") {
+ DocumentPtr aDoc = document();
+ // collect all existing names of features to give unique names
+ std::set<std::string> aFeatNames, aResNames;
+ std::list<FeaturePtr> allFeat = aDoc->allFeatures();
+ std::list<FeaturePtr>::iterator allFeatIter = allFeat.begin();
+ for(; allFeatIter != allFeat.end(); allFeatIter++) {
+ FeaturePtr aFeat = *allFeatIter;
+ if (aFeat->data().get() && aFeat->data()->isValid()) {
+ aFeatNames.insert(aFeat->name());
+ if (aFeat->getKind() == ID() && aFeat->data().get() && aFeat->data()->isValid()) {
+ std::list<ResultPtr>::const_iterator aRess = aFeat->results().cbegin();
+ for(; aRess != aFeat->results().cend(); aRess++) {
+ ResultPtr aRes = *aRess;
+ if (aRes->data().get() && aRes->data()->isValid()) {
+ aResNames.insert(aRes->data()->name());
+ }
+ }
+ }
+ }
+ }
+
+ AttributeSelectionListPtr aList = selectionList(LIST_ID());
+ std::set<int> aRemoved;
+ bool aStay = false; // to indicate that the good attribute found stays in the list
+ int anIndex = 1; // index of the name assigned to group-feature and result
+ // added in the order: 3 2 1 orig=0, so, keep the results to give names later
+ std::list<ObjectPtr> aResults;
+ for(int aNext = aList->size() - 1; aNext >= 0; aNext--) {
+ AttributeSelectionPtr anOldAttr = aList->value(aNext);
+ if (anOldAttr->isInvalid() || !anOldAttr->context().get()) {// remove invalids
+ aRemoved.insert(aNext);
+ continue;
+ }
+ if (!aStay) {
+ aStay = true;
+ continue;
+ }
+ aRemoved.insert(aNext);
+ FeaturePtr aNew = aDoc->addFeature(ID(), false);
+ AttributeSelectionListPtr aNewList = aNew->selectionList(LIST_ID());
+ aNewList->setSelectionType(aList->selectionType());
+ aNewList->append(anOldAttr->contextObject(), anOldAttr->value());
+ aResults.push_front(aNew); // to keep the order
+ }
+ aResults.push_back(data()->owner());
+ // remove all selections except the first
+ aList->remove(aRemoved);
+ // set names
+ if (aResults.size() > 1) { // rename if there are new groups appeared only
+ std::list<ObjectPtr>::iterator aResIter = aResults.begin();
+ for(int aSuffix = 1; aResIter != aResults.end(); aResIter++) {
+ FeaturePtr aFeat = std::dynamic_pointer_cast<ModelAPI_Feature>(*aResIter);
+ aFeat->data()->setName(findName(name(), aSuffix, aFeatNames));
+ if (!aFeat->results().empty() && !results().empty()) {
+ int aResSuf = aSuffix - 1;
+ std::string aResName = findName(firstResult()->data()->name(), aResSuf, aResNames);
+ aFeat->firstResult()->data()->setName(aResName);
+ // set the same color of result as in origin
+ if (firstResult()->data()->attribute(ModelAPI_Result::COLOR_ID()).get()) {
+ AttributeIntArrayPtr aSourceColor =
+ firstResult()->data()->intArray(ModelAPI_Result::COLOR_ID());
+ if (aSourceColor.get() && aSourceColor->size()) {
+ AttributeIntArrayPtr aDestColor =
+ aFeat->firstResult()->data()->intArray(ModelAPI_Result::COLOR_ID());
+ aDestColor->setSize(aSourceColor->size());
+ for(int a = 0; a < aSourceColor->size(); a++)
+ aDestColor->setValue(a, aSourceColor->value(a));
+ }
+ }
+ }
+ }
+ // remove also filters if split performed
+ FiltersFeaturePtr aFilters = aList->filters();
+ if (aFilters.get()) {
+ std::list<std::string> aFiltersList = aFilters->filters();
+ std::list<std::string>::iterator aFilterName = aFiltersList.begin();
+ for(; aFilterName != aFiltersList.end(); aFilterName++) {
+ aFilters->removeFilter(*aFilterName);
+ }
+ }
+ }
+ }
+ return true;
+}
/// Use plugin manager for features creation
CollectionPlugin_Group();
+ /// Used for the split action of the group (Move to the end and split)
+ COLLECTIONPLUGIN_EXPORT virtual bool customAction(const std::string& theActionId);
};
#endif
--- /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
+#
+
+# Check the specification case of move to the end and split (#3059)
+
+from salome.shaper import model
+from ModelAPI import *
+from GeomAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [], model.selection(), 12, 0)
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1 = Sketch_1.addCircle(33.32502963835739, 19.24021483244179, 5)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 5)
+SketchLine_1 = Sketch_1.addLine(0, 0, 33.32502963835739, 19.24021483244179)
+SketchLine_1.setAuxiliary(True)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchPoint_1.result())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchLine_1.endPoint())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False)
+SketchLine_2 = SketchProjection_2.createdFeature()
+SketchConstraintAngle_1 = Sketch_1.setAngle(SketchLine_2.result(), SketchLine_1.result(), 30)
+Extrusion_1.setNestedSketch(Sketch_1)
+Group_1 = model.addGroup(Part_1_doc, "Faces", [model.selection("FACE", "Extrusion_1_1/To_Face")])
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], model.selection("EDGE", "PartSet/OZ"), 12)
+model.do()
+Part_1_doc.moveFeature(Group_1.feature(), AngularCopy_1.feature(), True)
+model.end()
+
+# must be created 12 groups of faces, 12 results
+assert(Part_1_doc.size("Groups") == 12)
+
+for i in range(12):
+ resShape = modelAPI_Result(Part_1_doc.object("Groups", i)).shape()
+ assert(not resShape.isNull())
+ # the group result is a compund, check that this is a compound of one face
+ aShapeExplorer = GeomAPI_ShapeExplorer(resShape, GeomAPI_Shape.FACE)
+ assert(aShapeExplorer.more())
+ assert(aShapeExplorer.current().isFace())
+ aShapeExplorer.next()
+ assert(not aShapeExplorer.more())
+
+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
+#
+
+# Check the movement to the end and split: move to intermediate position, no duplicates appeared
+
+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"))
+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_1 = Sketch_1.setCoincident(SketchPoint_1.result(), SketchCircle_1.center())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 10)
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2f")], model.selection(), 10, 0)
+Group_1 = model.addGroup(Part_1_doc, "Edges", [model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchCircle_1_2][Extrusion_1_1/To_Face]")])
+ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [], model.selection(), 0, 5, [model.selection("SOLID", "Extrusion_1_1")])
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/To_Face"))
+SketchProjection_2 = Sketch_2.addProjection(model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchCircle_1_2][Extrusion_1_1/To_Face]"), False)
+SketchCircle_2 = SketchProjection_2.createdFeature()
+SketchCircle_3 = Sketch_2.addCircle(0, 10, 3)
+SketchConstraintCoincidence_2 = Sketch_2.setCoincident(SketchCircle_2.results()[1], SketchCircle_3.center())
+SketchCircle_4 = Sketch_2.addCircle(0, -10, 3)
+SketchConstraintCoincidence_3 = Sketch_2.setCoincident(SketchCircle_2.results()[1], SketchCircle_4.center())
+SketchProjection_3 = Sketch_2.addProjection(model.selection("EDGE", "PartSet/OY"), True)
+SketchLine_1 = SketchProjection_3.createdFeature()
+SketchConstraintCoincidence_4 = Sketch_2.setCoincident(SketchCircle_3.center(), SketchLine_1.result())
+SketchConstraintCoincidence_5 = Sketch_2.setCoincident(SketchCircle_4.center(), SketchLine_1.result())
+SketchConstraintRadius_2 = Sketch_2.setRadius(SketchCircle_3.results()[1], 3)
+SketchConstraintEqual_1 = Sketch_2.setEqual(SketchCircle_3.results()[1], SketchCircle_4.results()[1])
+ExtrusionCut_1.setNestedSketch(Sketch_2)
+
+ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [], model.selection(), 0, 3, [model.selection("SOLID", "ExtrusionCut_1_1")])
+Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "ExtrusionCut_1_1/Modified_Face&Extrusion_1_1/To_Face"))
+SketchLine_2 = Sketch_3.addLine(10, 2, -10, 2)
+SketchLine_3 = Sketch_3.addLine(-10, 2, -10, -2)
+SketchLine_4 = Sketch_3.addLine(-10, -2, 10, -2)
+SketchLine_5 = Sketch_3.addLine(10, -2, 10, 2)
+SketchConstraintCoincidence_6 = Sketch_3.setCoincident(SketchLine_5.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_7 = Sketch_3.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_8 = Sketch_3.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_9 = Sketch_3.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintHorizontal_1 = Sketch_3.setHorizontal(SketchLine_2.result())
+SketchConstraintVertical_1 = Sketch_3.setVertical(SketchLine_3.result())
+SketchConstraintHorizontal_2 = Sketch_3.setHorizontal(SketchLine_4.result())
+SketchConstraintVertical_2 = Sketch_3.setVertical(SketchLine_5.result())
+SketchProjection_4 = Sketch_3.addProjection(model.selection("EDGE", "([ExtrusionCut_1_1/Modified_Face&Sketch_1/SketchCircle_1_2][Extrusion_1_1/From_Face])2(ExtrusionCut_1_1/Generated_Edge&ExtrusionCut_1_1/From_Face_1)2([ExtrusionCut_1_1/Modified_Face&Extrusion_1_1/To_Face][ExtrusionCut_1_1/Generated_Face&Sketch_2/SketchCircle_4_2])2"), False)
+SketchArc_1 = SketchProjection_4.createdFeature()
+SketchConstraintTangent_1 = Sketch_3.setTangent(SketchLine_5.result(), SketchArc_1.results()[1])
+SketchProjection_5 = Sketch_3.addProjection(model.selection("EDGE", "([ExtrusionCut_1_1/Modified_Face&Extrusion_1_1/To_Face][ExtrusionCut_1_1/Generated_Face&Sketch_2/SketchCircle_4_2])(ExtrusionCut_1_1/Generated_Edge&ExtrusionCut_1_1/From_Face_3)2(ExtrusionCut_1_1/Generated_Edge&ExtrusionCut_1_1/From_Face_2)2([ExtrusionCut_1_1/Generated_Face&Sketch_2/SketchCircle_4_2][ExtrusionCut_1_1/Modified_Face&ExtrusionCut_1_1/From_Face_3])2"), False)
+SketchArc_2 = SketchProjection_5.createdFeature()
+SketchConstraintTangent_2 = Sketch_3.setTangent(SketchArc_2.results()[1], SketchLine_3.result())
+SketchConstraintDistanceVertical_1 = Sketch_3.setVerticalDistance(SketchAPI_Arc(SketchArc_1).center(), SketchLine_2.startPoint(), 2)
+SketchConstraintDistanceVertical_2 = Sketch_3.setVerticalDistance(SketchAPI_Arc(SketchArc_1).center(), SketchLine_4.endPoint(), 2)
+ExtrusionCut_2.setNestedSketch(Sketch_3)
+model.do()
+# move only after the first extrusion-cut
+Part_1_doc.setCurrentFeature(ExtrusionCut_1.feature(), True)
+model.do()
+Part_1_doc.moveFeature(Group_1.feature(), ExtrusionCut_1.feature(), True)
+model.end()
+assert(Part_1_doc.size("Groups") == 3) # 3 edges in groups results
+
+# check that simple move to the end provides 4 edges (no duplicates)
+model.undo()
+model.undo()
+
+model.begin()
+Part_1_doc.moveFeature(Group_1.feature(), ExtrusionCut_2.feature(), True)
+model.end()
+assert(Part_1_doc.size("Groups") == 4) # 4 edges in groups results
+
+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
+#
+
+# Check the movement to the end and split: whole results, check names of splitted results and groups
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [], model.selection(), 10, 0)
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-8.333743842364534, 20.52339901477833, -20.15024630541872, 20.52339901477833)
+SketchLine_2 = Sketch_1.addLine(-20.15024630541872, 20.52339901477833, -20.15024630541872, 3.980295566502462)
+SketchLine_3 = Sketch_1.addLine(-20.15024630541872, 3.980295566502462, -8.333743842364534, 3.980295566502462)
+SketchLine_4 = Sketch_1.addLine(-8.333743842364534, 3.980295566502462, -8.333743842364534, 20.52339901477833)
+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(5.721674876847291, 12.81157635467982, 6.421166795138789)
+Extrusion_1.setNestedSketch(Sketch_1)
+Group_1 = model.addGroup(Part_1_doc, "Faces", [model.selection("SOLID", "Extrusion_1_1"), model.selection("SOLID", "Extrusion_1_2")])
+Group_1.setName("GroupResult")
+Group_1.result().setName("GroupResult")
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/To_Face"))
+SketchLine_5 = Sketch_2.addLine(3.924377723198604, 15.23693857548147, -14.36967929032953, 15.23693857548147)
+SketchLine_6 = Sketch_2.addLine(-14.36967929032953, 15.23693857548147, -14.36967929032953, 11.61585476914922)
+SketchLine_7 = Sketch_2.addLine(-14.36967929032953, 11.61585476914922, 3.924377723198604, 11.61585476914922)
+SketchLine_8 = Sketch_2.addLine(3.924377723198604, 11.61585476914922, 3.924377723198604, 15.23693857548147)
+SketchConstraintCoincidence_5 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintHorizontal_3 = Sketch_2.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_3 = Sketch_2.setVertical(SketchLine_6.result())
+SketchConstraintHorizontal_4 = Sketch_2.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_4 = Sketch_2.setVertical(SketchLine_8.result())
+model.do()
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_2/Face-SketchLine_5r-SketchLine_6f-SketchLine_7f-SketchLine_8f_wire")], model.selection(), 2, 5)
+Fuse_1 = model.addFuse(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1"), model.selection("SOLID", "Extrusion_2_1")], keepSubResults = True)
+model.do()
+Part_1_doc.moveFeature(Group_1.feature(), Fuse_1.feature(), True)
+model.end()
+
+assert(Part_1_doc.size("Groups") == 2) # 2 results because initially 2 results were selected
+
+# check names of results
+from ModelAPI import *
+res1 = modelAPI_Result(Part_1_doc.object("Groups", 0))
+assert(res1.data().name() == "GroupResult_1")
+res2 = modelAPI_Result(Part_1_doc.object("Groups", 1))
+assert(res2.data().name() == "GroupResult_2")
+
+assert(model.checkPythonDump())
return isSub(theMain, aParent);
}
-void Model_Document::moveFeature(FeaturePtr theMoved, FeaturePtr theAfterThis)
+void Model_Document::moveFeature(FeaturePtr theMoved, FeaturePtr theAfterThis, const bool theSplit)
{
bool aCurrentUp = theMoved == currentFeature(false);
if (aCurrentUp) {
}
myObjs->moveFeature(theMoved, anAfterThisSub);
+
+ if (theSplit) { // split the group into sub-features
+ theMoved->customAction("split");
+ }
+
if (aCurrentUp) { // make the moved feature enabled or disabled due to the real status
setCurrentFeature(currentFeature(false), false);
} else if (theAfterThis == currentFeature(false) || anAfterThisSub == currentFeature(false)) {
// must be after move to make enabled all features which are before theMoved
setCurrentFeature(theMoved, true);
}
+
+ if (theSplit) { // split the group into sub-features
+ theMoved->customAction("split");
+ }
}
void Model_Document::updateHistory(const std::shared_ptr<ModelAPI_Object> theObject)
MODEL_EXPORT virtual void removeFeature(FeaturePtr theFeature);
//! Moves the feature to make it after the given one in the history.
- MODEL_EXPORT virtual void moveFeature(FeaturePtr theMoved, FeaturePtr theAfterThis);
+ MODEL_EXPORT virtual void moveFeature(
+ FeaturePtr theMoved, FeaturePtr theAfterThis, const bool theSplit = false);
//! Returns the first found object in the group by the object name
//! \param theGroupID group that contains an object
//! Moves the feature to make it after the given one in the history.
virtual void moveFeature(std::shared_ptr<ModelAPI_Feature> theMoved,
- std::shared_ptr<ModelAPI_Feature> theAfterThis) = 0;
+ std::shared_ptr<ModelAPI_Feature> theAfterThis,
+ const bool theSplit = false) = 0;
///! Returns the id of the document
virtual const int id() const = 0;
bool PartSet_Module::canApplyAction(const ObjectPtr& theObject, const QString& theActionId) const
{
bool aValid = true;
- if (theActionId == "MOVE_CMD") {
+ if (theActionId == "MOVE_CMD" || theActionId == "MOVE_SPLIT_CMD") {
FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
if (aFeature) {
ResultPtr aResult = ModuleBase_Tools::firstResult(aFeature);
aSizedMap->InitTrash(aPixMap->Format(), aWidth, aHeigh);
for (Standard_Size i = 0; i < aWidth; i++) {
for (Standard_Size j = 0; j < aHeigh; j++) {
- aSizedMap->SetPixelColor(i, j, aPixMap->PixelColor(i / aRatio, j / aRatio));
+ aSizedMap->SetPixelColor(int(i), int(j), aPixMap->PixelColor(i / aRatio, j / aRatio));
}
}
aPixMap = aSizedMap;
aDesktop, this, SLOT(onRename()));
addAction("RENAME_CMD", aAction);
- aAction = ModuleBase_Tools::createAction(QIcon(":pictures/move.png"),
+ aAction = ModuleBase_Tools::createAction(QIcon(":pictures/move_to_end.png"),
XGUI_Workshop::MOVE_TO_END_COMMAND, this);
addAction("MOVE_CMD", aAction);
+ aAction = ModuleBase_Tools::createAction(QIcon(":pictures/move_to_end_split.png"),
+ XGUI_Workshop::MOVE_TO_END_SPLIT_COMMAND, this);
+ addAction("MOVE_SPLIT_CMD", aAction);
+
aAction = ModuleBase_Tools::createAction(QIcon(":pictures/clean_history.png"),
tr("Clean history"), aDesktop);
addAction("CLEAN_HISTORY_CMD", aAction);
if (!(hasParameter || hasFeature))
action("SHOW_ONLY_CMD")->setEnabled(true);
}
- else if (hasFeature && myWorkshop->canMoveFeature())
+ else if (hasFeature && myWorkshop->canMoveFeature()) {
action("MOVE_CMD")->setEnabled(true);
+ action("MOVE_SPLIT_CMD")->setEnabled(true);
+ }
if( aMgr->activeDocument() == aObject->document() )
{
action("SHADING_CMD")->setEnabled(true);
action("WIREFRAME_CMD")->setEnabled(true);
}
- if (hasFeature && myWorkshop->canMoveFeature())
+ if (hasFeature && myWorkshop->canMoveFeature()) {
action("MOVE_CMD")->setEnabled(true);
+ action("MOVE_SPLIT_CMD")->setEnabled(true);
+ }
} // end multi-selection
// Check folder management commands state if only features are selected
aList.append(action("RENAME_CMD"));
aList.append(action("SHOW_RESULTS_CMD"));
aList.append(action("MOVE_CMD"));
+ aList.append(action("MOVE_SPLIT_CMD"));
aList.append(mySeparator1);
aList.append(action("INSERT_FOLDER_CMD"));
aList.append(action("ADD_TO_FOLDER_BEFORE_CMD"));
aActions.append(action("ADD_OUT_FOLDER_AFTER_CMD"));
aActions.append(mySeparator3);
aActions.append(action("MOVE_CMD"));
+ aActions.append(action("MOVE_SPLIT_CMD"));
aActions.append(action("COLOR_CMD"));
aActions.append(action("DEFLECTION_CMD"));
aActions.append(action("TRANSPARENCY_CMD"));
//#define DEBUG_WITH_MESSAGE_REPORT
QString XGUI_Workshop::MOVE_TO_END_COMMAND = QObject::tr("Move to the end");
+QString XGUI_Workshop::MOVE_TO_END_SPLIT_COMMAND = QObject::tr("Move to the end and split");
//#define DEBUG_DELETE
//#define DEBUG_FEATURE_NAME
else
aMgr->redo();
- if (QString((*aIt).c_str()) == MOVE_TO_END_COMMAND)
+ if (QString((*aIt).c_str()) == MOVE_TO_END_COMMAND ||
+ QString((*aIt).c_str()) == MOVE_TO_END_SPLIT_COMMAND)
myObjectBrowser->rebuildDataTree();
}
operationMgr()->updateApplyOfOperations();
deleteObjects();
else if (theId == "CLEAN_HISTORY_CMD")
cleanHistory();
- else if (theId == "MOVE_CMD")
- moveObjects();
+ else if (theId == "MOVE_CMD" || theId == "MOVE_SPLIT_CMD")
+ moveObjects(theId == "MOVE_SPLIT_CMD");
else if (theId == "COLOR_CMD")
changeColor(aObjects);
else if (theId == "DEFLECTION_CMD")
DocumentPtr aDoc = theF1->document();
return aDoc->index(theF1) < aDoc->index(theF2);
}
-void XGUI_Workshop::moveObjects()
+void XGUI_Workshop::moveObjects(const bool theSplit)
{
if (!abortAllOperations())
return;
if (!XGUI_Tools::canRemoveOrRename(desktop(), aFeatures))
return;
- QString anActionId = "MOVE_CMD";
+ QString anActionId = theSplit ? "MOVE_CMD" : "MOVE_SPLIT_CMD";
QString aDescription = contextMenuMgr()->action(anActionId)->text();
aMgr->startOperation(aDescription.toStdString());
if (!aFeature.get() || !myModule->canApplyAction(aFeature, anActionId))
continue;
- anActiveDocument->moveFeature(aFeature, aCurrentFeature);
+ anActiveDocument->moveFeature(aFeature, aCurrentFeature, theSplit);
aCurrentFeature = anActiveDocument->currentFeature(true);
}
aMgr->finishOperation();
bool canMoveFeature();
/// Move selected features to be after the current feature
- void moveObjects();
+ void moveObjects(const bool theSplit);
/// Returns true if the object can be shaded. If the object is a compsolid result, the method
/// checks subobjects of the result
/// A constant string used for "Move to end" command definition
/// It is used for specific processing of Undo/Redo for this command.
static QString MOVE_TO_END_COMMAND;
+ /// A constant string used for "Move to end and split" command definition
+ /// It is used for specific processing of Undo/Redo for this command.
+ static QString MOVE_TO_END_SPLIT_COMMAND;
/// Closes all in the current session and load the directory
/// \param theDirectory a path to directory
<source>Move to the end</source>
<translation>Aller à la fin</translation>
</message>
+ <message>
+ <source>Move to the end and split</source>
+ <translation>Aller à la fin et diviser</translation>
+ </message>
<message>
<source>SHAPER files (*.shaper *.cadbld)</source>
<translation>Fichiers SHAPER (*.shaper *.cadbld)</translation>
<file>pictures/color.png</file>
<file>pictures/normal-view-inversed.png</file>
<file>pictures/normal-view.png</file>
+ <file>pictures/move_to_end.png</file>
+ <file>pictures/move_to_end_split.png</file>
</qresource>
</RCC>